Example #1
0
 def __init__(self, index, operation):
     self.__index = index
     self.__operation = operation
     self.__operand_choice = cps.Choice(
         self.operand_choice_text(), MC_ALL,doc="""
         Indicate whether the operand is an image or object measurement.""")
     
     self.__operand_objects = cps.ObjectNameSubscriber(
         self.operand_objects_text(),cps.NONE,doc="""
         Choose the objects you want to measure for this operation.""")
     
     self.__operand_measurement = cps.Measurement(
         self.operand_measurement_text(),
         self.object_fn,doc="""
         Enter the category that was used to create the measurement. You
         will be prompted to add additional information depending on 
         the type of measurement that is requested.""")
     
     self.__multiplicand = cps.Float(
         "Multiply the above operand by",1,doc="""
         Enter the number by which you would like to multiply the above operand.""")
     
     self.__exponent = cps.Float(
         "Raise the power of above operand by",1,doc="""
         Enter the power by which you would like to raise the above operand.""")
Example #2
0
 def add_image(self, removable=True):
     # The text for these settings will be replaced in renumber_settings()
     group = cps.SettingsGroup()
     group.removable = removable
     group.append("image_or_measurement", cps.Choice(
         "Image or measurement?", [IM_IMAGE, IM_MEASUREMENT],
         doc="""You can perform math operations using two images or you
         can use a measurement for one of the operands. For instance,
         to divide the intensity of one image by another, choose Image
         for both and pick the respective images. To divide the intensity
         of an image by its median intensity, use <b>MeasureImageIntensity</b>
         prior to this module to calculate the median intensity, then
         select "Measurement" and use the median intensity measurement as
         the denominator"""))
     group.append("image_name", cps.ImageNameSubscriber("", "",doc="""Which image do you want to use for this operation?"""))
     group.append("measurement", cps.Measurement(
         "Measurement", lambda : cpmeas.IMAGE,"",
         doc="""This is a measurement made on the image. The value of the
         measurement is used for the operand for all of the pixels of the
         other operand's image."""))
     group.append("factor", cps.Float("", 1,doc="""By what number would you like to multiply the above image? This multiplication
             is applied before other operations."""))
     if removable:
         group.append("remover", cps.RemoveSettingButton("", "Remove this image", self.images, group))
     group.append("divider", cps.Divider())
     self.images.append(group)
Example #3
0
    def add_measurement(self, flag_settings, can_delete=True):
        measurement_settings = flag_settings.measurement_settings

        group = cps.SettingsGroup()
        group.append("divider1", cps.Divider(line=False))
        group.append(
            "source_choice",
            cps.Choice("Flag is based on",
                       S_ALL,
                       doc='''
                <ul>
                <li><i> Whole-image measurement:</i> A per-image measurement, such as intensity or granularity.</li>
                <li><i> Average measurement for all objects in each image:</i> The average of all object measurements in the image.</li>
                <li><i> Measurements for all objects in each image:</i> All the 
                object measurements in an image, without averaging. In other words, if <i>any</i> of the objects meet the criteria, the image will be flagged.</li>
                </ul>'''))
        group.append(
            "object_name",
            cps.ObjectNameSubscriber(
                "Select the object whose measurements will be used to flag",
                "None",
                doc=
                '''<i>(Used only when flag is based on an object measurement)</i><br>What did you call the objects whose measurements you want to use for flagging?'''
            ))

        def object_fn():
            if group.source_choice == S_IMAGE:
                return cpmeas.IMAGE
            return group.object_name.value

        group.append("measurement",
                     cps.Measurement("Which measurement?", object_fn))
        group.append(
            "wants_minimum",
            cps.Binary(
                "Flag images based on low values?",
                True,
                doc=
                '''Images with measurements below this cutoff will be flagged.'''
            ))
        group.append("minimum_value", cps.Float("Minimum value", 0))
        group.append(
            "wants_maximum",
            cps.Binary(
                "Flag images based on high values?",
                True,
                doc=
                '''Images with measurements above this cutoff will be flagged.'''
            ))
        group.append("maximum_value", cps.Float("Maximum value", 1))

        if can_delete:
            group.append(
                "remover",
                cps.RemoveSettingButton("", "Remove this measurement",
                                        measurement_settings, group))

        group.append("divider2", cps.Divider(line=True))
        measurement_settings.append(group)
    def add_measurement(self, can_delete=True):
        '''Add another measurement to the filter list'''
        group = cps.SettingsGroup()
        group.append(
            "measurement",
            cps.Measurement('Select the measurement to filter by',
                            self.object_name.get_value,
                            "AreaShape_Area",
                            doc="""
            <i>(Used only if filtering using measurements)</i><br>
            See the <b>Measurements</b> modules help pages 
            for more information on the features measured."""))

        group.append(
            "wants_minimum",
            cps.Binary('Filter using a minimum measurement value?',
                       True,
                       doc="""
            <i>(Used only if Limits is selected for filtering method)</i><br>
            Check this box to filter the objects based on a minimum acceptable object
            measurement value. Objects which are greater than or equal to this value
            will be retained."""))

        group.append("min_limit", cps.Float('Minimum value', 0))

        group.append(
            "wants_maximum",
            cps.Binary('Filter using a maximum measurement value?',
                       True,
                       doc="""
            <i>(Used only if Limits is selected for filtering method)</i><br>
            Check this box to filter the objects based on a maximum acceptable object
            measurement value. Objects which are less than or equal to this value
            will be retained."""))

        group.append("max_limit", cps.Float('Maximum value', 1))
        group.append("divider", cps.Divider())
        self.measurements.append(group)
        if can_delete:
            group.append(
                "remover",
                cps.RemoveSettingButton("Remove above measurement", "Remove",
                                        self.measurements, group))
Example #5
0
    def create_settings(self):
        """Create your settings by subclassing this function
        
        create_settings is called at the end of initialization.
        
        You should create the setting variables for your module here:
            # Ask the user for the input image
            self.image_name = cellprofiler.settings.ImageNameSubscriber(...)
            # Ask the user for the name of the output image
            self.output_image = cellprofiler.settings.ImageNameProvider(...)
            # Ask the user for a parameter
            self.smoothing_size = cellprofiler.settings.Float(...)"""

        self.grouping_values = cps.Measurement(
            "Select the image measurement describing the positive and negative control status",
            lambda: cpmeas.IMAGE,
            doc='''
            The Z' factor, a measure of assay quality, is calculated by this 
            module based on measurements from images that are specified as positive controls 
            and images that are specified as negative controls. (Images that are neither are 
            ignored.) The module assumes that 
            all of the negative controls are specified by a minimum value, all of the
            positive controls are specified by a maximum value, and all other images have an 
            intermediate value; this might allow you to use your dosing information to also 
            specify the positive and negative controls. If you don't use actual dose 
            data to designate your controls, a common practice is to designate -1 as a 
            negative control, 0 as an experimental sample, and 1 as a positive control.  
            In other words, positive controls should all be specified by a single high 
            value (for instance, 1) and negative controls should all be specified by a 
            single low value (for instance, 0). Other samples should have an intermediate value
            to exclude them from the Z' factor analysis.<p>
            The typical way to provide this information in the pipeline is to create 
            a text comma-delimited (CSV) file outside of CellProfiler and then load that file into the pipeline
            using the <b>Metadata</b> module or the legacy <b>LoadData</b> module. In that case, choose the
            measurement that matches the column header of the measurement
            in the input file. See the <b>Metadata</b> module help for an example text file.'''
        )
        self.dose_values = []
        self.add_dose_value(can_remove=False)
        self.add_dose_button = cps.DoSomething(
            "", "Add another dose specification", self.add_dose_value)
