view identify_primary_objects.xml @ 3:52c01fb29b2a draft

"planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools commit c3917e27eb1c1deeb381aa0dc8161c07699562fb"
author bgruening
date Mon, 11 May 2020 07:48:09 -0400
parents d9bf32d13dfd
children b6eec6087271
line wrap: on
line source

<tool id="cp_identify_primary_objects" name="IdentifyPrimaryObjects" version="@CP_VERSION@">
    <description>identify biological objects of interest</description>

    <macros>
        <import>macros.xml</import>
        <xml name="ipo_common">
            <param name="input_from_nat" type="text" label="Enter the name of the input image (from NamesAndTypes)">
                <expand macro="text_validator" />
            </param>
            <param name="name_to_be_identified" type="text" label="Enter the name of the primary objects to be identified">
                <expand macro="text_validator" />
            </param>
            <param name="min_diameter" type="integer" label="Typical minimum diameter of objects, in pixel units (Min)" value="10" min="0">
                <help>
                    <![CDATA[
                        The min and max diameters are crucial for two reasons: first, the module uses it to calculate certain automatic settings in order to identify your objects of interest properly (see below). Second, when used in conjunction with the 'Discard objects outside the diameter range?' setting below, you can choose to remove objects outside the size range you provide here.
                        ]]>
                </help>
            </param>
            <param name="max_diameter" type="integer" label="Typical maximum diameter of objects, in pixel units (Max)" value="40" min="0" />
            <param name="discard_outside_border" type="select" display="radio" label="Discard objects outside the diameter range?">
                <option value="Yes">Yes</option>
                <option value="No">No</option>
            </param>
            <param name="discard_touching_border" type="select" display="radio" label="Discard objects touching the border of the image?">
                <option value="Yes">Yes</option>
                <option value="No">No</option>
            </param>
        </xml>

        <xml name="clumped_objects_params">
            <conditional name="con_smoothing_filter">
                <param name="smoothing_filter" type="select" label="Automatically calculate size of smoothing filter for declumping?">
                    <help>
                        <![CDATA[
                            Select 'Yes' to automatically calculate the amount of smoothing applied to the image to assist in declumping. Select "No" to manually enter the smoothing filter size.
                            This setting, along with the Minimum allowed distance between local maxima setting, affects whether objects close to each other are considered a single object or multiple objects. It does not affect the dividing lines between an object and the background.
                            Please note that this smoothing setting is applied after thresholding, and is therefore distinct from the threshold smoothing method setting above, which is applied before thresholding.
                            The size of the smoothing filter is automatically calculated based on the Typical diameter of objects, in pixel units (Min,Max) setting above. If you see too many objects merged that ought to be separate or too many objects split up that ought to be merged, you may want to override the automatically calculated value.
                            ]]>
                    </help>
                    <option value="Yes">Yes</option>
                    <option value="No">No</option>
                </param>
                <when value="No">
                    <param name="size_smoothing_filter" type="integer" label="Size of smoothing filter" min="0" max="1" value="1">
                        <help>
                            <![CDATA[
                                If you see too many objects merged that ought to be separated (under-segmentation), this value should be lower. If you see too many objects split up that ought to be merged (over-segmentation), the value should be higher.
                                Note that splitting and merging is also affected by your choice of settings for the setting, Automatically calculate minimum allowed distance between local maxima? It is an art to balance these two settings; read the help carefully for both.
                                Reducing the texture of objects by increasing the smoothing increases the chance that each real, distinct object has only one peak of intensity but also increases the chance that two distinct objects will be recognized as only one object. Note that increasing the size of the smoothing filter increases the processing time exponentially.
                                Enter 0 to prevent any image smoothing in certain cases; for example, for low resolution images with small objects ( < ~5 pixels in diameter).
                                ]]>
                        </help>
                    </param>
                </when>
                <when value="Yes" />
            </conditional>
            <conditional name="con_min_distance">
                <param name="min_distance" type="select" label="Automatically calculate minimum allowed distance between local maxima?">
                    <help>
                        <![CDATA[
                            Select "Yes" to automatically calculate the distance between intensity maxima to assist in declumping. Select "No" to manually enter the permissible maxima distance.
                            This setting, along with the Size of smoothing filter setting, affects whether objects close to each other are considered a single object or multiple objects. It does not affect the dividing lines between an object and the background. Local maxima that are closer together than the minimum allowed distance will be suppressed (the local intensity histogram is smoothed to remove the peaks within that distance).
                            The distance can be automatically calculated based on the minimum entered for the Typical diameter of objects, in pixel units (Min,Max) setting above, but if you see too many objects merged that ought to be separate, or too many objects split up that ought to be merged, you may want to override the automatically calculated value.
                            ]]>
                    </help>
                    <option value="Yes">Yes</option>
                    <option value="No">No</option>
                </param>
                <when value="No">
                    <param name="min_allowed_distance" type="integer" label="Supress local maxima that are closer than this minimum allowed distance" value="7">
                        <help>
                            <![CDATA[
                                Enter a positive integer, in pixel units. If you see too many objects merged that ought to be separated (under-segmentation), the value should be lower. If you see too many objects split up that ought to be merged (over-segmentation), the value should be higher.
                                The maxima suppression distance should be set to be roughly equivalent to the radius of the smallest object of interest that you would expect to see in the experiment.
                                Any distinct 'objects' that are found but are within two times this distance from each other will be assumed to be actually two lumpy parts of the same object, and they will be merged.
                                Note that splitting and merging is also affected by your choice of settings for the setting 'Size of smoothing filter'.
                                ]]>
                        </help>
                    </param>
                </when>
                <when value="Yes" />
            </conditional>
            <param name="speed_up" type="select" display="radio" label="Speed up by using lower-resolution image to find local maxima?">
                <help>
                    <![CDATA[
                        Select 'Yes' to down-sample the image for declumping. This can be helpful for saving processing time on large images.
                        Note that if you have entered a minimum object diameter of 10 or less, checking this box will have no effect.
                        ]]>
                </help>
                <option value="Yes">Yes</option>
                <option value="No">No</option>
            </param>
        </xml>

        <xml name="clumped_objects">
            <conditional name="con_dividing_lines">
                <param name="dividing_lines" type="select" label="Method to draw dividing lines between clumped objects">
                    <help>
                        <![CDATA[
                            This setting allows you to choose the method that is used to draw the line between segmented objects, provided that you have chosen to declump the objects. To decide between these methods, you can run Test mode to see the results of each.
                            <br> - Intensity: Works best where the dividing lines between clumped objects are dimmer than the remainder of the objects.
                            <br> - Technical description: Using the previously identified local maxima as seeds, this method is a watershed (Vincent and Soille, 1991) on the intensity image.
                            <br> - Shape: Dividing lines between clumped objects are based on the shape of the clump. For example, when a clump contains two objects, the dividing line will be placed where indentations occur between the two objects. The intensity patterns in the original image are largely irrelevant: the cells need not be dimmer along the lines between clumped objects. Technical description: Using the previously identified local maxima as seeds, this method is a watershed on the distance-transformed thresholded image.
                            <br> - Propagate: This method uses a propagation algorithm instead of a watershed. The image is ignored and the pixels are assigned to the objects by repeatedly adding unassigned pixels to the objects that are immediately adjacent to them. This method is suited in cases such as objects with branching extensions, for instance neurites, where the goal is to trace outward from the cell body along the branch, assigning pixels in the branch along the way. See the help for the IdentifySecondaryObjects module for more details on this method.
                            <br> - None: If objects are well separated and bright relative to the background, it may be unnecessary to attempt to separate clumped objects. Using the very fast None option, a simple threshold will be used to identify objects.
                            ]]>
                    </help>
                    <option value="Intensity">Intensity</option>
                    <option value="Shape">Shape</option>
                    <option value="Propagate">Propagate</option>
                    <option value="None">None</option>
                </param>
                <when value="Shape">
                    <expand macro="clumped_objects_params"/>
                </when>
                <when value="Intensity">
                    <expand macro="clumped_objects_params"/>
                </when>
                <when value="Propagate"/>
                <when value="None"/>
            </conditional>
        </xml>
        <xml name="otsu_threshold_category">

            <conditional name="con_threshold_class">
                <param name="threshold_class" type="select" label="Two-class or three-class thresholding?">
                    <help>
                        <![CDATA[
                            - Two classes: Select this option if the grayscale levels are readily distinguishable into only two classes: foreground (i.e., regions of interest) and background.
                            <br> - Three classes: Choose this option if the grayscale levels fall instead into three classes: foreground, background and a middle intensity between the two. You will then be asked whether the middle intensity class should be added to the foreground or background class in order to generate the final two-class output.
                            ]]>
                    </help>
                    <option value="Two classes">Two classes</option>
                    <option value="Three classes">Three classes</option>
                </param>
                <when value="Three classes">
                    <param name="assign_pixel" type="select" label="Assign pixels in the middle intensity class to the foreground or the background?" help="Choose whether you want the pixels with middle grayscale intensities to be assigned to the foreground class or the background class.">
                        <option value="Foreground">Foreground</option>
                        <option value="Background">Background</option>
                    </param>
                </when>
                <when value="Two classes" />
            </conditional>
        </xml>
        <xml name="threshold_values">
            <param name="threshold_correction_factor" type="float" value="1.0" min="0.0" label="Threshold correction factor">
                <help>
                    <![CDATA[
                        The value entered here adjusts the threshold either upwards or downwards, by multiplying it by this value.
                        A value of 1 means no adjustment, 0 to 1 makes the threshold more lenient and greater than 1 makes the threshold more stringent.
                        ]]>
                </help>
            </param>
            <param name="threshold_lower" type="float" value="0.0" min="0.0" max="1.0" label="Lower bound on threshold">
                <help>
                    <![CDATA[
                        This is helpful as a safety precaution: when the threshold as calculated automatically is clearly outside a reasonable range, the min/max allowable threshold will override the automatic threshold.
                        ]]>
                </help>
            </param>
            <param name="threshold_upper" type="float" value="1.0" min="0.0" max="1.0" label="Upper bound on threshold"/>
        </xml>
        <xml name="threshold_smoothing_scale">
            <param name="threshold_smoothing_scale" type="float" value="1.3488" label="Threshold smoothing scale">
                <help>
                    <![CDATA[
                        This setting controls the scale used to smooth the input image before the threshold is applied.
                        The input image can be optionally smoothed before being thresholded.
                        Smoothing can improve the uniformity of the resulting objects, by removing holes and jagged edges caused by noise in the acquired image.
                        Smoothing is most likely not appropriate if the input image is binary, if it has already been smoothed or if it is an output of a pixel-based classifier.
                        The scale should be approximately the size of the artifacts to be eliminated by smoothing.
                        A Gaussian is used with a sigma adjusted so that 1/2 of the Gaussian’s distribution falls within the diameter given by the scale (sigma = scale / 0.674) Use a value of 0 for no smoothing.
                        Use a value of 1.3488 for smoothing with a sigma of 1.
                        ]]>
                </help>
            </param>
        </xml>
        <xml name="threshold_method_help">
            <help>
                <![CDATA[
                    The intensity threshold affects the decision of whether each pixel will be considered foreground (region(s) of interest) or background.
                    A higher threshold value will result in only the brightest regions being identified, whereas a lower threshold value will include dim regions.
                    When using the strategy "Global", you can have the threshold automatically calculated from a choice of several methods, however, when you choose "Adaptive" as the thresholding strategy, your only option is Otsu automatic thresholding.
                    The threshold that is used for each image is recorded as a per-image measurement, so if you are surprised by unusual measurements from one of your images, you might check whether the automatically calculated threshold was unusually high or low compared to the other images. See the FlagImage module if you would like to flag an image based on the threshold value.

                    <br> - Otsu: This approach calculates the threshold separating the two classes of pixels (foreground and background) by minimizing the variance within the each class.
                    ]]>
            </help>
        </xml>
    </macros>

    <expand macro="py_requirements"/>
    <expand macro="cmd_modules" />
    <configfiles>
        <inputs name="inputs" />

        <configfile name="script_file">