Example #6
0
    def add_single_measurement(self, can_delete=True):
        '''Add a single measurement to the group of single measurements

        can_delete - True to include a "remove" button, False if you're not
                     allowed to remove it.
        '''
        group = cps.SettingsGroup()
        if can_delete:
            group.append("divider", cps.Divider(line=True))

        group.append(
            "object_name",
            cps.ObjectNameSubscriber(
                "Select the object to be classified",
                cps.NONE,
                doc="""The name of the objects to be classified. You can
            choose from objects created by any previous module. See
            <b>IdentifyPrimaryObjects</b>, <b>IdentifySecondaryObjects</b>, or
            <b>IdentifyTertiaryObjects</b>."""))

        def object_fn():
            return group.object_name.value

        group.append(
            "measurement",
            cps.Measurement("Select the measurement to classify by",
                            object_fn,
                            doc="""
            Select a measurement made by a previous module. The objects
            will be classified according to their values for this
            measurement."""))

        group.append(
            "bin_choice",
            cps.Choice("Select bin spacing", [BC_EVEN, BC_CUSTOM],
                       doc="""
            Select how you want to define the spacing of the bins.
            You have the following options:
            <ul>
            <li><i>%(BC_EVEN)s:</i> Choose this if you want to specify
            bins of equal size, bounded by upper and lower limits. If you
            want two bins, choose this option and then provide a single
            threshold when asked.</li>
            <li><i>%(BC_CUSTOM)s:</i> Choose this option to create the
            indicated number of bins  at evenly spaced intervals between the
            low and high threshold.
            You also have the option to create bins for objects that fall below
            or above the low and high threshold.</li>
            </ul>
            """ % globals()))

        group.append(
            "bin_count",
            cps.Integer("Number of bins",
                        3,
                        minval=1,
                        doc="""
            This is the number of bins that will be created between
            the low and high threshold"""))

        group.append(
            "low_threshold",
            cps.Float("Lower threshold",
                      0,
                      doc="""
            <i>(Used only if "%(BC_EVEN)s" selected)</i><br>
            This is the threshold that separates the lowest bin from the
            others. The lower threshold, upper threshold, and number of bins
            define the thresholds of bins between the lowest and highest.
            """ % globals()))

        group.append(
            "wants_low_bin",
            cps.Binary("Use a bin for objects below the threshold?",
                       False,
                       doc="""
            Select <i>%(YES)s</i> if you want to create a bin for objects
            whose values fall below the low threshold. Select <i>%(NO)s</i>
            if you do not want a bin for these objects.
            """ % globals()))

        def min_upper_threshold():
            return group.low_threshold.value + np.finfo(float).eps

        group.append(
            "high_threshold",
            cps.Float("Upper threshold",
                      1,
                      minval=cps.NumberConnector(min_upper_threshold),
                      doc="""
            <i>(Used only if "%(BC_EVEN)s" selected)</i><br>
            This is the threshold that separates the last bin from
            the others.
            <i>Note:</i> If you would like two bins, you should select <i>%(BC_CUSTOM)s</i>.
            """ % globals()))

        group.append(
            "wants_high_bin",
            cps.Binary("Use a bin for objects above the threshold?",
                       False,
                       doc="""
            Select <i>%(YES)s</i> if you want to create a bin for objects
            whose values are above the high threshold. <br>
            Select <i>%(NO)s</i> if you do not want a bin for these objects."""
                       % globals()))

        group.append(
            "custom_thresholds",
            cps.Text(
                "Enter the custom thresholds separating the values between bins",
                "0,1",
                doc="""
            <i>(Used only if "%(BC_CUSTOM)s" selected)</i><br>
            This setting establishes the threshold values for the
            bins. You should enter one threshold between each bin, separating
            thresholds with commas (for example, <i>0.3, 1.5, 2.1</i> for four bins).
            The module will create one more bin than there are thresholds.
            """ % globals()))

        group.append(
            "wants_custom_names",
            cps.Binary("Give each bin a name?",
                       False,
                       doc="""
            Select <i>%(YES)s</i> to assign custom names to bins you have
            specified.
            <p>Select <i>%(NO)s</i> for the module to automatically
            assign names based on the measurements and the bin number.""" %
                       globals()))

        group.append(
            "bin_names",
            cps.Text("Enter the bin names separated by commas",
                     cps.NONE,
                     doc="""
            <i>(Used only if Give each bin a name? is checked)</i><br>
            Enter names for each of the bins, separated by commas.
            An example including three bins might be <i>First,Second,Third</i>."""
                     ))

        group.append(
            "wants_images",
            cps.Binary("Retain an image of the classified objects?",
                       False,
                       doc="""
            Select <i>%(YES)s</i> to keep an image of the objects which is color-coded according
            to their classification, for use later in the pipeline (for example,
            to be saved by a <b>SaveImages</b> module).""" % globals()))

        group.append(
            "image_name",
            cps.ImageNameProvider("Name the output image",
                                  "ClassifiedNuclei",
                                  doc="""
            Enter the name to be given to the classified object
            image."""))

        group.can_delete = can_delete

        def number_of_bins():
            '''Return the # of bins in this classification'''
            if group.bin_choice == BC_EVEN:
                value = group.bin_count.value
            else:
                value = len(group.custom_thresholds.value.split(",")) - 1
            if group.wants_low_bin:
                value += 1
            if group.wants_high_bin:
                value += 1
            return value

        group.number_of_bins = number_of_bins

        def measurement_name():
            '''Get the measurement name to use inside the bin name

            Account for conflicts with previous measurements
            '''
            measurement_name = group.measurement.value
            other_same = 0
            for other in self.single_measurements:
                if id(other) == id(group):
                    break
                if other.measurement.value == measurement_name:
                    other_same += 1
            if other_same > 0:
                measurement_name += str(other_same)
            return measurement_name

        def bin_feature_names():
            '''Return the feature names for each bin'''
            if group.wants_custom_names:
                return [
                    name.strip() for name in group.bin_names.value.split(",")
                ]
            return [
                '_'.join((measurement_name(), 'Bin_%d' % (i + 1)))
                for i in range(number_of_bins())
            ]

        group.bin_feature_names = bin_feature_names

        def validate_group():
            bin_name_count = len(bin_feature_names())
            bin_count = number_of_bins()
            if bin_count < 1:
                bad_setting = (group.bin_count if group.bin_choice == BC_EVEN
                               else group.custom_thresholds)
                raise cps.ValidationError(
                    "You must have at least one bin in order to take measurements. "
                    "Either add more bins or ask for bins for objects above or below threshold",
                    bad_setting)
            if bin_name_count != number_of_bins():
                raise cps.ValidationError(
                    "The number of bin names (%d) does not match the number of bins (%d)."
                    % (bin_name_count, bin_count), group.bin_names)
            for bin_feature_name in bin_feature_names():
                cps.AlphanumericText.validate_alphanumeric_text(
                    bin_feature_name, group.bin_names, True)
            if group.bin_choice == BC_CUSTOM:
                try:
                    [
                        float(x.strip())
                        for x in group.custom_thresholds.value.split(",")
                    ]
                except ValueError:
                    raise cps.ValidationError(
                        'Custom thresholds must be a comma-separated list '
                        'of numbers (example: "1.0, 2.3, 4.5")',
                        group.custom_thresholds)

        group.validate_group = validate_group

        if can_delete:
            group.remove_settings_button = cps.RemoveSettingButton(
                "", "Remove this classification", self.single_measurements,
                group)
        self.single_measurements.append(group)
    def create_settings(self):
        """Create your settings by subclassing this function
        
        create_settings is called at the end of initialization.
        
        You should create the setting variables for your module here:
            # Ask the user for the input image
            self.image_name = cellprofiler.settings.ImageNameSubscriber(...)
            # Ask the user for the name of the output image
            self.output_image = cellprofiler.settings.ImageNameProvider(...)
            # Ask the user for a parameter
            self.smoothing_size = cellprofiler.settings.Float(...)
        """
        self.objects_or_image = cps.Choice(
            "Display object or image measurements?", [OI_OBJECTS, OI_IMAGE],
            doc="""
            <ul>
            <li><i>%(OI_OBJECTS)s</i> displays measurements made on
            objects.</li>
            <li><i>%(OI_IMAGE)s</i> displays a single measurement made
            on an image.</li> 
            </ul>""" % globals())

        self.objects_name = cps.ObjectNameSubscriber(
            "Select the input objects",
            cps.NONE,
            doc="""
            <i>(Used only when displaying object measurements)</i><br>
            Choose the name of objects identified by some previous
            module (such as <b>IdentifyPrimaryObjects</b> or
            <b>IdentifySecondaryObjects</b>).""")

        def object_fn():
            if self.objects_or_image == OI_OBJECTS:
                return self.objects_name.value
            else:
                return cpmeas.IMAGE

        self.measurement = cps.Measurement("Measurement to display",
                                           object_fn,
                                           doc="""
            Choose the measurement to display. This will be a measurement
            made by some previous module on either the whole image (if
            displaying a single image measurement) or on the objects you
            selected.""")

        self.image_name = cps.ImageNameSubscriber(
            "Select the image on which to display the measurements",
            cps.NONE,
            doc="""
            Choose the image to be displayed behind the measurements.
            This can be any image created or loaded by a previous module.""")

        self.color_or_text = cps.Choice(
            "Display mode", [CT_TEXT, CT_COLOR],
            doc="""<i>(Used only when displaying object measurements)</i><br>
            Choose how to display the measurement information. If you choose
            %(CT_TEXT)s, <b>DisplayDataOnImage</b> will display the numeric
            value on top of each object. If you choose %(CT_COLOR)s,
            <b>DisplayDataOnImage</b> will convert the image to grayscale, if
            necessary, and display the portion of the image within each object
            using a hue that indicates the measurement value relative to
            the other objects in the set using the default color map.
            """ % globals())

        self.colormap = cps.Colormap(
            "Color map",
            doc="""<i>(Used only when displaying object measurements)</i><br>
            This is the color map used as the color gradient for coloring the
            objects by their measurement values.
            """)
        self.text_color = cps.Text("Text color",
                                   "red",
                                   doc="""
            This is the color that will be used when displaying the text.
            There are several different ways by which you can specify the color:<br>
            <ul>
            <li><i>Single letter:</i> "b"=blue, "g"=green, "r"=red, "c"=cyan, "m"=magenta,
            "y"=yellow, "k"=black, "w"=white</li>
            <li><i>Name:</i> You can use any name supported by HTML; a list of colors is shown on
            <a href="http://www.w3schools.com/html/html_colors.asp">this page</a>.
            </li>
            <li><i>RGB code:</i> You can specify the color as a combination of
            the red, green, and blue intensities, for instance, "#FFFF00"
            for yellow; yellow = red("FF") + green("FF") + blue("00"), where <i>FF</i> is
            hexadecimal for 255, the highest intensity. See  
            <a href="http://www.w3schools.com/html/html_colors.asp">this page</a> for a more detailed
            explanation.</li>
            </ul>""")

        self.display_image = cps.ImageNameProvider(
            "Name the output image that has the measurements displayed",
            "DisplayImage",
            doc="""
            The name that will be given to the image with
            the measurements superimposed. You can use this name to refer to the image in
            subsequent modules (such as <b>SaveImages</b>).""")

        self.font_size = cps.Integer("Font size (points)", 10, minval=1)

        self.decimals = cps.Integer("Number of decimals", 2, minval=0)

        self.saved_image_contents = cps.Choice("Image elements to save",
                                               [E_IMAGE, E_FIGURE, E_AXES],
                                               doc="""
            This setting controls the level of annotation on the image:
            <ul>
            <li><i>%(E_IMAGE)s:</i> Saves the image with the overlaid measurement annotations.</li>
            <li><i>%(E_AXES)s:</i> Adds axes with tick marks and image coordinates.</li>
            <li><i>%(E_FIGURE)s:</i> Adds a title and other decorations.</li></ul>"""
                                               % globals())

        self.offset = cps.Integer("Annotation offset (in pixels)",
                                  0,
                                  doc="""
            Add a pixel offset to the measurement. Normally, the text is
            placed at the object (or image) center, which can obscure relevant features of
            the object. This setting adds a specified offset to the text, in a random
            direction.""")
Example #8
0
    def create_settings(self):
        self.image_name = cps.ImageNameSubscriber(
            "Select the input image",
            cps.NONE,
            doc='''Select the image to be rescaled.''')

        self.rescaled_image_name = cps.ImageNameProvider(
            "Name the output image",
            "RescaledBlue",
            doc='''Enter the name of output rescaled image.''')

        self.rescale_method = cps.Choice('Rescaling method',
                                         choices=M_ALL,
                                         doc='''
            There are a number of options for rescaling the input image: 
            <ul>
            <li><i>%(M_STRETCH)s:</i> Find the minimum and maximum values within the unmasked part of the image 
            (or the whole image if there is no mask) and rescale every pixel so that 
            the minimum has an intensity of zero and the maximum has an intensity of one.</li>
            <li><i>%(M_MANUAL_INPUT_RANGE)s:</i> Pixels are
            scaled from their user-specified original range to the range 0 to 1.
            Options are available to handle values outside of the original range.<br>
            To convert 12-bit images saved in 16-bit format to the correct range,
            use the range 0 to 0.0625. The value 0.0625 is equivalent 
            to 2<sup>12</sup> divided by 2<sup>16</sup>, so it will convert a 16 bit image containing 
            only 12 bits of data to the proper range.</li>
            <li><i>%(M_MANUAL_IO_RANGE)s:</i> Pixels are scaled from their original range to
            the new target range. Options are available to handle values outside
            of the original range.</li>
            <li><i>%(M_DIVIDE_BY_IMAGE_MINIMUM)s:</i> Divide the intensity value of each pixel 
            by the image's minimum intensity value so that all pixel intensities are equal to or 
            greater than 1. The rescaled image can serve as an illumination correction function in 
            <b>CorrectIlluminationApply</b>.</li>
            <li><i>%(M_DIVIDE_BY_IMAGE_MAXIMUM)s:</i> Divide the intensity value of each pixel by the 
            image's maximum intensity value so that all pixel intensities are less than or equal to 1.</li>
            <li><i>%(M_DIVIDE_BY_VALUE)s:</i> Divide the intensity value of each pixel by the value entered.</li>
            <li><i>%(M_DIVIDE_BY_MEASUREMENT)s:</i> The intensity value of each pixel is divided by some 
            previously calculated measurement. This measurement can be the output of some other module
            or can be a value loaded by the <b>Metadata</b> module.</li>
            <li><i>%(M_SCALE_BY_IMAGE_MAXIMUM)s:</i> Scale an image so that its maximum value is the 
            same as the maximum value within the reference image.</li>
            <li><i>%(M_CONVERT_TO_8_BIT)s:</i> Images in CellProfiler are normally stored as a floating 
            point number in the range of 0 to 1. This option converts these images to class uint8, 
            meaning an 8 bit integer in the range of 0 to 255, 
            reducing the amount of memory required to store the image. <i>Warning:</i> Most
            CellProfiler modules require the incoming image to be in the standard 0
            to 1 range, so this conversion may cause downstream modules to behave 
            in unexpected ways.</li>
            </ul>''' % globals())

        self.wants_automatic_low = cps.Choice(
            'Method to calculate the minimum intensity',
            LOW_ALL,
            doc="""
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" is selected)</i><br>
            This setting controls how the minimum intensity is determined.
            <ul>
            <li><i>%(CUSTOM_VALUE)s:</i> Enter the minimum intensity manually below.</li>
            <li><i>%(LOW_EACH_IMAGE)s</i>: use the lowest intensity in this image
            as the minimum intensity for rescaling</li>
            <li><i>%(LOW_ALL_IMAGES)s</i>: use the lowest intensity from all images
            in the image group or the experiment if grouping is not being used.
            <b>Note:</b> Choosing this option may have undesirable results for
            a large ungrouped experiment split into a number of batches. Each batch
            will open all images from the chosen channel at the start of the run.
            This sort of synchronized action may have a severe impact on your
            network file system.</li>
            </ul>
            """ % globals())

        self.wants_automatic_high = cps.Choice(
            'Method to calculate the maximum intensity',
            HIGH_ALL,
            doc="""
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" is selected)</i><br>
            This setting controls how the maximum intensity is determined.
            <ul>
            <li><i>%(CUSTOM_VALUE)s</i>: Enter the maximum intensity manually below.</li>
            <li><i>%(HIGH_EACH_IMAGE)s</i>: Use the highest intensity in this image
            as the maximum intensity for rescaling</li>
            <li><i>%(HIGH_ALL_IMAGES)s</i>: Use the highest intensity from all images
            in the image group or the experiment if grouping is not being used.
            <b>Note:</b> Choosing this option may have undesirable results for
            a large ungrouped experiment split into a number of batches. Each batch
            will open all images from the chosen channel at the start of the run.
            This sort of synchronized action may have a severe impact on your
            network file system.</li>
            </ul>
            """ % globals())

        self.source_low = cps.Float(
            'Lower intensity limit for the input image', 0)

        self.source_high = cps.Float(
            'Upper intensity limit for the input image', 1)

        self.source_scale = cps.FloatRange(
            'Intensity range for the input image', (0, 1))

        self.dest_scale = cps.FloatRange(
            'Intensity range for the output image', (0, 1))

        self.low_truncation_choice = cps.Choice(
            'Method to rescale pixels below the lower limit',
            [R_MASK, R_SET_TO_ZERO, R_SET_TO_CUSTOM, R_SCALE],
            doc='''
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" is selected)</i><br>
            There are several ways to handle values less than the lower limit of the intensity range:
            <ul>
            <li><i>%(R_MASK)s:</i> Creates a mask for the output image. All pixels below
            the lower limit will be masked out.</li>
            <li><i>%(R_SET_TO_ZERO)s:</i> Sets all pixels below the lower limit to zero.</li>
            <li><i>%(R_SET_TO_CUSTOM)s:</i> Sets all pixels below the lower limit to a custom
            value.</li>
            <li><i>%(R_SCALE)s:</i> Scales pixels with values below the lower limit
            using the same offset and divisor as other pixels. The results
            will be less than zero.</li>
            </ul>''' % globals())

        self.custom_low_truncation = cps.Float(
            "Custom value for pixels below lower limit",
            0,
            doc="""
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" and "%(R_SET_TO_CUSTOM)s are selected)</i><br>
            enter the custom value to be assigned to pixels with values below the lower limit."""
            % globals())

        self.high_truncation_choice = cps.Choice(
            'Method to rescale pixels above the upper limit',
            [R_MASK, R_SET_TO_ONE, R_SET_TO_CUSTOM, R_SCALE],
            doc="""
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" is selected)</i><br>
            There are several ways to handle values greater than the upper limit of the intensity range; 
            Options are described in the Help for the equivalent lower limit question."""
            % globals())

        self.custom_high_truncation = cps.Float(
            "Custom value for pixels above upper limit",
            0,
            doc="""
            <i>(Used only if "%(M_MANUAL_IO_RANGE)s" and "%(R_SET_TO_CUSTOM)s are selected)</i><br>
            Enter the custom value to be assigned to pixels with values above the upper limit."""
            % globals())

        self.matching_image_name = cps.ImageNameSubscriber(
            "Select image to match in maximum intensity",
            cps.NONE,
            doc="""
            <i>(Used only if "%(M_SCALE_BY_IMAGE_MAXIMUM)s" is selected)</i><br>
            Select the image whose maximum you want the rescaled image to match."""
            % globals())

        self.divisor_value = cps.Float("Divisor value",
                                       1,
                                       minval=np.finfo(float).eps,
                                       doc="""
            <i>(Used only if "%(M_DIVIDE_BY_VALUE)s" is selected)</i><br>
            Enter the value to use as the divisor for the final image.""" %
                                       globals())

        self.divisor_measurement = cps.Measurement("Divisor measurement",
                                                   lambda: cpmeas.IMAGE,
                                                   doc="""
            <i>(Used only if "%(M_DIVIDE_BY_MEASUREMENT)s" is selected)</i><br>
            Select the measurement value to use as the divisor for the final image."""
                                                   % globals())
Example #9
0
    def create_settings(self):
        self.x_source = cps.Choice("Type of measurement to plot on X-axis",
                                   SOURCE_CHOICE,
                                   doc='''
            You can plot two types of measurements:
            <ul>
            <li><i>%(SOURCE_IM)s:</i> For a per-image measurement, one numerical value is 
            recorded for each image analyzed.
            Per-image measurements are produced by
            many modules. Many have <b>MeasureImage</b> in the name but others do not
            (e.g., the number of objects in each image is a per-image 
            measurement made by the <b>IdentifyObject</b> 
            modules).</li>
            <li><i>%(SOURCE_OBJ)s:</i> For a per-object measurement, each identified 
            object is measured, so there may be none or many 
            numerical values recorded for each image analyzed. These are usually produced by
            modules with <b>MeasureObject</b> in the name.</li>
            </ul>''' % globals())

        self.x_object = cps.ObjectNameSubscriber(
            'Select the object to plot on the X-axis',
            cps.NONE,
            doc='''<i>(Used only when plotting objects)</i><br>
            Choose the name of objects identified by some previous 
            module (such as <b>IdentifyPrimaryObjects</b> or 
            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed on the X-axis.'''
        )

        self.x_axis = cps.Measurement(
            'Select the measurement to plot on the X-axis',
            self.get_x_object,
            cps.NONE,
            doc='''
            Choose the measurement (made by a previous 
            module) to plot on the X-axis.''')

        self.y_source = cps.Choice("Type of measurement to plot on Y-axis",
                                   SOURCE_CHOICE,
                                   doc='''
            You can plot two types of measurements:
            <ul>
            <li><i>%(SOURCE_IM)s:</i> For a per-image measurement, one numerical value is 
            recorded for each image analyzed.
            Per-image measurements are produced by
            many modules. Many have <b>MeasureImage</b> in the name but others do not
            (e.g., the number of objects in each image is a per-image 
            measurement made by <b>IdentifyObject</b> 
            modules).</li>
            <li><i>%(SOURCE_OBJ)s:</i> For a per-object measurement, each identified 
            object is measured, so there may be none or many 
            numerical values recorded for each image analyzed. These are usually produced by
            modules with <b>MeasureObject</b> in the name.</li>
            </ul>''' % globals())

        self.y_object = cps.ObjectNameSubscriber(
            'Select the object to plot on the Y-axis',
            cps.NONE,
            doc='''<i>(Used only when plotting objects)</i><br>
            Choose the name of objects identified by some previous 
            module (such as <b>IdentifyPrimaryObjects</b> or 
            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed on the Y-axis.'''
        )

        self.y_axis = cps.Measurement(
            'Select the measurement to plot on the Y-axis',
            self.get_y_object,
            cps.NONE,
            doc='''
            Choose the measurement (made by a previous 
            module) to plot on the Y-axis.''')

        self.xscale = cps.Choice('How should the X-axis be scaled?',
                                 SCALE_CHOICE,
                                 None,
                                 doc='''
            The X-axis can be scaled with either a <i>linear</i> 
            scale or a <i>log</i> (base 10) scaling. 
            <p>Log scaling is useful when one of the 
            measurements being plotted covers a large range of 
            values; a log scale can bring out features in the 
            measurements that would not easily be seen if the 
            measurement is plotted linearly.</p>''')

        self.yscale = cps.Choice('How should the Y-axis be scaled?',
                                 SCALE_CHOICE,
                                 None,
                                 doc='''
            The Y-axis can be scaled with either a <i>linear</i> 
            scale or with a <i>log</i> (base 10) scaling. 
            <p>Log scaling is useful when one of the 
            measurements being plotted covers a large range of 
            values; a log scale can bring out features in the 
            measurements that would not easily be seen if the 
            measurement is plotted linearly.</p>''')

        self.title = cps.Text('Enter a title for the plot, if desired',
                              '',
                              doc='''
            Enter a title for the plot. If you leave this blank,
            the title will default 
            to <i>(cycle N)</i> where <i>N</i> is the current image 
            cycle being executed.''')