import json
import sys
import os

FOURSPACES=@SPACES@

input_json_path = sys.argv[1]
input_pipeline= sys.argv[2]

params = json.load(open(input_json_path, "r"))

ipo = params['con_advanced']

adv = params['con_advanced']['advanced']


def write_ipo():
    _str = "\nIdentifyPrimaryObjects:[module_num:%d|svn_version:\\'Unknown\\'|variable_revision_number:13|show_window:True|notes:\\x5B\\'Identify the nuclei from the DNA channel.\\', \\'PARAMS\\x3A\\', \\'- Typical diameter of objects (Min,Max)\\', \\'- Method to distinguish clumped objects\\x3A Shape/None. With Shape, the distance between the 2 centers can be changed.\\'\\x5D|batch_state:array(\\x5B\\x5D, dtype=uint8)|enabled:True|wants_pause:False]\n" % new_count

    _str += FOURSPACES + "Select the input image:%s\n" % ipo['input_from_nat']
    _str += FOURSPACES + "Name the primary objects to be identified:%s\n" % ipo['name_to_be_identified']
    _str += FOURSPACES + "Typical diameter of objects, in pixel units (Min,Max):%d,%d\n" % (ipo['min_diameter'], ipo['max_diameter'])
    _str += FOURSPACES + "Discard objects outside the diameter range?:%s\n" % ipo['discard_outside_border']
    _str += FOURSPACES + "Discard objects touching the border of the image?:%s\n" % ipo['discard_touching_border']


    # default values when adv=no;required in the cppipe file
    distinguish_clumped_objects = "Intensity"
    dividing_lines = "Intensity"
    size_smoothing_filter = 1
    min_allowed_distance = 7
    speed_up = "Yes"
    fill_hole = "After both thresholding and declumping"
    calc_size_smoothing_filter = "Yes"
    calc_min_disance = "Yes"
    excessive_handling = "Continue"
    max_obj =  500
    thre_setting_version = 10
    threshold_strategy = "Global"
    threshold_method = "Minimum cross entropy"
    threshold_smoothing_scale = 1.3488
    threshold_correction_factor = 1.0
    threshold_lower = 0.0
    threshold_upper = 1.0
    manual_threshold = 0.0
    threshold_measurement = "None"
    threshold_class = "Two classes"
    assign_pixel = "Foreground"
    adaptive_window = 50
    lower_outlier_fraction = 0.05
    upper_outlier_fraction = 0.05
    avg_method = "Mean"
    variance_method = "Standard deviation"
    no_of_deviation = 2.0

    if adv == "Yes":
        distinguish_clumped_objects = ipo['con_distinguish_clumped_objects'][
            'distinguish_clumped_objects']
        if "con_dividing_lines" in ipo['con_distinguish_clumped_objects']:
            smoothing = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_smoothing_filter']['smoothing_filter']
            supress = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_min_distance']['min_distance']
            dividing_lines = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['dividing_lines']

            if smoothing == "Yes":
                size_smoothing_filter= 0
            else:
                size_smoothing_filter = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_smoothing_filter'][
                            'size_smoothing_filter']

            if supress == "No":
                min_allowed_distance = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_min_distance'][
                            'min_allowed_distance']

            speed_up = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['speed_up']

            calc_size_smoothing_filter = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_smoothing_filter'][
                        'smoothing_filter']
            calc_min_disance = ipo['con_distinguish_clumped_objects']['con_dividing_lines']['con_min_distance']['min_distance']

        fill_hole = ipo['fill_hole']

        if "con_handling_excessive" in ipo:
            excessive_handling = ipo['con_handling_excessive']['excessive_handling']
            if excessive_handling == "Continue":
                max_obj = 500
            else:
                max_obj = ipo['con_handling_excessive']['max_obj']

        threshold_strategy=ipo['con_threshold_strategy']['threshold_strategy']
        threshold_method = ipo['con_threshold_strategy']['con_threshold_method']['threshold_method']

        if threshold_strategy =="Adaptive":
            adaptive_window =ipo['con_threshold_strategy']['adaptive_window']
            threshold_smoothing_scale = ipo['con_threshold_strategy']['threshold_smoothing_scale']
            threshold_class = ipo['con_threshold_strategy']['con_threshold_method']['con_threshold_class'][
                'threshold_class']
            if threshold_class == "Three classes":
                assing_pixel = ipo['con_threshold_strategy']['con_threshold_method']['con_threshold_class']['assign_pixel']
        else:
            if threshold_method == "Manual":
                manual_threshold = ipo['con_threshold_strategy']['con_threshold_method']['manual_threshold']
            else:
                if threshold_method == "Measurement":
                    threshold_measurement = ipo['con_threshold_strategy']['con_threshold_method']['global_measurement_threshold_cat'] +"_" +ipo['con_threshold_strategy']['con_threshold_method']['global_measurement_threshold_measurement']

                if threshold_method == "Otsu":
                    threshold_class = ipo['con_threshold_strategy']['con_threshold_method']['con_threshold_class'][
                    'threshold_class']
                    if threshold_class == "Three classes":
                        assign_pixel=ipo['con_threshold_strategy']['con_threshold_method']['con_threshold_class']['assign_pixel']

                    threshold_smoothing_scale = ipo['con_threshold_strategy']['con_threshold_method']['threshold_smoothing_scale']

                if threshold_method == "Minimum cross entropy":
                    threshold_smoothing_scale = ipo['con_threshold_strategy']['con_threshold_method']['threshold_smoothing_scale']

                if threshold_method == "RobustBackground":
                    threshold_smoothing_scale = ipo['con_threshold_strategy']['con_threshold_method']['threshold_smoothing_scale']
                    lower_outlier_fraction = ipo['con_threshold_strategy']['con_threshold_method']['lower_outlier_fraction']
                    upper_outlier_fraction =ipo['con_threshold_strategy']['con_threshold_method']['upper_outlier_fraction']
                    avg_method = ipo['con_threshold_strategy']['con_threshold_method']['avg_method']
                    variance_method = ipo['con_threshold_strategy']['con_threshold_method'] ['variance_method']
                    no_of_deviation = ipo['con_threshold_strategy']['con_threshold_method']['no_of_deviations']

                threshold_correction_factor = ipo['con_threshold_strategy']['con_threshold_method'][
                    'threshold_correction_factor']
                threshold_lower = ipo['con_threshold_strategy']['con_threshold_method']['threshold_lower']
                threshold_upper = ipo['con_threshold_strategy']['con_threshold_method']['threshold_upper']

    _str += FOURSPACES + "Method to distinguish clumped objects:%s\n" % distinguish_clumped_objects
    _str += FOURSPACES + "Method to draw dividing lines between clumped objects:%s\n" % dividing_lines
    _str += FOURSPACES + "Size of smoothing filter:%d\n" % size_smoothing_filter
    _str += FOURSPACES + "Suppress local maxima that are closer than this minimum allowed distance:%d\n" % min_allowed_distance
    _str += FOURSPACES + "Speed up by using lower-resolution image to find local maxima?:%s\n" % speed_up
    _str += FOURSPACES + "Fill holes in identified objects?:%s\n" % fill_hole
    _str += FOURSPACES + "Automatically calculate size of smoothing filter for declumping?:%s\n" % calc_size_smoothing_filter
    _str += FOURSPACES + "Automatically calculate minimum allowed distance between local maxima?:%s\n" % calc_min_disance
    _str += FOURSPACES + "Handling of objects if excessive number of objects identified:%s\n" % excessive_handling
    _str += FOURSPACES + "Maximum number of objects:%d\n" % max_obj

    _str += FOURSPACES + "Use advanced settings?:%s\n" % adv
    _str += FOURSPACES + "Threshold settings version:10\n"
    _str += FOURSPACES + "Threshold strategy:%s\n" % threshold_strategy
    _str += FOURSPACES + "Thresholding method:%s\n" % threshold_method
    _str += FOURSPACES + "Threshold smoothing scale:%.4f\n" % threshold_smoothing_scale
    _str += FOURSPACES + "Threshold correction factor:%.1f\n" % threshold_correction_factor
    _str += FOURSPACES + "Lower and upper bounds on threshold:%.1f,%.1f\n" % (threshold_lower, threshold_upper)
    _str += FOURSPACES + "Manual threshold:%d\n" % manual_threshold
    _str += FOURSPACES + "Select the measurement to threshold with:%s\n" % threshold_measurement
    _str += FOURSPACES + "Two-class or three-class thresholding?:%s\n" % threshold_class
    _str += FOURSPACES + "Assign pixels in the middle intensity class to the foreground or the background?:%s\n" % assign_pixel
    _str += FOURSPACES + "Size of adaptive window:%d\n" % adaptive_window
    _str += FOURSPACES + "Lower outlier fraction:%.2f\n" % lower_outlier_fraction
    _str += FOURSPACES + "Upper outlier fraction:%.2f\n" % upper_outlier_fraction
    _str += FOURSPACES + "Averaging method:%s\n" % avg_method
    _str += FOURSPACES + "Variance method:%s\n" % variance_method
    _str += FOURSPACES + "# of deviations:%.2f\n" % no_of_deviation

    _str += FOURSPACES + "Thresholding method:%s\n" % threshold_method  # This is a repeated entry, but needed for pipeline file

    return _str


with open(input_pipeline) as fin:
    lines = fin.readlines()

    k, v = lines[4].strip().split(':')

    module_count = int(v)
    new_count = module_count + 1
    lines[4] = k + ":%d\n" % new_count
    with open("output.cppipe", "w") as f:
        f.writelines(lines)
        f.write(write_ipo())
    f.close()
        </configfile>
    </configfiles>

    <inputs>
        <expand macro="input_pipeline_param" />
        <conditional name="con_advanced">
            <param name="advanced" type="select" label="Use advanced settings?">
                <option value="No">No, use basic settings</option>
                <option value="Yes">Yes, use advanced settings</option>
            </param>
            <when value="No">
                <expand macro="ipo_common" />
            </when>
            <when value="Yes">
                <expand macro="ipo_common" />
                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" type="select" label="Threshold strategy">
                        <help>
                            <![CDATA[
                                The thresholding strategy determines the type of input that is used to calculate the threshold. These options allow you to calculate a threshold based on the whole image or based on image sub-regions.
                                The choices for the threshold strategy are:

                                <br> - Global: Calculates a single threshold value based on the unmasked pixels of the input image and use that value to classify pixels above the threshold as foreground and below as background.
                                image0 This strategy is fast and robust, especially if the background is relatively uniform (for example, after illumination correction).

                                <br> - Adaptive: Calculates a different threshold for each pixel, thus adapting to changes in foreground/background intensities across the image. For each pixel, the threshold is calculated based on the pixels within a given neighborhood (or window) surrounding that pixel.
                                image1 This method is slower but can produce better results for non-uniform backgrounds. However, for significant illumination variation, using the CorrectIllumination modules is preferable.
                                ]]>
                        </help>
                        <option value="Global">Global</option>
                        <option value="Adaptive" selected="true">Adaptive</option>
                    </param>
                    <when value="Adaptive">
                        <conditional name="con_threshold_method">
                            <param name="threshold_method" type="select" label="Thresholding method">
                                <expand macro="threshold_method_help"/>
                                <option value="Otsu" selected="True">Otsu</option>
                            </param>
                            <when value="Otsu">
                                <expand macro="otsu_threshold_category" />

                            </when>
                        </conditional>
                        <param name="adaptive_window" type="integer" label="Size of the adaptive window" value="50" help="Often a good choice is some multiple of the largest expected object size." />
                        <expand macro="threshold_smoothing_scale" />
                        <expand macro="threshold_values" />
                    </when>
                    <when value="Global">
                        <conditional name="con_threshold_method">
                            <param name="threshold_method" type="select" label="Thresholding method">
                                <expand macro="threshold_method_help"/>
                                <option value="Manual">Manual</option>
                                <option value="Measurement">Measurement</option>
                                <option value="Minimum cross entropy">Minimum cross entropy</option>
                                <option value="Otsu" selected="True">Otsu</option>
                                <option value="RobustBackground">Robust background</option>
                            </param>
                            <when value="Otsu">
                                <expand macro="otsu_threshold_category" />

                                <expand macro="threshold_smoothing_scale" />
                                <expand macro="threshold_values" />
                            </when>
                            <when value="Manual">
                                <param name="manual_threshold" type="float" label="Enter the value that will act as an absolute threshold for the images" min="0" max="1" value="0" />
                            </when>
                            <when value="RobustBackground">
                                <param name="lower_outlier_fraction" type="float" value="0.05" min="0.0" max="1.0" label="Lower outlier fraction" />
                                <param name="upper_outlier_fraction" type="float" value="0.05" min="0.0" max="1.0" label="Upper outlier fraction" />
                                <param name="avg_method" type="select" label="Averaging method">
                                    <option value="Mean">Mean</option>
                                    <option value="Median">Median</option>
                                    <option value="Mode">Mode</option>
                                </param>
                                <param name="variance_method" type="select" label="Variance">
                                    <option value="Standard deviation">Standard deviation</option>
                                    <option value="Median absolute deviation">Median absolute deviation</option>
                                </param>
                                <param name="no_of_deviations" type="float" value="2.0" label="# of deviations">
                                    <help>
                                        <![CDATA[
                                        Robust background calculates the variance, multiplies it by the value given by this setting and adds it to the average.
                                        Adding several deviations raises the threshold well above the average. Use a larger number to be more stringent about identifying foreground pixels.
                                        Use a smaller number to be less stringent. It’s even possible to use a negative number if you want the threshold to be lower than the average (e.g., for images that are densely covered by foreground).
                                        ]]>
                                    </help>
                                </param>
                                <expand macro="threshold_smoothing_scale" />
                                <expand macro="threshold_values" />
                            </when>
                            <when value="Measurement">
                                <param name="global_measurement_threshold_cat" type="select" label="Select the measurement category to threshold with">
                                    <option value="FileName">File Name</option>
                                    <option value="Frame">Frame</option>
                                    <option value="Height">Height</option>
                                    <option value="MD5Digest">MD5Digest</option>
                                    <option value="PathName">Path Name</option>
                                    <option value="Scaling">Scaling</option>
                                    <option value="Series">Series</option>
                                    <option value="URL">URL</option>
                                    <option value="Width">Width</option>
                                </param>
                                <param name="global_measurement_threshold_measurement" type="text" label="Select the measurement to threshold with">
                                    <help>
                                        Measurement corresponds to the names in Starting modules. 
                                    </help>
                                </param>
                                <expand macro="threshold_values" />
                            </when>
                            <when value="Minimum cross entropy">
                                <expand macro="threshold_smoothing_scale" />
                                <expand macro="threshold_values" />
                            </when>
                        </conditional>
                    </when>
                </conditional>
                

                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" type="select" label="Method to distinguish clumped objects">
                        <help>
                            <![CDATA[
                                This setting allows you to choose the method that is used to distinguish between individual objects that are touching each other (and not properly delineated as two objects by thresholding alone). In other words, this setting allows you to “declump” a large, merged object into individual objects of interest. To decide between these methods, you can run Test mode to see the results of each.
                                <br> - Intensity: For objects that tend to have only a single peak of brightness (e.g., objects that are brighter towards their interiors and dimmer towards their edges), this option counts each intensity peak as a separate object. The objects can be any shape, so they need not be round and uniform in size as would be required for the Shape option.
                                <br> - Shape: For cases when there are definite indentations separating objects. The image is converted to black and white (binary) and the shape determines whether clumped objects will be distinguished. The declumping results of this method are affected by the thresholding method you choose.
                                <br> - None: If objects are well separated and bright relative to the background, it may be unnecessary to attempt to separate clumped objects. Using the very fast None option, a simple threshold will be used to identify objects.
                                ]]>
                        </help>
                        <option value="Shape">Shape</option>
                        <option value="Intensity" selected="True">Intensity</option>
                        <option value="None">None</option>
                    </param>
                    <when value="Shape">
                        <expand macro="clumped_objects"/>
                    </when>
                    <when value="Intensity">
                        <expand macro="clumped_objects"/>
                    </when>
                    <when value="None"/>
                </conditional>
                <param name="fill_hole" type="select" label="Fill holes in identified objects">
                    <help>
                        <![CDATA[
                            This option controls how holes (regions of background surrounded by one or more objects) are filled in:
                            <br> - After both thresholding and declumping: Fill in holes that are smaller than the maximum object size prior to declumping and to fill in any holes after declumping.
                            <br> - After declumping only: Fill in holes located within identified objects after declumping.
                            <br> - Never: Leave holes within objects. Please note that if an object is located within a hole and this option is enabled, the object will be lost when the hole is filled in.
                            ]]>
                    </help>
                    <option value="Never">Never</option>
                    <option value="After both thresholding and declumping" selected="True">After both thresholding and declumping</option>
                    <option value="After declumping only">After declumping only</option>
                </param>

                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" type="select" label="Handling of objects if excessive number of objects identified">
                        <help>
                            <![CDATA[
                                This setting deals with images that are segmented into an unreasonable number of objects. This might happen if the module calculates a low threshold or if the image has unusual artifacts. IdentifyPrimaryObjects can handle this condition in one of three ways:
                                <br> - Continue: Continue processing regardless if large numbers of objects are found.
                                <br> - Erase: Erase all objects if the number of objects exceeds the maximum. This results in an image with no primary objects. This option is a good choice if a large number of objects indicates that the image should not be processed; it can save a lot of time in subsequent Measure modules.
                                ]]>
                        </help>
                        <option value="Continue">Continue</option>
                        <option value="Erase">Erase</option>
                    </param>
                    <when value="Erase">
                        <param name="max_obj" type="integer" value="500" label="Maximum number of objects" help="This setting limits the number of objects in the image." />
                    </when>
                    <when value="Continue" />
                </conditional>
            </when>
        </conditional>
    </inputs>

    <outputs>
        <expand macro="output_pipeline_param" />
    </outputs>

    <tests>
        <test>
            <!-- no advanced setting -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="No" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="15" />
                <param name="max_diameter" value="200" />
                <param name="discard_outside_border" value="Yes" />
                <param name="discard_touching_border" value="Yes" />
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_noadv.cppipe" />
        </test>
        <test>
            <!-- advanced setting, adaptive threshold strategy, otsu method -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="Yes" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="15" />
                <param name="max_diameter" value="200" />
                <param name="discard_outside_border" value="Yes" />
                <param name="discard_touching_border" value="Yes" />

                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" value="Adaptive" />
                    <conditional name="con_threshold_method">
                        <param name="threshold_method" value="Otsu" />
                        <conditional name="con_threshold_class">
                            <param name="threshold_class" value="Three classes" />
                            <param name="assign_pixel" value="Foreground" />
                        </conditional>
                    </conditional>
                    <param name="adaptive_window" value="50" />
                    <param name="threshold_smoothing_scale" value="1.5" />
                    <param name="threshold_correction_factor" value="1" />
                    <param name="threshold_lower" value="0.0" />
                    <param name="threshold_upper" value="1.0" />
                </conditional>
                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" value="Shape" />
                    <conditional name="con_dividing_lines" >
                        <param name="dividing_lines" value="Shape" />
                        <conditional name="con_smoothing_filter">
                            <param name="smoothing_filter" value="No"/>
                            <param name="size_smoothing_filter" value="1" />
                        </conditional>
                        <conditional name="con_min_distance">
                            <param name="min_distance" value="No"/>
                            <param name="min_allowed_distance" value="1"/>
                        </conditional>
                        <param name="speed_up" value="Yes" />
                    </conditional>
                </conditional>
                <param name="fill_hole" value="After both thresholding and declumping" />
                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" value="Continue"/>
                </conditional>
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_adv_adaptive_otsu.cppipe" />
        </test>

        <test>
            <!-- advanced setting, global threshold strategy, manual method -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="Yes" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="5" />
                <param name="max_diameter" value="20" />
                <param name="discard_outside_border" value="No" />
                <param name="discard_touching_border" value="Yes" />

                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" value="Global" />
                    <conditional name="con_threshold_method">
                        <param name="threshold_method" value="Manual" />
                        <param name="manual_threshold" value="1" />
                      </conditional>
                </conditional>
                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" value="Shape" />
                    <conditional name="con_dividing_lines" >
                        <param name="dividing_lines" value="Shape" />
                        <conditional name="con_smoothing_filter">
                            <param name="smoothing_filter" value="No"/>
                            <param name="size_smoothing_filter" value="1" />
                        </conditional>
                        <conditional name="con_min_distance">
                            <param name="min_distance" value="No"/>
                            <param name="min_allowed_distance" value="1"/>
                        </conditional>
                        <param name="speed_up" value="Yes" />
                    </conditional>
                </conditional>
                <param name="fill_hole" value="After both thresholding and declumping" />
                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" value="Erase"/>
                    <param name="max_obj" value="499" />
                </conditional>
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_adv_global_manual.cppipe" />
        </test>
        <test>
            <!-- advanced setting, global threshold strategy, measurement method -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="Yes" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="5" />
                <param name="max_diameter" value="20" />
                <param name="discard_outside_border" value="Yes" />
                <param name="discard_touching_border" value="No" />

                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" value="Global" />
                    <conditional name="con_threshold_method">
                        <param name="threshold_method" value="Measurement" />
                        <param name="global_measurement_threshold_cat" value="FileName" />
                        <param name="global_measurement_threshold_measurement" value="DNA" />
                        <param name="threshold_correction_factor" value="1" />
                        <param name="threshold_lower" value="0.1" />  
                        <param name="threshold_upper" value="0.4" />
                    </conditional>
                </conditional>
                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" value="Intensity" />
                    <conditional name="con_dividing_lines" >
                        <param name="dividing_lines" value="Shape" />
                        <conditional name="con_smoothing_filter">
                            <param name="smoothing_filter" value="Yes"/>
                        </conditional>
                        <conditional name="con_min_distance">
                            <param name="min_distance" value="No"/>
                            <param name="min_allowed_distance" value="6"/>
                        </conditional>
                        <param name="speed_up" value="Yes" />
                    </conditional>
                </conditional>
                <param name="fill_hole" value="After both thresholding and declumping" />
                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" value="Continue"/>
                </conditional>
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_adv_global_measurement.cppipe" />
        </test>

        <test>
            <!-- advanced setting, global threshold strategy, minimum cross entropy method -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="Yes" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="15" />
                <param name="max_diameter" value="40" />
                <param name="discard_outside_border" value="Yes" />
                <param name="discard_touching_border" value="Yes" />

                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" value="Global" />
                    <conditional name="con_threshold_method">
                        <param name="threshold_method" value="Minimum cross entropy" />
                        <param name="threshold_smoothing_scale" value="1.5" />
                        <param name="threshold_correction_factor" value="1" />
                        <param name="threshold_lower" value="0.0" />
                        <param name="threshold_upper" value="1.0" />
                    </conditional>
                </conditional>
                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" value="Shape" />
                    <conditional name="con_dividing_lines" >
                        <param name="dividing_lines" value="Shape" />
                        <conditional name="con_smoothing_filter">
                            <param name="smoothing_filter" value="No"/>
                            <param name="size_smoothing_filter" value="1" />
                        </conditional>
                        <conditional name="con_min_distance">
                            <param name="min_distance" value="No"/>
                            <param name="min_allowed_distance" value="7"/>
                        </conditional>
                        <param name="speed_up" value="Yes" />
                    </conditional>
                </conditional>
                <param name="fill_hole" value="After both thresholding and declumping" />
                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" value="Continue"/>
                </conditional>
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_adv_global_mce.cppipe" />
        </test>

        <test>
            <!-- advanced setting, global threshold strategy, robustbackground method -->
            <expand macro="test_input_pipeline_param" />
            <conditional name="con_advanced">
                <param name="advanced" value="Yes" />
                <param name="input_from_nat" value="DNA" />
                <param name="name_to_be_identified" value="Nuclei" />
                <param name="min_diameter" value="10" />
                <param name="max_diameter" value="40" />
                <param name="discard_outside_border" value="Yes" />
                <param name="discard_touching_border" value="Yes" />

                <conditional name="con_threshold_strategy">
                    <param name="threshold_strategy" value="Global" />
                    <conditional name="con_threshold_method">
                        <param name="threshold_method" value="RobustBackground" />
                        <param name="lower_outlier_fraction" value="0.06" />
                        <param name="upper_outlier_fraction" value="0.07" />
                        <param name="avg_method" value="Median"/>
                        <param name="variance_method" value="Median absolute deviation"/>
                        <param name="no_of_deviations" value="3.0" />
                        <param name="threshold_smoothing_scale" value="1.4" />
                        <param name="threshold_correction_factor" value="1" />
                        <param name="threshold_lower" value="0.0" />
                        <param name="threshold_upper" value="1.0" />
                    </conditional>
                </conditional>
                <conditional name="con_distinguish_clumped_objects">
                    <param name="distinguish_clumped_objects" value="Shape" />
                    <conditional name="con_dividing_lines" >
                        <param name="dividing_lines" value="Shape" />
                        <conditional name="con_smoothing_filter">
                            <param name="smoothing_filter" value="No"/>
                            <param name="size_smoothing_filter" value="1" />
                        </conditional>
                        <conditional name="con_min_distance">
                            <param name="min_distance" value="No"/>
                            <param name="min_allowed_distance" value="7"/>
                        </conditional>
                        <param name="speed_up" value="Yes" />
                    </conditional>
                </conditional>
                <param name="fill_hole" value="After both thresholding and declumping" />
                <conditional name="con_handling_excessive">
                    <param name="excessive_handling" value="Continue"/>
                </conditional>
            </conditional>
            <expand macro="test_out_file" file="identify_primary_objects_adv_global_rb.cppipe" />
        </test>

    </tests>

    <help>
        <![CDATA[
            .. class:: infomark

            **What it does**

            This tool identifies biological objects of interest. It requires grayscale images containing bright objects on a dark background. Incoming images must be 2D (including 2D slices of 3D images); please use the Watershed module for identification of objects in 3D.

            @COMMON_HELP@
            ]]>
    </help>

    <expand macro="citations" />

</tool>