Example #10
0
    def add_measurement(self, flag_settings, can_delete=True):
        measurement_settings = flag_settings.measurement_settings

        group = cps.SettingsGroup()
        group.append("divider1", cps.Divider(line=False))
        group.append(
            "source_choice",
            cps.Choice("Flag is based on",
                       S_ALL,
                       doc='''
                        <ul>
                        <li><i>%(S_IMAGE)s:</i> A per-image measurement, such as intensity or 
                        granularity.</li>
                        <li><i>%(S_AVERAGE_OBJECT)s:</i> The average of all 
                        object measurements in the image.</li>
                        <li><i>%(S_ALL_OBJECTS)s:</i> All the 
                        object measurements in an image, without averaging. In other words, if <i>any</i> 
                        of the objects meet the criteria, the image will be flagged.</li>
                        <li><i>%(S_RULES)s:</i>Use a text file of rules produced by CellProfiler Analyst. If you 
                        choose <i>Rules</i>, you will have to ensure that this pipeline makes every measurement 
                        in the rules file prior to this module.</li>
                        </ul>''' % globals()))

        group.append(
            "object_name",
            cps.ObjectNameSubscriber(
                "Select the object to be used for flagging",
                cps.NONE,
                doc='''
                        <i>(Used only when flag is based on an object measurement)</i><br>
                        Select the objects whose measurements you want to use for flagging.'''
            ))

        def object_fn():
            if group.source_choice == S_IMAGE:
                return cpmeas.IMAGE
            return group.object_name.value

        group.append(
            "rules_directory",
            cps.DirectoryPath("Rules file location",
                              doc="""
                        <i>(Used only when flagging using %(S_RULES)s)</i><br>
                        Select the location of the rules file that will be used for filtering.
                        %(IO_FOLDER_CHOICE_HELP_TEXT)s""" % globals()))

        def get_directory_fn():
            '''Get the directory for the rules file name'''
            return group.rules_directory.get_absolute_path()

        def set_directory_fn(path):
            dir_choice, custom_path = group.rules_directory.get_parts_from_path(
                path)
            group.rules_directory.join_parts(dir_choice, custom_path)

        group.append(
            "rules_file_name",
            cps.FilenameText("Rules file name",
                             "rules.txt",
                             get_directory_fn=get_directory_fn,
                             set_directory_fn=set_directory_fn,
                             doc="""
                        <i>(Used only when flagging using %(S_RULES)s)</i><br>
                        The name of the rules file. This file should be a plain text
                        file containing the complete set of rules.
                        <p>Each line of
                        this file should be a rule naming a measurement to be made
                        on an image, for instance:
                        <pre>IF (Image_ImageQuality_PowerLogLogSlope_DNA &lt; -2.5, [0.79, -0.79], [-0.94, 0.94])</pre><br><br>
                        The above rule will score +0.79 for the positive category and -0.94
                        for the negative category for images whose power log slope is less than -2.5
                        pixels and will score the opposite for images whose slope is larger.
                        The filter adds positive and negative and flags the images whose
                        positive score is higher than the negative score.</p>"""
                             % globals()))

        def get_rules_class_choices(group=group):
            '''Get the available choices from the rules file'''
            try:
                rules = self.get_rules(group)
                nclasses = len(rules.rules[0].weights[0])
                return [str(i) for i in range(1, nclasses + 1)]
            except:
                return [str(i) for i in range(1, 3)]

        group.append(
            "rules_class",
            cps.MultiChoice("Class number",
                            choices=["1", "2"],
                            doc="""
                        <i>(Used only when flagging using %(S_RULES)s)</i><br>
                        Select which classes to flag when filtering. The
                        CellProfiler Analyst classifier user interface lists the names of 
                        the classes in order. By default, these are the positive (class 1)
                        and negative (class 2) classes. <b>FlagImage</b> uses the
                        first class from CellProfiler Analyst if you choose "1", etc. 
                        <p>Please note the following:
                        <ul>
                        <li>The flag is set if the image falls into the selected class.</li>
                        <li>You can make multiple class selections. If you do so, the module
                        will set the flag if the image falls into any of the selected classes.</li>
                        </ul></p>""" % globals()))

        group.rules_class.get_choices = get_rules_class_choices

        group.append("measurement",
                     cps.Measurement("Which measurement?", object_fn))

        group.append(
            "wants_minimum",
            cps.Binary("Flag images based on low values?",
                       True,
                       doc='''
                         Select <i>%(YES)s</i> to flag images with measurements below the specified cutoff.'''
                       % globals()))

        group.append("minimum_value", cps.Float("Minimum value", 0))

        group.append(
            "wants_maximum",
            cps.Binary("Flag images based on high values?",
                       True,
                       doc='''
                         Select <i>%(YES)s</i> to flag images with measurements above the specified cutoff.'''
                       % globals()))

        group.append("maximum_value", cps.Float("Maximum value", 1))

        if can_delete:
            group.append(
                "remover",
                cps.RemoveSettingButton("", "Remove this measurement",
                                        measurement_settings, group))

        group.append("divider2", cps.Divider(line=True))
        measurement_settings.append(group)
    def create_settings(self):
        self.delimiter = cps.CustomChoice(
            'Select or enter the column delimiter',
            DELIMITERS,
            doc="""
                            What delimiter do you want to use? This is the character that separates columns in a file. The
                            two default choices are tab and comma, but you can type in any single character delimiter you would prefer. Be sure that the delimiter you choose is not a character that is present within your data (for example, in file names)."""
        )

        self.prepend_output_filename = cps.Binary(
            "Prepend the output file name to the data file names?",
            True,
            doc="""
                            This can be useful if you want to run a pipeline multiple 
                            times without overwriting the old results.""")

        self.directory = cps.DirectoryPath(
            "Output file location",
            dir_choices=[
                DEFAULT_OUTPUT_FOLDER_NAME, DEFAULT_INPUT_FOLDER_NAME,
                ABSOLUTE_FOLDER_NAME, DEFAULT_INPUT_SUBFOLDER_NAME,
                DEFAULT_OUTPUT_SUBFOLDER_NAME
            ],
            doc="""This setting lets you choose the folder for the output
            files. %(IO_FOLDER_CHOICE_HELP_TEXT)s
            
            <p>%(IO_WITH_METADATA_HELP_TEXT)s %(USING_METADATA_TAGS_REF)s<br>
            For instance, if you have a metadata tag named 
            "Plate", you can create a per-plate folder by selecting one of the subfolder options
            and then specifying the subfolder name as "\g&lt;Plate&gt;". The module will 
            substitute the metadata values for the current image set for any metadata tags in the 
            folder name. %(USING_METADATA_HELP_REF)s.</p>""" % globals())

        self.add_metadata = cps.Binary(
            "Add image metadata columns to your object data file?",
            False,
            doc=
            """"Image_Metadata_" columns are normally exported in the Image data file, but if you check this box they will also be exported with the Object data file(s)."""
        )

        self.excel_limits = cps.Binary(
            "Limit output to a size that is allowed in Excel?",
            False,
            doc="""
                            If your output has more than 256 columns, a window will open
                            which allows you to select the columns you'd like to export. If your output exceeds
                            65,000 rows, you can still open the .csv in Excel, but not all rows will be visible."""
        )

        self.pick_columns = cps.Binary(
            "Select the columns of measurements to export?",
            False,
            doc="""
                            Checking this setting will open up a window that allows you to select the columns to export."""
        )

        self.columns = cps.MeasurementMultiChoice(
            "Press button to select measurements to export",
            doc=
            """<i>(Used only when selecting the columns of measurements to export)</i><br>This setting controls the columns to be exported. Press
            the button and check the measurements or categories to export""")

        self.wants_aggregate_means = cps.Binary(
            "Calculate the per-image mean values for object measurements?",
            False,
            doc="""
                            <b>ExportToSpreadsheet</b> can calculate population statistics over all the 
                            objects in each image and save that value as an aggregate 
                            measurement in the Image file.  For instance, if you are measuring 
                            the area of the Nuclei objects and you check the box for this option, <b>ExportToSpreadsheet</b> will 
                            create a column in the Image file called "Mean_Nuclei_AreaShape_Area". 
                            <p>You may not want to use <b>ExportToSpreadsheet</b> to calculate these 
                            measurements if your pipeline generates a large number of per-object 
                            measurements; doing so might exceed Excel's limits on the number of columns (256). """
        )

        self.wants_aggregate_medians = cps.Binary(
            "Calculate the per-image median values for object measurements?",
            False)

        self.wants_aggregate_std = cps.Binary(
            "Calculate the per-image standard deviation values for object measurements?",
            False)

        self.wants_genepattern_file = cps.Binary(
            "Create a GenePattern GCT file?",
            False,
            doc="""
            Create a GCT file compatible with <a href="http://www.broadinstitute.org/cancer/software/genepattern/">GenePattern</a>.
            The GCT file format is a tab-delimited text file format that describes a gene expression dataset; the specifics of the
            format are described <a href="http://www.broadinstitute.org/cancer/software/genepattern/tutorial/gp_fileformats.html#gct">here</a>.
            By converting your measurements into a GCT file, you can make use of GenePattern's data visualization and clustering methods.
            
            <p>Each row in the GCT file represents (ordinarily) a gene and each column represents a sample (in this case, a per-image set
            of measurements). In addition to any other spreadsheets desired, checking this box will produce a GCT file with the 
            extension .gct, prepended with the text selection above. If per-image aggregate measurements are requested above, those 
            measurements are included in the GCT file as well.</p>""")

        self.how_to_specify_gene_name = cps.Choice(
            "Select source of sample row name",
            GP_NAME_OPTIONS,
            GP_NAME_METADATA,
            doc="""
            <i>(Used only if a GenePattern file is requested)</i><br>
            The first column of the GCT file is the unique identifier for each sample, which is ordinarily the gene name. 
            This information may be specified in one of two ways:
            <ul>
            <li><i>Metadata:</i> If you used <b>LoadData</b> or <b>LoadImages</b> to input your images, you may use a per-image data measurement 
            (such as metadata) that corresponds to the identifier for this column. %(USING_METADATA_HELP_REF)s.</li>
            <li><i>Image filename:</i> If the gene name is not available, the image filename can be used as a surrogate identifier.</li>
            </ul>""" % globals())

        self.gene_name_column = cps.Measurement(
            "Select the metadata to use as the identifier",
            lambda: cpmeas.IMAGE,
            doc="""
            <i>(Used only if a GenePattern file is requested and metadata is used to name each row)</i><br>
            Choose the measurement that corresponds to the identifier, such as metadata from <b>LoadData</b>'s input file. 
            %(USING_METADATA_HELP_REF)s.""" % globals())

        self.use_which_image_for_gene_name = cps.ImageNameSubscriber(
            "Select the image to use as the identifier",
            "None",
            doc="""
            <i>(Used only if a GenePattern file is requested and image filename is used to name each row)</i><br>
            Select which image whose filename will be used to identify each sample row."""
        )

        self.wants_everything = cps.Binary(
            "Export all measurements, using default file names?",
            True,
            doc="""Check this setting to export every measurement.
            <b>ExportToSpreadsheet</b> will create one file per object type,
            as well as per-image, per-experiment and object relationships, 
            if relevant. 
            It will use the object name as the file name, 
            optionally prepending the output file name if
            specified above. Leave this box unchecked to specify which
            objects should be exported or to override the automatic names.""")

        self.object_groups = []
        self.add_object_group()
        self.add_button = cps.DoSomething("", "Add another data set",
                                          self.add_object_group)
 def create_settings(self):
     """Create your settings by subclassing this function
     
     create_settings is called at the end of initialization.
     
     You should create the setting variables for your module here:
         # Ask the user for the input image
         self.image_name = cellprofiler.settings.ImageNameSubscriber(...)
         # Ask the user for the name of the output image
         self.output_image = cellprofiler.settings.ImageNameProvider(...)
         # Ask the user for a parameter
         self.smoothing_size = cellprofiler.settings.Float(...)
     """
     self.objects_or_image = cps.Choice(
         "Display object or image measurements?",
         [OI_OBJECTS, OI_IMAGE],doc = """
         <ul>
         <li><i>%(OI_OBJECTS)s</i> displays measurements made on
         objects.</li>
         <li><i>%(OI_IMAGE)s</i> displays a single measurement made
         on an image.</li> 
         </ul>"""%globals())
     
     self.objects_name = cps.ObjectNameSubscriber(
         "Select the input objects", cps.NONE, doc = """
         <i>(Used only when displaying object measurements)</i><br>
         Choose the name of objects identified by some previous
         module (such as <b>IdentifyPrimaryObjects</b> or
         <b>IdentifySecondaryObjects</b>).""")
     
     def object_fn():
         if self.objects_or_image == OI_OBJECTS:
             return self.objects_name.value
         else:
             return cpmeas.IMAGE
     self.measurement = cps.Measurement(
         "Measurement to display", object_fn,doc="""
         Choose the measurement to display. This will be a measurement
         made by some previous module on either the whole image (if
         displaying a single image measurement) or on the objects you
         selected.""")
     
     self.wants_image = cps.Binary(
         "Display background image?", True,
         doc="""Choose whether or not to display the measurements on
         a background image. Usually, you will want to see the image
         context for the measurements, but it may be useful to save
         just the overlay of the text measurements and composite the
         overlay image and the original image later. Choose "Yes" to
         display the measurements on top of a background image or "No"
         to display the measurements on a black background.""")
     self.image_name = cps.ImageNameSubscriber(
         "Select the image on which to display the measurements", cps.NONE, doc="""
         Choose the image to be displayed behind the measurements.
         This can be any image created or loaded by a previous module.
         If you have chosen not to display the background image, the image
         will only be used to determine the dimensions of the displayed image""")
     
     self.color_or_text = cps.Choice(
         "Display mode", [CT_TEXT, CT_COLOR],
         doc = """<i>(Used only when displaying object measurements)</i><br>
         Choose how to display the measurement information. If you choose
         %(CT_TEXT)s, <b>DisplayDataOnImage</b> will display the numeric
         value on top of each object. If you choose %(CT_COLOR)s,
         <b>DisplayDataOnImage</b> will convert the image to grayscale, if
         necessary, and display the portion of the image within each object
         using a hue that indicates the measurement value relative to
         the other objects in the set using the default color map.
         """ % globals()
         )
     
     self.colormap = cps.Colormap(
         "Color map",
         doc = """<i>(Used only when displaying object measurements)</i><br>
         This is the color map used as the color gradient for coloring the
         objects by their measurement values.
         """)        
     self.text_color = cps.Color(
         "Text color","red",doc="""
         This is the color that will be used when displaying the text.
         """)
     
     self.display_image = cps.ImageNameProvider(
         "Name the output image that has the measurements displayed","DisplayImage",doc="""
         The name that will be given to the image with
         the measurements superimposed. You can use this name to refer to the image in
         subsequent modules (such as <b>SaveImages</b>).""")
     
     self.font_size = cps.Integer(
         "Font size (points)", 10, minval=1)
     
     self.decimals = cps.Integer(
         "Number of decimals", 2, minval=0)
     
     self.saved_image_contents = cps.Choice(
         "Image elements to save",
         [E_IMAGE, E_FIGURE, E_AXES],doc="""
         This setting controls the level of annotation on the image:
         <ul>
         <li><i>%(E_IMAGE)s:</i> Saves the image with the overlaid measurement annotations.</li>
         <li><i>%(E_AXES)s:</i> Adds axes with tick marks and image coordinates.</li>
         <li><i>%(E_FIGURE)s:</i> Adds a title and other decorations.</li></ul>"""%globals())
     
     self.offset = cps.Integer(
         "Annotation offset (in pixels)",0,doc="""
         Add a pixel offset to the measurement. Normally, the text is
         placed at the object (or image) center, which can obscure relevant features of
         the object. This setting adds a specified offset to the text, in a random
         direction.""")
     
     self.color_map_scale_choice = cps.Choice(
         "Color map scale",
         [CMS_USE_MEASUREMENT_RANGE, CMS_MANUAL],
         doc = """<i>(Used only when displaying object measurements as a 
         colormap)</i><br>
         <b>DisplayDataOnImage</b> assigns a color to each object's
         measurement value from a colormap when in colormap-mode, mapping
         the value to a color along the colormap's continuum. This mapping
         has implicit upper and lower bounds to its range which are the
         extremes of the colormap. This setting determines whether the
         extremes are the minimum and maximum values of the measurement
         from among the objects in the current image or manually-entered
         extremes. Choose <i>%(CMS_USE_MEASUREMENT_RANGE)s</i> to use
         the full range of colors to get the maximum contrast within the
         image. Choose <i>%(CMS_MANUAL)s</i> to manually set the upper and
         lower bounds so that images with different maxima and minima
         can be compared by a uniform color mapping.
         """ % globals())
     self.color_map_scale = cps.FloatRange(
         "Color map range", 
         value = (0.0, 1.0),
         doc = """<i>(Used only when setting a manual colormap range)</i><br>
         This setting determines the lower and upper bounds of the values
         for the color map.
         """)
Example #13
0
    def create_threshold_settings(self, methods=TM_METHODS):
        '''Create settings related to thresholding'''
        self.threshold_method = cps.Choice('Select the thresholding method',
                                           methods,
                                           doc="""
            The intensity threshold affects the decision of whether each pixel
            will be considered foreground (regions of interest) or background.
            A stringent threshold will result in only 
            bright regions being identified, with tight lines around them, whereas 
            a lenient threshold will include dim regions and the lines between regions 
            and background will be more loose. You can have the threshold automatically calculated 
            using several methods, or you can enter an absolute number between 0 
            and 1 for the threshold. To help determine the choice of threshold manually, you
            can inspect the pixel intensities in an image of your choice. 
            %(HELP_ON_PIXEL_INTENSITIES)s""" % globals() +
                                           """ Both options have advantages. 
            An absolute number treats every image identically, but is not robust 
            with regard to slight changes in lighting/staining conditions between images. An
            automatically calculated threshold adapts to changes in
            lighting/staining conditions between images and is usually more
            robust/accurate, but it can occasionally produce a poor threshold for
            unusual/artifactual images. It also takes a small amount of time to
            calculate.
            
            <p>The threshold that is used for each image is recorded as a
            measurement in the output file, 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.
            
            <p>There are seven methods for finding thresholds automatically:
            <ul><li><i>Otsu:</i> This method is probably best if you are not able 
            to make certain assumptions about every images in your experiment, 
            especially if the percentage of the image covered by regions 
            of interest varies substantially from image to image. Our implementation 
            takes into account the maximum and minimum values in the image and log-transforming the
            image prior to calculating the threshold. For this reason, please note
            that negative-valued pixels are ignored in this computation, so caution should be
            used in using image offsets (such as by using <b>ImageMath</b>).
            <p>If you know that the percentage of 
            each image that is foreground does not vary much from image
            to image, the MoG method can be better, especially if the foreground percentage is
            not near 50%.</li>
            <li><i>Mixture of Gaussian (MoG):</i>This function assumes that the 
            pixels in the image belong to either a background class or a foreground
            class, using an initial guess of the fraction of the image that is 
            covered by foreground. This method is our own version of a Mixture of Gaussians
            algorithm (<i>O. Friman, unpublished</i>). Essentially, there are two steps:
            <ol><li>First, a number of Gaussian distributions are estimated to 
            match the distribution of pixel intensities in the image. Currently 
            three Gaussian distributions are fitted, one corresponding to a 
            background class, one corresponding to a foreground class, and one 
            distribution for an intermediate class. The distributions are fitted
            using the Expectation-Maximization algorithm, a procedure referred 
            to as Mixture of Gaussians modeling. </li>
            <li>When the three Gaussian distributions have been fitted, a decision 
            is made whether the intermediate class more closely models the background pixels 
            or foreground pixels, based on the estimated fraction provided by the user.</li></ol></li>
            <li><i>Background:</i> This method is simple and appropriate for images in 
            which most of the image is background. It finds the mode of the 
            histogram of the image, which is assumed to be the background of the 
            image, and chooses a threshold at twice that value (which you can 
            adjust with a Threshold Correction Factor; see below).  The calculation 
	    includes those pixels between 2% and 98% of the intensity range. This thresholding method 
	    can be helpful if your images vary in overall brightness, but the objects of 
            interest are consistently N times brighter than the background level of the image. </li>
            <li><i>Robust background:</i> Much like the Background method, this method is 
	    also simple and assumes that the background distribution
	    approximates a Gaussian by trimming the brightest and dimmest 5% of pixel 
	    intensities. It then calculates the mean and standard deviation of the 
            remaining pixels and calculates the threshold as the mean + 2 times 
            the standard deviation. This thresholding method can be helpful if the majority
	    of the image is background, and the results are often comparable or better than the
	    Background method.</li>
            <li><i>Ridler-Calvard:</i> This method is simple and its results are
            often very similar to Otsu's. According to
            Sezgin and Sankur's paper (<i>Journal of Electronic Imaging</i>, 2004), Otsu's 
            overall quality on testing 40 nondestructive testing images is slightly 
            better than Ridler's (average error: Otsu, 0.318; Ridler, 0.401). 
            Ridler-Calvard chooses an initial threshold and then iteratively calculates the next 
            one by taking the mean of the average intensities of the background and 
            foreground pixels determined by the first threshold, repeating this until 
            the threshold converges.</li>
            <li><i>Kapur:</i> This method computes the threshold of an image by
            log-transforming its values, then searching for the threshold that
            maximizes the sum of entropies of the foreground and background
            pixel values, when treated as separate distributions.</li>
            <li><i>Maximum correlation:</i>This is an implementation of the
            method described in Padmanabhan et al, 2010. It computes the maximum
            correlation between the binary mask created by thresholding and
            the thresholded image and is somewhat similar mathematically to
            Otsu. The authors claim superior results when thresholding images
            of neurites and other images that have sparse foreground densities.</li>
            </ul>
            
            <p>You can also choose between <i>Global</i>, <i>Adaptive</i>, and 
            <i>Per-object</i> thresholding for the automatic methods:
            <ul>
            <li><i>Global:</i> One threshold is calculated for the entire image (fast)</li>
            <li><i>Adaptive:</i> The calculated threshold varies across the image. This method 
            is a bit slower but may be more accurate near edges of regions of interest, 
            or where illumination variation is significant (though in the latter case, 
            using the <b>CorrectIllumination</b> modules is preferable).</li>
            <li><i>Per-object:</i> If you are using this module to find child objects located
            <i>within</i> parent objects, the per-object method will calculate a distinct
            threshold for each parent object. This is especially helpful, for
            example, when the background brightness varies substantially among the
            parent objects. 
            <br><i>Important:</i> the per-object method requires that you run an
            <b>IdentifyPrimaryObjects</b> module to identify the parent objects upstream in the
            pipeline. After the parent objects are identified in the pipeline, you
            must then also run a <b>Crop</b> module with the following inputs: 
            <ul>
            <li>The input image is the image containing the sub-objects to be identified.</li>
            <li>Select <i>Objects</i> as the shape to crop into.</li>
            <li>Select the parent objects (e.g., <i>Nuclei</i>) as the objects to use as a cropping mask.</li>
            </ul>
            Finally, in the <b>IdentifyPrimaryObjects</b> module, select the cropped image as input image.</li></ul>
            
            <p>Selecting <i>manual thresholding</i> allows you to enter a single value between 0 and 1
            as the threshold value. This setting can be useful when you are certain what the
            cutoff should be and it does not vary from image to image in the experiment. If you are 
            using this module to find objects in an image that is already binary (where the foreground is 1 and 
            the background is 0), a manual value of 0.5 will identify the objects.
            
            <p>Selecting thresholding via a <i>binary image</i> will use a selected binary image as a mask for the
            input image. The most typical approach to produce a binary image is to use the <b>ApplyThreshold</b> module 
            (image as input, image as output) or the <b>ConvertObjectsToImage</b> module (objects as input, image 
            as output); both have options to produce a binary image. Note that unlike <b>MaskImage</b>, the binary 
            image will not be stored permanently as a mask. Also, even though no algorithm is actually used to 
            find the threshold in this case, the final threshold value is reported as the Otsu threshold 
            calculated for the foreground region.
            
            <p>Selecting thresholding via <i>measurement</i> will use an image measurement previously calculated
            in order to threshold the image. Like manual thresholding, this setting can be useful when you are 
            certain what the cutoff should be. The difference in this case is that the desired threshold does 
            vary from image to image in the experiment but can be measured using a Measurement module.</p>
            
            <p>References
            <ul>
            <li>Sezgin M, Sankur B (2004) "Survey over image thresholding techniques and quantitative 
            performance evaluation." <i>Journal of Electronic Imaging</i>, 13(1), 146-165</li>
            <li>Padmanabhan K, Eddy WF, Crowley JC (2010) "A novel algorithm for
            optimal image thresholding of biological data" <i>Journal of 
            Neuroscience Methods</i> 193, 380-384.</li>
            </ul></p>
            """)

        self.threshold_correction_factor = cps.Float(
            'Threshold correction factor',
            1,
            doc="""\
            When the threshold is calculated automatically, it may consistently be
            too stringent or too lenient. You may need to enter an adjustment factor
            that you empirically determine is suitable for your images. The number 1
            means no adjustment, 0 to 1 makes the threshold more lenient and greater
            than 1 (e.g., 1.3) makes the threshold more stringent. For example, the
            Otsu automatic thresholding inherently assumes that 50% of the image is
            covered by objects. If a larger percentage of the image is covered, the
            Otsu method will give a slightly biased threshold that may have to be
            corrected using this setting.""")

        self.threshold_range = cps.FloatRange(
            'Lower and upper bounds on threshold', (0, 1),
            minval=0,
            maxval=1,
            doc="""\
            Enter the minimum and maximum allowable threshold, in the range [0,1].  
            This is helpful as a safety precaution when the threshold is calculated
            automatically. For example, if there are no objects in the field of view,
            the automatic threshold might be calculated as unreasonably low. In such cases, the
            lower bound you enter here will override the automatic threshold."""
        )

        self.object_fraction = cps.CustomChoice(
            'Approximate fraction of image covered by objects?', [
                '0.01', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8',
                '0.9', '0.99'
            ],
            doc="""\
            <i>(Used only when applying the MoG thresholding method)</i><br>
            Enter an estimate of how much of the image is covered with objects, which
            is used to estimate the distribution of pixel intensities.""")

        self.manual_threshold = cps.Float("Manual threshold",
                                          value=0.0,
                                          minval=0.0,
                                          maxval=1.0,
                                          doc="""\
            <i>(Used only if Manual selected for thresholding method)</i><br>
            Enter the value that will act as an absolute threshold for the images, in the range of [0,1]."""
                                          )

        self.thresholding_measurement = cps.Measurement(
            "Select the measurement to threshold with",
            lambda: cpmeas.IMAGE,
            doc="""
            <i>(Used only if Measurement is selected for thresholding method)</i><br>
            Choose the image measurement that will act as an absolute threshold for the images."""
        )

        self.binary_image = cps.ImageNameSubscriber("Select binary image",
                                                    "None",
                                                    doc="""
            <i>(Used only if Binary image selected for thresholding method)</i><br>
            What is the binary thresholding image?""")

        self.two_class_otsu = cps.Choice(
            'Two-class or three-class thresholding?',
            [O_TWO_CLASS, O_THREE_CLASS],
            doc="""
            <i>(Used only for the Otsu thresholding method)</i> <br>
            Select <i>Two</i> if the grayscale levels are readily distinguishable 
            into only two classes: foreground 
            (i.e., objects) and background. Select <i>Three</i> if the grayscale 
            levels fall instead into three classes. 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.  Note that whether 
            two- or three-class thresholding is chosen, the image pixels are always 
            finally assigned two classes: foreground and background.
            <p>For example, three-class thresholding may
            be useful for images in which you have nuclear staining along with 
            low-intensity non-specific cell staining. Where two-class thresholding
            might incorrectly assign this intermediate staining to the nuclei 
            objects for some cells, three-class thresholding allows you to assign it to the 
            foreground or background as desired. However, in extreme cases where either 
            there are almost no objects or the entire field of view is covered with 
            objects, three-class thresholding may perform worse than two-class."""
        )

        self.use_weighted_variance = cps.Choice(
            'Minimize the weighted variance or the entropy?',
            [O_WEIGHTED_VARIANCE, O_ENTROPY])

        self.assign_middle_to_foreground = cps.Choice(
            'Assign pixels in the middle intensity class to the foreground '
            'or the background?', [O_FOREGROUND, O_BACKGROUND],
            doc="""
            <i>(Used only for three-class thresholding)</i><br>
            Choose whether you want the pixels with middle grayscale intensities to be assigned 
            to the foreground class or the background class.""")

        self.adaptive_window_method = cps.Choice(
            "Method to calculate adaptive window size",
            [FI_IMAGE_SIZE, FI_CUSTOM],
            doc="""
            <i>(Used only if an adaptive thresholding method is used)</i><br>
            The adaptive method breaks the image into blocks, computing the threshold 
            for each block. There are two ways to compute the block size:
            <ul>
            <li><i>%(FI_IMAGE_SIZE)s:</i> The block size is one-tenth of the image dimensions,
            or 50 x 50 pixels, whichever is bigger.</li>
            <li><i>%(FI_CUSTOM)s:</i> The block size is specified by the user.</li>
            </ul>""" % globals())

        self.adaptive_window_size = cps.Integer('Size of adaptive window',
                                                10,
                                                doc="""
            <i>(Used only if an adaptive thresholding method with a %(FI_CUSTOM)s window size 
            are selected)</i><br>
            Enter the window for the adaptive method. For example,
            you may want to use a multiple of the largest expected object size."""
                                                % globals())
Example #14
0
    def add_measurement(self, flag_settings, can_delete=True):
        measurement_settings = flag_settings.measurement_settings

        group = cps.SettingsGroup()
        group.append("divider1", cps.Divider(line=False))
        group.append("source_choice",
                     cps.Choice(
                "Flag is based on", S_ALL, doc = '''
                <ul>
                <li><i> Whole-image measurement:</i> A per-image measurement, such as intensity or 
                granularity.</li>
                <li><i> Average measurement for all objects in each image:</i> The average of all 
                object measurements in the image.</li>
                <li><i> Measurements for all objects in each image:</i> All the 
                object measurements in an image, without averaging. In other words, if <i>any</i> 
                of the objects meet the criteria, the image will be flagged.</li>
                <li><i>Rules:</i>Use a text file of rules produced by CellProfiler Analyst. If you 
                choose <i>Rules</i>, you will have to ensure that this pipeline makes every measurement 
                in the rules file prior to this module.</li>
                </ul>'''))
        group.append("object_name",
                     cps.ObjectNameSubscriber(
                "Select the object whose measurements will be used to flag",
                "None", doc = '''<i>(Used only when flag is based on an object measurement)</i><br>What did you call the objects whose measurements you want to use for flagging?'''))

        def object_fn():
            if group.source_choice == S_IMAGE:
                return cpmeas.IMAGE
            return group.object_name.value

        group.append("rules_directory",
                     cps.DirectoryPath(
                    "Rules file location",
                    doc = """<i>(Used only when filtering by rules)</i>
                    <br>
                    Select the location of the rules file that will be used for filtering.
                    %(IO_FOLDER_CHOICE_HELP_TEXT)s""" % globals()))
         
        def get_directory_fn():
            '''Get the directory for the rules file name'''
            return group.rules_directory.get_absolute_path()
                
        def set_directory_fn(path):
            dir_choice, custom_path = group.rules_directory.get_parts_from_path(path)
            group.rules_directory.join_parts(dir_choice, custom_path)
        
        group.append("rules_file_name", cps.FilenameText(
                    "Rules file name","rules.txt",
                    get_directory_fn = get_directory_fn,
                    set_directory_fn = set_directory_fn,
                    doc="""<i>(Used only when filtering using rules)</i>
                    <br>The name of the file holding the rules. Each line of
                    this file should be a rule naming a measurement to be made
                    on an image, for instance:<pre>IF (Image_ImageQuality_PowerLogLogSlope_DNA &lt; -2.5, [0.79, -0.79], [-0.94, 0.94])</pre><br><br>
                    The above rule will score +0.79 for the positive category and -0.94
                    for the negative category for images whose power log slope is less than -2.5
                    pixels and will score the opposite for images whose slope is larger.
                    The filter adds positive and negative and flags the images whose
                    positive score is higher than the negative score.
                    <p>Note that if the rules are obtained from CellProfiler Analyst, the images
                    that are fail are those represented by the second number between the brackets.</p>"""))

        group.append("measurement", cps.Measurement("Which measurement?",
                                                    object_fn))
        group.append("wants_minimum",
                     cps.Binary("Flag images based on low values?",
                                True, doc = '''Images with measurements below this cutoff will be flagged.'''))
        group.append("minimum_value", cps.Float("Minimum value", 0))
        group.append("wants_maximum",
                     cps.Binary("Flag images based on high values?",
                                True, doc = '''Images with measurements above this cutoff will be flagged.'''))
        group.append("maximum_value", cps.Float("Maximum value", 1))
        
        if can_delete:
            group.append("remover", cps.RemoveSettingButton("", "Remove this measurement", measurement_settings, group))
            
        group.append("divider2", cps.Divider(line=True))
        measurement_settings.append(group)
Example #15
0
    def create_settings(self):
        """Create the settings for the module

        Create the settings for the module during initialization.
        """
        self.contrast_choice = cps.Choice(
            "Make each classification decision on how many measurements?",
            [BY_SINGLE_MEASUREMENT, BY_TWO_MEASUREMENTS],
            doc="""
            This setting controls how many measurements are used to make a classifications decision
            for each object:
            <ul>
            <li><i>%(BY_SINGLE_MEASUREMENT)s:</i> Classifies each object based on a single measurement.</li>
            <li><i>%(BY_TWO_MEASUREMENTS)s:</i> Classifies each object based on a pair of measurements taken
            together (that is, an object must meet two criteria to belong to a class).</li>
            </ul>""" % globals())

        ############### Single measurement settings ##################
        #
        # A list holding groupings for each of the single measurements
        # to be done
        #
        self.single_measurements = []
        #
        # A count of # of measurements
        #
        self.single_measurement_count = cps.HiddenCount(
            self.single_measurements)
        #
        # Add one single measurement to start off
        #
        self.add_single_measurement(False)
        #
        # A button to press to get another measurement
        #
        self.add_measurement_button = cps.DoSomething(
            "", "Add another classification", self.add_single_measurement)
        #
        ############### Two-measurement settings #####################
        #
        # The object for the contrasting method
        #
        self.object_name = cps.ObjectNameSubscriber("Select the object name",
                                                    cps.NONE,
                                                    doc="""
            Choose the object that you want to measure from the list.
            This should be an object created by a previous module such as
            <b>IdentifyPrimaryObjects</b>, <b>IdentifySecondaryObjects</b>, or
            <b>IdentifyTertiaryObjects</b>.""")

        #
        # The two measurements for the contrasting method
        #
        def object_fn():
            return self.object_name.value

        self.first_measurement = cps.Measurement(
            "Select the first measurement",
            object_fn,
            doc="""
            Choose a measurement made on the above object. This is
            the first of two measurements that will be contrasted together.
            The measurement should be one made on the object in a prior
            module.""")

        self.first_threshold_method = cps.Choice(
            "Method to select the cutoff", [TM_MEAN, TM_MEDIAN, TM_CUSTOM],
            doc="""
            Objects are classified as being above or below a cutoff
            value for a measurement. You can set this cutoff threshold in one
            of three ways:<br>
            <ul>
            <li><i>%(TM_MEAN)s</i>: At the mean
            of the measurement's value for all objects in the image cycle.</li>
            <li><i>%(TM_MEDIAN)s</i>: At the median of the
            measurement's value for all objects in the image set.</li>
            <li><i>%(TM_CUSTOM)s</i>: You specify a custom threshold value.</li>
            </ul>""" % globals())

        self.first_threshold = cps.Float("Enter the cutoff value",
                                         0.5,
                                         doc="""
            This is the cutoff value separating objects in the two
            classes.""")

        self.second_measurement = cps.Measurement(
            "Select the second measurement",
            object_fn,
            doc="""
            Select a measurement made on the above object. This is
            the second of two measurements that will be contrasted together.
            The measurement should be one made on the object in a prior
            module.""")

        self.second_threshold_method = cps.Choice(
            "Method to select the cutoff", [TM_MEAN, TM_MEDIAN, TM_CUSTOM],
            doc="""
            Objects are classified as being above or below a cutoff
            value for a measurement. You can set this cutoff threshold in one
            of three ways:<br>
            <ul>
            <li><i>%(TM_MEAN)s:</i> At the mean
            of the measurement's value for all objects in the image cycle.</li>
            <li><i>%(TM_MEDIAN)s:</i> At the median of the
            measurement's value for all objects in the image set.</li>
            <li><i>%(TM_CUSTOM)s:</i> You specify a custom threshold value.</li>
            </ul>""" % globals())

        self.second_threshold = cps.Float("Enter the cutoff value",
                                          0.5,
                                          doc="""
            This is the cutoff value separating objects in the two
            classes.""")

        self.wants_custom_names = cps.Binary("Use custom names for the bins?",
                                             False,
                                             doc="""
            Select <i>%(YES)s</i> if you want to specify the names of each bin
            measurement. <br>
            Select <i>%(NO)s</i> to create names based on the
            measurements. For instance, for
            "Intensity_MeanIntensity_Green" and "Intensity_TotalIntensity_Blue",
            the module generates measurements such as
            "Classify_Intensity_MeanIntensity_Green_High_Intensity_TotalIntensity_Low"."""
                                             % globals())

        self.low_low_custom_name = cps.AlphanumericText(
            "Enter the low-low bin name",
            "low_low",
            doc="""
            <i>(Used only if using a pair of measurements)</i><br>
            Name of the measurement for objects that
            fall below the threshold for both measurements.""")

        self.low_high_custom_name = cps.AlphanumericText(
            "Enter the low-high bin name",
            "low_high",
            doc="""
            <i>(Used only if using a pair of measurements)</i><br>
            Name of the measurement for objects whose
            first measurement is below threshold and whose second measurement
            is above threshold.""")

        self.high_low_custom_name = cps.AlphanumericText(
            "Enter the high-low bin name",
            "high_low",
            doc="""
            <i>(Used only if using a pair of measurements)</i><br>
            Name of the measurement for objects whose
            first measurement is above threshold and whose second measurement
            is below threshold.""")

        self.high_high_custom_name = cps.AlphanumericText(
            "Enter the high-high bin name",
            "high_high",
            doc="""
            <i>(Used only if using a pair of measurements)</i><br>
            Name of the measurement for objects that
            are above the threshold for both measurements.""")

        self.wants_image = cps.Binary(
            "Retain an image of the classified objects?",
            False,
            doc="""
            Select <i>%(YES)s</i> to retain the image of the objects color-coded according
            to their classification, for use later in the pipeline (for example,
            to be saved by a <b>SaveImages</b> module).""" % globals())

        self.image_name = cps.ImageNameProvider("Enter the image name",
                                                cps.NONE,
                                                doc="""
            <i>(Used only if the classified object image is to be retained for later use in the pipeline)</i> <br>
            Enter the name to be given to the classified object image.""")
    def add_dose_value(self, can_remove=True):
        '''Add a dose value measurement to the list

        can_delete - set this to False to keep from showing the "remove"
                     button for images that must be present.'''
        group = cps.SettingsGroup()
        group.append("measurement",
                     cps.Measurement("Select the image measurement describing the treatment dose",
                                     lambda: cpmeas.IMAGE,
                                     doc="""
            The V and Z' factor, a measure of assay quality, and the EC50, indicating
            dose/response, are calculated by this module based on each image being
            specified as a particular treatment dose. Choose a measurement that gives
            the dose of some treatment for each of your images. <p>
            The typical way to provide this information in the pipeline is to create
            a comma-delimited text file (CSV) outside of CellProfiler and then load that file into the pipeline
            using <b>Metadata</b> or the <b>LoadData</b>. In that case, choose the
            measurement that matches the column header of the measurement
            in the CSV input file. See <b>LoadData</b> help for an example text file.
            """))

        group.append("log_transform", cps.Binary(
                "Log-transform the dose values?", False, doc='''
            Select <i>%(YES)s</i> if you have dose-response data and you want to log-transform
            the dose values before fitting a sigmoid curve.
            <p>Select <i>%(NO)s</i> if your data values indicate only positive vs. negative
            controls.</p>''' % globals()))

        group.append('wants_save_figure', cps.Binary(
                '''Create dose/response plots?''', False, doc='''<a name='wants_save_figure'></a>
            Select <i>%(YES)s</i> if you want to create and save
            dose response plots. You will be asked for information on how to save the plots.''' % globals()))

        group.append('figure_name', cps.Text(
                "Figure prefix", "", doc='''
            <i>(Used only when creating dose/response plots)</i><br>
            CellProfiler will create a file name by appending the measurement name
            to the prefix you enter here. For instance, if you have objects
            named, "Cells", the "AreaShape_Area measurement", and a prefix of "Dose_",
            CellProfiler will save the figure as <i>Dose_Cells_AreaShape_Area.m</i>.
            Leave this setting blank if you do not want a prefix.'''
        ))
        group.append('pathname', cps.DirectoryPath(
                "Output file location",
                dir_choices=[
                    cps.DEFAULT_OUTPUT_FOLDER_NAME, cps.DEFAULT_INPUT_FOLDER_NAME,
                    cps.ABSOLUTE_FOLDER_NAME, cps.DEFAULT_OUTPUT_SUBFOLDER_NAME,
                    cps.DEFAULT_INPUT_SUBFOLDER_NAME], doc="""
            <i>(Used only when creating dose/response plots)</i><br>
            This setting lets you choose the folder for the output
            files. %(IO_FOLDER_CHOICE_HELP_TEXT)s

            <p>%(IO_WITH_METADATA_HELP_TEXT)s %(USING_METADATA_TAGS_REF)s
            For instance, if you have a metadata tag named
            "Plate", you can create a per-plate folder by selecting one of the subfolder options
            and then specifying the subfolder name as "\g&lt;Plate&gt;". The module will
            substitute the metadata values for the current image set for any metadata tags in the
            folder name. %(USING_METADATA_HELP_REF)s.</p>""" % globals()))

        group.append("divider", cps.Divider())

        group.append("remover", cps.RemoveSettingButton("", "Remove this dose measurement",
                                                        self.dose_values,
                                                        group))
        self.dose_values.append(group)
    def create_settings(self):
        """Create the module settings
        
        create_settings is called at the end of initialization.
        """
        self.object = cps.ObjectNameSubscriber(
            'Select the object whose measurements will be displayed',
            cps.NONE,
            doc='''
            Choose the name of objects identified by some previous 
            module (such as <b>IdentifyPrimaryObjects</b> or 
            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed.'''
        )

        self.x_axis = cps.Measurement('Select the object measurement to plot',
                                      self.get_object,
                                      cps.NONE,
                                      doc='''
            Choose the object measurement made by a previous 
            module to plot.''')

        self.bins = cps.Integer('Number of bins',
                                100,
                                1,
                                1000,
                                doc='''
            Enter the number of equally-spaced bins that you want 
            used on the X-axis.''')

        self.xscale = cps.Choice(
            'Transform the data prior to plotting along the X-axis?',
            ['no', 'log'],
            None,
            doc='''
            The measurement data can be scaled with either a 
            linear scale (<i>No</i>) or a <i>log</i> (base 10) 
            scaling.
            <p>Log scaling is useful when one of the 
            measurements being plotted covers a large range of 
            values; a log scale can bring out features in the 
            measurements that would not easily be seen if the 
            measurement is plotted linearly.<p>''')

        self.yscale = cps.Choice('How should the Y-axis be scaled?',
                                 ['linear', 'log'],
                                 None,
                                 doc='''
            The Y-axis can be scaled either with either a <i>linear</i> 
            scale or a <i>log</i> (base 10) scaling. 
            <p>Log scaling is useful when one of the 
            measurements being plotted covers a large range of 
            values; a log scale can bring out features in the 
            measurements that would not easily be seen if the 
            measurement is plotted linearly.</p>''')

        self.title = cps.Text('Enter a title for the plot, if desired',
                              '',
                              doc='''
            Enter a title for the plot. If you leave this blank,
            the title will default 
            to <i>(cycle N)</i> where <i>N</i> is the current image 
            cycle being executed.''')

        self.wants_xbounds = cps.Binary(
            'Specify min/max bounds for the X-axis?',
            False,
            doc='''
            Select <i>%(YES)s</i> to specify minimum and maximum values for the 
            plot on the X-axis. This is helpful if an outlier bin skews the
            plot such that the bins of interest are no longer visible.''' %
            globals())

        self.xbounds = cps.FloatRange('Minimum/maximum values for the X-axis')
Example #18
0
    def create_settings(self):
        self.objects_or_image = cps.Choice(
            "Display object or image measurements?", [OI_OBJECTS, OI_IMAGE],
            doc="""
            <ul>
            <li><i>%(OI_IMAGE)s</i> allows you to select an image 
            measurement to display for each well.</li> 
            <li><i>%(OI_OBJECTS)s</i> allows you to select an object measurement to display 
            for each well.</li>
            </ul>""" % globals())

        self.object = cps.ObjectNameSubscriber(
            'Select the object whose measurements will be displayed',
            cps.NONE,
            doc='''
            Choose the name of objects identified by some previous 
            module (such as <b>IdentifyPrimaryObjects</b> or 
            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed.'''
        )

        self.plot_measurement = cps.Measurement(
            'Select the measurement to plot',
            self.get_object,
            cps.NONE,
            doc='''
            Choose the image or object measurement made by a previous module to plot.'''
        )

        self.plate_name = cps.Measurement('Select your plate metadata',
                                          lambda: cpmeas.IMAGE,
                                          'Metadata_Plate',
                                          doc='''
            Choose the metadata tag that corresponds to the plate identifier. That is,
            each plate should have a metadata tag containing a specifier corresponding
            uniquely to that plate. 
            <p>%(USING_METADATA_HELP_REF)s.</p>''' % globals())

        self.plate_type = cps.Choice(
            'Multiwell plate format', ['96', '384'],
            doc=
            '''The module assumes that your data is laid out in a multi-well plate format
            common to high-throughput biological screens. Supported formats are:
            <ul>
            <li><i>96:</i> A 96-well plate with 8 rows &times; 12 columns</li>
            <li><i>384:</i> A 384-well plate with 16 rows &times; 24 columns</li>
            </ul>''')

        self.well_format = cps.Choice("Well metadata format",
                                      [WF_NAME, WF_ROWCOL],
                                      doc="""
            <ul>
            <li> <i>%(WF_NAME)s</i> allows you to select an image 
            measurement to display for each well.</li> 
            <li><i>%(WF_ROWCOL)s</i> allows you to select an object measurement to display 
            for each well.</li>
            </ul>""" % globals())

        self.well_name = cps.Measurement('Select your well metadata',
                                         lambda: cpmeas.IMAGE,
                                         'Metadata_Well',
                                         doc='''
            Choose the metadata tag that corresponds to the well identifier. 
            The row-column format of these entries should be an 
            alphabetical character (specifying the plate row), followed by two integer 
            characters (specifying the plate column). For example, a standard format 
            96-well plate would span from "A1" to "H12", whereas a 384-well plate (16 
            rows and 24 columns) would span from well "A01" to well "P24"." 
            <p>%(USING_METADATA_HELP_REF)s.</p>''' % globals())

        self.well_row = cps.Measurement('Select your well row metadata',
                                        lambda: cpmeas.IMAGE,
                                        'Metadata_WellRow',
                                        doc='''
            Choose the metadata tag that corresponds to the well row identifier, typically
            specified as an alphabetical character. For example, a standard format 
            96-well plate would span from  row "A" to "H", whereas a 384-well plate (16 
            rows and 24 columns) would span from row "A" to "P".
            <p>%(USING_METADATA_HELP_REF)s.</p>''' % globals())

        self.well_col = cps.Measurement('Select your well column metadata',
                                        lambda: cpmeas.IMAGE,
                                        'Metadata_WellCol',
                                        doc='''
            Choose the metadata tag that corresponds to the well column identifier, typically
            specified with two integer characters. For example, a standard format 
            96-well plate would span from column "01" to "12", whereas a 384-well plate (16 
            rows and 24 columns) would span from column "01" to "24".
            <p>%(USING_METADATA_HELP_REF)s.</p>''' % globals())

        self.agg_method = cps.Choice('How should the values be aggregated?',
                                     AGG_NAMES,
                                     AGG_NAMES[0],
                                     doc='''
            Measurements must be aggregated to a 
            single number for each well so that they can be represented by a color. 
            Options are:
            <ul>
            <li><i>%(AGG_AVG)s:</i> Average</li>
            <li><i>%(AGG_STDEV)s:</i> Standard deviation</li>
            <li><i>%(AGG_MEDIAN)s</i></li>
            <li><i>%(AGG_CV)s:</i> Coefficient of variation, defined as the ratio of the standard 
            deviation to the mean. This is useful for comparing between data sets with 
            different units or widely different means.</li>
            </ul>''' % globals())

        self.title = cps.Text('Enter a title for the plot, if desired',
                              '',
                              doc='''
            Enter a title for the plot. If you leave this blank,
            the title will default 
            to <i>(cycle N)</i> where <i>N</i> is the current image 
            cycle being executed.''')
Example #19
0
    def create_settings(self):
        self.x_object = cps.ObjectNameSubscriber(
            'Select the object to display on the X-axis',
            'None',
            doc='''
                            Choose the name of objects identified by some previous 
                            module (such as <b>IdentifyPrimaryObjects</b> or 
                            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed on the X-axis.'''
        )

        self.x_axis = cps.Measurement(
            'Select the object measurement to plot on the X-axis',
            self.get_x_object,
            'None',
            doc='''
                            Choose the object measurement made by a previous 
                            module to display on the X-axis.''')

        self.y_object = cps.ObjectNameSubscriber(
            'Select the object to display on the Y-axis',
            'None',
            doc=''' 
                            Choose the name of objects identified by some previous 
                            module (such as <b>IdentifyPrimaryObjects</b> or 
                            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed on the Y-axis.'''
        )

        self.y_axis = cps.Measurement(
            'Select the object measurement to plot on the Y-axis',
            self.get_y_object,
            'None',
            doc='''
                            Choose the object measurement made by a previous 
                            module to display on the Y-axis.''')

        self.gridsize = cps.Integer('Select the grid size',
                                    100,
                                    1,
                                    1000,
                                    doc='''
                            Enter the number of grid regions you want used on each
                            axis. Increasing the number of grid regions increases the
                            resolution of the plot.''')

        self.xscale = cps.Choice('How should the X-axis be scaled?',
                                 ['linear', 'log'],
                                 None,
                                 doc='''
                            The X-axis can be scaled either with a <i>linear</i> 
                            scale or with a <i>log</i> (base 10) scaling. 
                            <p>Using a log scaling is useful when one of the 
                            measurements being plotted covers a large range of 
                            values; a log scale can bring out features in the 
                            measurements that would not easily be seen if the 
                            measurement is plotted linearly.</p>''')

        self.yscale = cps.Choice('How should the Y-axis be scaled?',
                                 ['linear', 'log'],
                                 None,
                                 doc='''
                            The Y-axis can be scaled either with a <i>linear</i> 
                            scale or with a <i>log</i> (base 10) scaling. 
                            <p>Using a log scaling is useful when one of the 
                            measurements being plotted covers a large range of 
                            values; a log scale can bring out features in the 
                            measurements that would not easily be seen if the 
                            measurement is plotted linearly.</p>''')

        self.bins = cps.Choice('How should the colorbar be scaled?',
                               ['linear', 'log'],
                               None,
                               doc='''
                            The colorbar can be scaled either with a <i>linear</i> 
                            scale or with a <i>log</i> (base 10) scaling.
                            <p>Using a log scaling is useful when one of the 
                            measurements being plotted covers a large range of 
                            values; a log scale can bring out features in the 
                            measurements that would not easily be seen if the 
                            measurement is plotted linearly.''')

        maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith('_r')]
        maps.sort()

        self.colormap = cps.Choice('Select the color map',
                                   maps,
                                   'jet',
                                   doc='''
                            Select the color map for the density plot. See this 
                            <a href="http://www.astro.princeton.edu/~msshin/science/code/matplotlib_cm/">
                            page</a> for pictures of the available colormaps.'''
                                   )

        self.title = cps.Text('Enter a title for the plot, if desired',
                              '',
                              doc='''
                            Enter a title for the plot. If you leave this blank,
                            the title will default 
                            to <i>(cycle N)</i> where <i>N</i> is the current image 
                            cycle being executed.''')
Example #20
0
    def create_settings(self):        
        self.objects_or_image = cps.Choice(
            "Display object or image measurements?",
            [OI_OBJECTS, OI_IMAGE],
            doc = """<ul><li> <i>%s</i> allows you to select an image 
            measurement to display for each well.</li> 
            <li><i>%s</i> allows you to select an object measurement to display 
            for each well.</li></ul>"""%(OI_IMAGE, OI_OBJECTS))
        
        self.object = cps.ObjectNameSubscriber(
            'Select the object whose measurements will be displayed','None',
            doc='''
            Choose the name of objects identified by some previous 
            module (such as <b>IdentifyPrimaryObjects</b> or 
            <b>IdentifySecondaryObjects</b>) whose measurements are to be displayed.''')
        
        self.plot_measurement = cps.Measurement(
            'Select the measurement to plot', self.get_object, 'None', doc='''
            Choose the image or object measurement made by a previous module to plot.''')
                
        self.plate_name = cps.Measurement('Select your plate metadata',
            lambda:cpmeas.IMAGE, 'Metadata_Plate', doc = '''
            Choose the metadata that corresponds to the plate identifier. That is,
            each plate should have a metadata tag containing a specifier corresponding
            uniquely to that plate. 
            <p>%(USING_METADATA_HELP_REF)s.</p>'''%globals())
        
        self.plate_type = cps.Choice(
            'What type of plate is the data from?',
            ['96','384'],doc = 
            '''The module assumes that your data is laid out in a multi-well plate format
            common to high-throughput biological screens. Supported formats are:
            <ul>
            <li><i>96:</i> A 96-well plate with 8 rows x 12 columns</li>
            <li><i>384:</i> A 384-well plate with 16 rows x 24 columns</li>
            </ul>''')
        
        self.well_format = cps.Choice(
            "What form is your well metadata in?",
            [WF_NAME, WF_ROWCOL],
            doc = """<ul><li> <i>%s</i> allows you to select an image 
            measurement to display for each well.</li> 
            <li><i>%s</i> allows you to select an object measurement to display 
            for each well.</li></ul>"""%(WF_NAME, WF_ROWCOL))

        self.well_name = cps.Measurement('Select your well metadata', 
            lambda:cpmeas.IMAGE, 'Metadata_Well', doc = '''
            Choose the metadata that corresponds to the well identifier, such as
            "A01." 
            <p>%(USING_METADATA_HELP_REF)s.</p>'''%globals())

        self.well_row = cps.Measurement('Select your well row metadata', 
            lambda:cpmeas.IMAGE, 'Metadata_WellRow', doc = '''
            Choose the metadata that corresponds to the well row identifier. For many plates,
            the column is specified as a letter. 
            <p>%(USING_METADATA_HELP_REF)s.</p>'''%globals())
        
        self.well_col = cps.Measurement('Select your well column metadata', 
            lambda:cpmeas.IMAGE, 'Metadata_WellCol', doc = '''
            Choose the metadata that corresponds to the well row identifier. For many plates,
            the row is specified as a number. 
            <p>%(USING_METADATA_HELP_REF)s.</p>'''%globals())

        self.agg_method = cps.Choice(
            'How should the values be aggregated?', 
            AGG_NAMES, AGG_NAMES[0], doc='''Measurements must be aggregated to a 
            single number for each well so that they can be represented by a color. 
            Options are:
            <ul>
            <li><i>avg:</i> Average</li>
            <li><i>stdev:</i> Standard deviation</li>
            <li><i>median</i></li>
            <li><i>cv%:</i> Coefficient of variation, defined as the ratio of the standard 
            deviation to the mean. This is useful for comparing between data sets with 
            different units or widely different means.</li>
            </ul>''')

        self.title = cps.Text(
            'Enter a title for the plot, if desired', '',
            doc = '''
            Enter a title for the plot. If you leave this blank,
            the title will default 
            to <i>(cycle N)</i> where <i>N</i> is the current image 
            cycle being executed.''')