Exemple #1
0
    def create_settings(self):
        """Create the settings for the module

        Create the settings for the module during initialization.
        """
        self.secondary_objects_name = cps.ObjectNameSubscriber(
            "Select the larger identified objects",
            cps.NONE,
            doc="""
            Select the larger identified objects. This will usually
            be an object previously identified by a <b>IdentifySecondaryObjects</b>
            module.""")

        self.primary_objects_name = cps.ObjectNameSubscriber(
            "Select the smaller identified objects",
            cps.NONE,
            doc="""
            Select the smaller identified objects. This will usually
            be an object previously identified by a <b>IdentifyPrimaryObjects</b>
            module.""")

        self.subregion_objects_name = cps.ObjectNameProvider(
            "Name the tertiary objects to be identified",
            "Cytoplasm",
            doc="""
            Enter a name for the new tertiary objects. The tertiary objects
            will consist of the smaller object subtracted from the larger object."""
        )

        self.shrink_primary = cps.Binary(
            "Shrink smaller object prior to subtraction?",
            True,
            doc="""
            Select <i>%(YES)s</i> to shrink the smaller object by 1 pixel before subtracting the objects.
            this approach will ensure that there is always a tertiary object produced, even if it is
            only 1 pixel wide.
            <p>Select <i>%(NO)s</i> to subtract the objects directly, which will ensure that no pixels
            are shared between the primary/secondary/tertiary objects and hence measurements for all
            three sets of objects will not use the same pixels multiple times. However, this may result
            in the creation of objects with no area. Measurements can still be made on such objects, but
            the results will be zero or not-a-number (NaN)</p>""" % globals())

        self.use_outlines = cps.Binary(
            "Retain outlines of the tertiary objects?",
            False,
            doc="""
            %(RETAINING_OUTLINES_HELP)s""" % globals())

        self.outlines_name = cps.OutlineNameProvider("Name the outline image",
                                                     "CytoplasmOutlines",
                                                     doc="""
            %(NAMING_OUTLINES_HELP)s""" % globals())
    def add_object(self, can_remove=True):
        '''Add an object to be measured (plus optional centers)'''
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider(line=False))
        group.append(
            "object_name",
            cps.ObjectNameSubscriber("Select objects to measure",
                                     cps.NONE,
                                     doc="""
                Select the objects that you want to measure the intensity from."""
                                     ))

        group.append(
            "center_choice",
            cps.Choice("Object to use as center?",
                       C_ALL,
                       doc="""
                There are three ways to specify the center of the radial measurement:
                <ul>
                <li><i>%(C_SELF)s:</i> Use the centers of these objects for the
                radial measurement.</li>
                <li><i>%(C_CENTERS_OF_OTHER)s:</i> Use the centers of other objects
                for the radial measurement.</li>
                <li><i>%(C_EDGES_OF_OTHER)s:</i> Measure distances from the
                edge of the other object to each pixel outside of the
                centering object. Do not include pixels within the centering
                object in the radial measurement calculations.</li>
                </ul>
                For example, if measuring the radial distribution in a Cell
                object, you can use the center of the Cell objects (<i>%(C_SELF)s</i>)
                or you can use previously identified Nuclei objects as
                the centers (<i>%(C_CENTERS_OF_OTHER)s</i>).""" % globals()))

        group.append(
            "center_object_name",
            cps.ObjectNameSubscriber("Select objects to use as centers",
                                     cps.NONE,
                                     doc="""
                <i>(Used only if "%(C_CENTERS_OF_OTHER)s" are selected for centers)</i><br>
                Select the object to use as the center, or select <i>None</i> to
                use the input object centers (which is the same as selecting
                <i>%(C_SELF)s</i> for the object centers).""" % globals()))

        if can_remove:
            group.append(
                "remover",
                cps.RemoveSettingButton("", "Remove this object", self.objects,
                                        group))
        self.objects.append(group)
    def add_object_group(self, can_remove: bool = True) -> None:
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider(line=False))

        group.append(
            "name",
            cps.ObjectNameSubscriber(
                text="Select objects to measure",
                value="None",
                doc="Select the objects that you want to measure.",
            ),
        )

        if can_remove:
            group.append(
                "remove",
                cps.RemoveSettingButton(
                    text="",
                    label="Remove this object",
                    list=self.object_groups,
                    entry=group,
                ),
            )

        self.object_groups.append(group)
 def add_object_cb(self, can_remove=True):
     '''Add an object to the object_groups collection
     
     can_delete - set this to False to keep from showing the "remove"
                  button for objects that must be present.
     '''
     group = cps.SettingsGroup()
     if can_remove:
         group.append("divider", cps.Divider(line=False))
     group.append(
         'object_name',
         cps.ObjectNameSubscriber("Select objects to measure",
                                  "None",
                                  doc="""
                     What did you call the objects whose texture you want to measure? 
                     If you only want to measure the texture 
                     for the image overall, you can remove all objects using the "Remove this object" button. 
                     <p>Objects specified here will have their
                     texture measured against <i>all</i> images specfied above, which
                     may lead to image-object combinations that are unneccesary. If you
                     do not want this behavior, use multiple <b>EnhancedMeasureTexture</b>
                     modules to specify the particular image-object measures that you want.</p>"""
                                  ))
     if can_remove:
         group.append(
             "remover",
             cps.RemoveSettingButton("", "Remove this object",
                                     self.object_groups, group))
     self.object_groups.append(group)
    def create_settings(self):

        self.input_object_name = cps.ObjectNameSubscriber(
            "Select objects to measure",
            cps.NONE,
            doc=
            """Select the objects whose radial entropy you want to measure.""")

        self.input_image_name = cps.ImageNameSubscriber(
            "Select an image to measure",
            cps.NONE,
            doc="""Select the
            grayscale image you want to measure the entropy of.""")

        self.bin_number = cps.Integer(
            "Input number of bins",
            6,
            minval=3,
            maxval=60,
            doc=
            """Number of radial bins to divide your object into.  The minimum number
            of bins allowed is 3, the maximum number is 60.""")

        self.intensity_measurement = cps.Choice(
            "Which intensity measurement should be used?",
            ['Mean', 'Median', 'Integrated'],
            value='Mean',
            doc="""
            Whether each wedge's mean, median, or integrated intensity
            should be used to calculate the entropy.""")
    def create_settings(self):
        self.object_name = cps.ObjectNameSubscriber("Select the input objects",
                                                    cps.NONE,
                                                    doc='''
            Select the objects that you want to rescale.''')

        self.output_object_name = cps.ObjectNameProvider(
            "Name the output objects",
            "RescaledObject",
            doc='''
            Enter a name for the resulting objects.''')

        self.operation = cps.Choice("Select the operation",
                                    O_ALL,
                                    doc='''
            Select the operation that you want to perform:
            <ul>
            <li><i>%(O_DOWNSCALE)s:</i> Downscale the Object Masks to a smaller image size.</li>
            <li><i>%(O_UPSCALE)s:</i> Expand objects, assigning every pixel in the image to an
            object. Background pixels are assigned to the nearest object.</li>
            </ul>''' % globals())

        self.scaling = cps.Float("Factor to scale the object mask",
                                 1,
                                 minval=0)
    def add_image_measurement(self, can_remove=True):
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider())

        group.append("image_name", cps.ImageNameSubscriber(
                "Select the image to measure",
                cps.NONE, doc="""\
Choose an image name from the drop-down menu to calculate intensity for
that image. Use the *Add another image* button below to add additional
images to be measured. You can add the same image multiple times
if you want to measure the intensity within several different
objects."""))

        group.append("wants_objects", cps.Binary(
                "Measure the intensity only from areas enclosed by objects?",
                False, doc="""\
Select *%(YES)s* to measure only those pixels within an object type you
choose, identified by a prior module. Note that this module will
aggregate intensities across all objects in the image: to measure each
object individually, see **MeasureObjectIntensity** instead.
""" % globals()))

        group.append("object_name", cps.ObjectNameSubscriber(
                "Select the input objects", cps.NONE, doc="""\
*(Used only when measuring intensity from area occupied by objects)*

Select the objects that the intensity will be aggregated within. The
intensity measurement will be restricted to the pixels within these
objects."""))

        if can_remove:
            group.append("remover", cps.RemoveSettingButton("",
                                                            "Remove this image", self.images, group))
        self.images.append(group)
            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.""",
                )
Exemple #9
0
 def create_settings(self):
     self.object_name = cps.ObjectNameSubscriber(
         "Input objects", "None",
         doc = """Enter the name of the objects whose population context is
         to be measured.""")
     self.operation = cps.Choice(
         "Operation",
         choices= (O_POPULATION_DENSITY, O_DISTANCE_TO_EDGE, O_BOTH),
         doc = """Select the measurements you wish to perform. The choices
         are:<br><ul>
         <li><i>%(O_POPULATION_DENSITY)s</i> - calculate the population
         density within a radius from each cell.</li>
         <li><i>%(O_DISTANCE_TO_EDGE)s</i> - calculate the distance of
         each cell from the edge of a binary mask.</li>
         <li><i>%(O_BOTH)s</i> - make both measurements"""%globals())
     self.radius = cps.Integer(
         "Search radius", 50, minval=1,
         doc = """Count all objects within this radius""")
     self.object_diameter = cps.Integer(
         "Object diameter", 20, minval=0,
         doc = """The average diameter of objects in the image. This number
         is used to adjust the area of the image to account for objects
         that would otherwise be excluded because they were touching
         the border.""")
     self.edge_image = cps.ImageNameSubscriber(
         "Edge image",
         doc = """For measuring distance to an edge, this is the reference
         image. Cell distances will be computed to the nearest foreground / 
         background edge in the reference image.""")
Exemple #10
0
    def create_settings(self):
        """Create the settings for the module

        Create the settings for the module during initialization.
        """
        self.secondary_objects_name = cps.ObjectNameSubscriber(
            "Select the larger identified objects",
            cps.NONE,
            doc="""\
Select the larger identified objects. This will usually be an object
previously identified by an **IdentifySecondaryObjects** module.""",
        )

        self.primary_objects_name = cps.ObjectNameSubscriber(
            "Select the smaller identified objects",
            cps.NONE,
            doc="""\
Select the smaller identified objects. This will usually be an object
previously identified by an **IdentifyPrimaryObjects** module.""",
        )

        self.subregion_objects_name = cps.ObjectNameProvider(
            "Name the tertiary objects to be identified",
            "Cytoplasm",
            doc="""\
Enter a name for the new tertiary objects. The tertiary objects
will consist of the smaller object subtracted from the larger object.""",
        )

        self.shrink_primary = cps.Binary(
            "Shrink smaller object prior to subtraction?",
            True,
            doc="""\
Select *Yes* to shrink the smaller objects by 1 pixel before
subtracting them from the larger objects. this approach will ensure that
there is always a tertiary object produced, even if it is only 1 pixel wide.
If you need alternate amounts of shrinking, use the **ExpandOrShrink**
module prior to **IdentifyTertiaryObjects**.

Select *No* to subtract the objects directly, which will ensure that
no pixels are shared between the primary/secondary/tertiary objects and
hence measurements for all three sets of objects will not use the same
pixels multiple times. However, this may result in the creation of
objects with no area. Measurements can still be made on such objects,
but the results will be zero or not-a-number (NaN).
""" % globals(),
        )
Exemple #11
0
    def create_settings(self):
        """Create the settings here and set the module name (initialization)

        """
        self.source_choice = cps.Choice("Use objects or an image as a mask?",
                                        [IO_OBJECTS, IO_IMAGE],
                                        doc="""\
You can mask an image in two ways:

-  *%(IO_OBJECTS)s*: Using objects created by another module (for
   instance **IdentifyPrimaryObjects**). The module will mask out all
   parts of the image that are not within one of the objects (unless you
   invert the mask).
-  *%(IO_IMAGE)s*: Using a binary image as the mask, where black
   portions of the image (false or zero-value pixels) will be masked
   out. If the image is not binary, the module will use all pixels whose
   intensity is greater than 0.5 as the mask’s foreground (white area).
   You can use **Threshold** instead to create a binary image with
   finer control over the intensity choice.
   """ % globals())

        self.object_name = cps.ObjectNameSubscriber("Select object for mask",
                                                    cps.NONE,
                                                    doc="""\
*(Used only if mask is to be made from objects)*

Select the objects you would like to use to mask the input image.
""")

        self.masking_image_name = cps.ImageNameSubscriber(
            "Select image for mask",
            cps.NONE,
            doc="""\
*(Used only if mask is to be made from an image)*

Select the image that you like to use to mask the input image.
""")

        self.image_name = cps.ImageNameSubscriber(
            "Select the input image",
            cps.NONE,
            doc="Select the image that you want to mask.")

        self.masked_image_name = cps.ImageNameProvider(
            "Name the output image",
            "MaskBlue",
            doc="Enter the name for the output masked image.")

        self.invert_mask = cps.Binary("Invert the mask?",
                                      False,
                                      doc="""\
This option reverses the foreground/background relationship of the mask.

-  Select "*%(NO)s*" to produce the mask from the foreground (white
   portion) of the masking image or the area within the masking objects.
-  Select "*%(YES)s*" to instead produce the mask from the *background*
   (black portions) of the masking image or the area *outside* the
   masking objects.
       """ % globals())
 def add_objects(self, can_remove=True):
     group = cps.SettingsGroup()
     group.append("object_name",
                  cps.ObjectNameSubscriber("Object name", "Nuclei"))
     if can_remove:
         group.append(
             "remover",
             cps.RemoveSettingButton("Remove object", "Remove",
                                     self.object_classes, group))
     self.object_classes.append(group)
 def add_objects(self):
     og = cps.SettingsGroup()
     og.append("objects_name", cps.ObjectNameSubscriber(
             "Select objects to measure", cps.NONE,
             doc="""Select the objects whose granualarity
         will be measured. You can select objects from prior modules
         that identify objects, such as <b>IdentifyPrimaryObjects</b>. If you only want to measure the granularity
         for the image overall, you can remove all objects using the "Remove this object" button."""))
     og.append("remover", cps.RemoveSettingButton(
             "", "Remove this object", self.objects, og))
     self.objects.append(og)
    def add_outline(self, can_remove=True):
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider(line=False))

        group.append(
            "outline_choice",
            cps.Choice("Load outlines from an image or objects?",
                       [FROM_OBJECTS, FROM_IMAGES],
                       doc="""
            This setting selects what source the outlines come from:
            <ul>
            <li><i>%(FROM_OBJECTS)s:</i> Create the image directly from the
            objects. This option will improve the functionality of the
            contrast options for this module's interactive display and will
            save memory.</li>
            <li><i>%(FROM_IMAGES)s:</i> Prior versions of <b>OverlayOutlines</b> would only
            display outline images which were optional outputs of the identify
            modules. For legacy pipelines or to continue using the outline
            images instead of objects, choose this option.</li>
            </ul>
            """ % globals()))

        group.append(
            "objects_name",
            cps.ObjectNameSubscriber(
                "Select objects to display",
                cps.NONE,
                doc="""Choose the objects whose outlines you would like
        to display."""))
        group.append(
            "outline_name",
            cps.OutlineNameSubscriber("Select outlines to display",
                                      cps.NONE,
                                      doc="""
            Choose outlines to display, from a previous <b>Identify</b>
            module. Each of the <b>Identify</b> modules has a checkbox that
            determines whether the outlines are saved. If you have checked this,
            you were asked to supply a name for the outline; you
            can then select that name here.
            """))

        default_color = (COLOR_ORDER[len(self.outlines)]
                         if len(self.outlines) < len(COLOR_ORDER) else
                         COLOR_ORDER[0])
        group.append("color", cps.Color("Select outline color", default_color))
        if can_remove:
            group.append(
                "remover",
                cps.RemoveSettingButton("", "Remove this outline",
                                        self.outlines, group))

        self.outlines.append(group)
Exemple #15
0
    def add_object(self, can_delete=True):
        '''Add an object to the object_groups collection'''
        group = cps.SettingsGroup()
        if can_delete:
            group.append("divider", cps.Divider(line=False))

        group.append("object_name", cps.ObjectNameSubscriber(
                'Select an object to measure', cps.NONE, doc='''
            Select the objects to be measured.'''))

        if can_delete:
            group.append("remover", cps.RemoveSettingButton('', 'Remove this object', self.object_groups, group))
        self.object_groups.append(group)
    def create_settings(self) -> None:
        self.crop_mask_name = cps.ObjectNameSubscriber(
            text="Select the cropping mask",
            value="None",
            doc="",
            can_be_blank=True,
        )

        self.object_groups = []
        self.add_object_group(can_remove=False)
        self.divider = cps.Divider(line=True)
        self.add_object_group_button = cps.DoSomething(
            text="",
            label="Add another object",
            callback=self.add_object_group)
    def add_object(self, can_remove=True):
        '''Add an object to the object_groups collection

        can_delete - set this to False to keep from showing the "remove"
                     button for images that must be present.
        '''
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider(line=False))
        group.append("name", cps.ObjectNameSubscriber(
                "Select objects to measure", cps.NONE, doc="""
            Select the objects whose intensities you want to measure."""))

        if can_remove:
            group.append("remover", cps.RemoveSettingButton("", "Remove this object", self.objects, group))
        self.objects.append(group)
Exemple #18
0
 def add_objects(self, can_delete=True):
     group = cps.SettingsGroup()
     self.objects_to_export.append(group)
     group.append(
         "objects_name",
         cps.ObjectNameSubscriber("Objects name",
                                  value="Nuclei",
                                  doc="""
             This setting lets you choose the objects you want to export.
             <b>ExportToCellH5</b> will write the segmentation of the objects
             to your CellH5 file so that they can be saved and used by other
             applications that support the format.
             """))
     group.append(
         "Remover",
         cps.RemoveSettingButton("Remove the objects above", "Remove",
                                 self.objects_to_export, group))
    def create_settings(self):
        #
        # The ImageNameSubscriber "subscribes" to all ImageNameProviders in
        # prior modules. Modules before yours will put images into CellProfiler.
        # The ImageSubscriber gives your user a list of these images
        # which can then be used as inputs in your module.
        #
        self.input_image_name = cps.ImageNameSubscriber(
            # The text to the left of the edit box
            "Input image name:",
            # HTML help that gets displayed when the user presses the
            # help button to the right of the edit box
            doc="""This is the image that the module operates on. You can
            choose any image that is made available by a prior module.
            <br>
            <b>ImageTemplate</b> will do something to this image.
            """)

        #
        # The ObjectNameSubscriber is similar - it will ask the user
        # which object to pick from the list of objects provided by
        # upstream modules.
        #
        self.input_object_name = cps.ObjectNameSubscriber(
            "Input object name",
            doc="""These are the objects that the module operates on.""")
        #
        # The radial degree is the "N" parameter in the Zernike - how many
        # inflection points there are, radiating out from the center. Higher
        # N means more features and a more detailed description
        #
        # The setting is an integer setting, bounded between 1 and 50.
        # N = 50 generates 1200 features!
        #
        self.radial_degree = cps.Integer(
            "Radial degree",
            10,
            minval=1,
            maxval=50,
            doc="""Calculate all Zernike features up to the given radial
            degree. The Zernike function is parameterized by a radial
            and azimuthal degree. The module will calculate all Zernike
            features for all azimuthal degrees up to and including the
            radial degree you enter here.""")
Exemple #20
0
    def create_settings(self):
        self.object_name = cps.ObjectNameSubscriber("Select the input objects",
                                                    cps.NONE,
                                                    doc="""
            Choose the name of the objects you want to convert to an image.""")

        self.image_name = cps.ImageNameProvider("Name the output image",
                                                "CellImage",
                                                doc="""
            Enter the name of the resulting image.""")

        self.image_mode = cps.Choice("Select the color format",
                                     IM_ALL,
                                     doc="""
            Select which colors the resulting image should use. You have the following
            options:
            <ul>
            <li><i>%(IM_COLOR)s:</i> Allows you to choose a colormap that will
            produce jumbled colors for your objects. </li>
            <li><i>%(IM_BINARY)s:</i> All object pixels will be assigned 1 and all
            background pixels will be assigned 0, creating a binary image.</li>
            <li><i>%(IM_GRAYSCALE)s:</i> Gives each object
            a graylevel pixel intensity value corresponding to its number (also
            called label), so it usually results in objects on the left side of the
            image being very dark, progressing toward white on the right side of
            the image. </li>
            <li><i>%(IM_UINT16)s:</i> Assigns each object a different number,
            from 1 to 65535 (the numbers that you can put in
            a 16-bit integer) and numbers all pixels in each
            object with the object's number. This format can
            be written out as a .mat or .tiff file if you
            want to process the label matrix image using
            another program.</li>
            </ul>
            You can choose <i>%(IM_COLOR)s</i> with a <i>Gray</i> colormap to produce
            jumbled gray objects.""" % globals())

        self.colormap = cps.Colormap("Select the colormap",
                                     doc="""
            <i>(Used only if "<i>%(IM_COLOR)s</i>" output image selected)</i><br>
            Choose the colormap to be used, which affects how the objects are colored.
            You can look up your default colormap under <i>File > Preferences</i>.
            """ % globals())
    def create_settings(self):
        self.input_type = cps.Choice("Select the type of input",
                                     [IF_IMAGE, IF_OBJECTS], IF_IMAGE)

        self.image_name = cps.ImageNameSubscriber("Select input images",
                                                  cps.NONE)

        self.objects_name = cps.ObjectNameSubscriber(
            "Select the input objects",
            cps.NONE,
        )

        self.output_name = cps.ImageNameProvider(
            "Input the output image stack name",
            "BinStack",
            doc="""
            Input the output name.
            """ % globals())

        self.main_object_def = cps.Choice(
            "How should the main label be determined?",
            [SEL_MID, SEL_MAXAREA, SEL_PROVIDED],
            SEL_MID,
            doc="""
            The main object can be determined by 3 ways:
            <ul>
            <li> %(SEL_PROVIDED)s: Label provided by metadata or
            manual. <\li>
            <li> %(SEL_MAXAREA)s: Label with the biggest area is assumed to be
            the main label. <\li>
            <li> %(SEL_MID)s: The label closest to the middle of the image is
            considered the main label. <\li>
            <\ul>
            """ % globals())

        self.main_object_id = cps.Text("Indicate the object id",
                                       '1',
                                       doc="""
                Indicates the id from the main object.
                Rightclick to choose a metadata value.
                """ % globals(),
                                       metadata=True)
Exemple #22
0
    def add_object(self, can_remove=True):
        """Add a slot for another object"""
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider(line=False))

        group.append(
            "name",
            cps.ObjectNameSubscriber(
                "Select objects to measure",
                cps.NONE,
                doc="""Select the objects that you want to measure."""))

        if can_remove:
            group.append(
                "remove",
                cps.RemoveSettingButton("", "Remove this object",
                                        self.object_groups, group))

        self.object_groups.append(group)
Exemple #23
0
            def __init__(self):
                self.__spacer = cps.Divider(line=True)
                self.__operand_choice = cps.Choice(
                        "Measure the area occupied in a binary image, or in objects?",
                        [O_BINARY_IMAGE, O_OBJECTS], doc="""
                    The area can be measured in two ways:
                    <ul>
                    <li><i>%(O_BINARY_IMAGE)s:</i> The area occupied by the foreground in a binary (black
                    and white) image.</li>
                    <li><i>%(O_OBJECTS)s:</i> The area occupied by previously-identified objects.</li>
                    </ul>""" % globals())

                self.__operand_objects = cps.ObjectNameSubscriber(
                        "Select objects to measure",
                        cps.NONE, doc="""
                    <i>(Used only if '%(O_OBJECTS)s' are to be measured)</i> <br>
                    Select the previously identified objects you would like to measure.""" % globals())

                self.__should_save_image = cps.Binary(
                        "Retain a binary image of the object regions?",
                        False, doc="""
                    <i>(Used only if '%(O_OBJECTS)s' are to be measured)</i><br>
                    Select <i>%(YES)s</i> if you would like to use a binary image
                    later in the pipeline, for example in <b>SaveImages</b>.  The image will
                    display the object area that you have measured as the foreground
                    in white and the background in black. """ % globals())

                self.__image_name = cps.ImageNameProvider(
                        "Name the output binary image",
                        "Stain", doc="""
                    <i>(Used only if the binary image of the objects is to be retained for later use in the pipeline)</i> <br>
                    Specify a name that will allow the binary image of the objects to be selected later in the pipeline.""")

                self.__binary_name = cps.ImageNameSubscriber(
                        "Select a binary image to measure",
                        cps.NONE, doc="""
                    <i>(Used only if '%(O_BINARY_IMAGE)s' is to be measured)</i><br>
                    This is a binary image created earlier in the pipeline,
                    where you would like to measure the area occupied by the foreground
                    in the image.""" % globals())
Exemple #24
0
    def create_settings(self) -> None:
        self.input_mask_name = cps.ObjectNameSubscriber(
            text="Select the input mask", value=cps.NONE, doc="")

        self.padding = cps.Integer(text="Enter padding size (px)",
                                   value=20,
                                   doc="")

        self.output_mask_name = cps.ObjectNameProvider(
            text="Name the output mask",
            value="PaddedMask",
            doc="Enter the name of the output mask",
        )

        self.custom = cps.Binary(text="Use custom settings?",
                                 value="No",
                                 doc="Use custom settings")

        self.divider = cps.Divider(line=True)

        self.image_name = cps.ImageNameSubscriber(
            text="Select image to overlay on",
            value=cps.LEAVE_BLANK,
            doc="""\
Choose the image_name upon which a padded mask constructed from the input_mask is laid.
""",
            can_be_blank=True,
        )

        self.input_mask_color = cps.Color(
            text="Select the input mask color",
            value="red",
            doc="Select the input mask color",
        )

        self.output_mask_color = cps.Color(
            text="Select the output mask color",
            value="blue",
            doc="Select the output mask color",
        )
    def add_image_measurement(self, can_remove=True):
        group = cps.SettingsGroup()
        if can_remove:
            group.append("divider", cps.Divider())

        group.append(
            "image_name",
            cps.ImageNameSubscriber("Select the image to measure",
                                    cps.NONE,
                                    doc='''
            Choose an image name from the drop-down menu to calculate intensity for that
            image. Use the <i>Add another image</i> button below to add additional images which will be
            measured. You can add the same image multiple times if you want to measure
            the intensity within several different objects.'''))

        group.append(
            "wants_objects",
            cps.Binary(
                "Measure the intensity only from areas enclosed by objects?",
                False,
                doc="""
            Select <i>%(YES)s</i> to measure only those pixels within an object of choice."""
                % globals()))

        group.append(
            "object_name",
            cps.ObjectNameSubscriber("Select the input objects",
                                     cps.NONE,
                                     doc='''
            <i>(Used only when measuring intensity from area enclosed by objects)</i><br>
            Select the objects that the intensity will be aggregated within. The intensity measurement will be
            restricted to the pixels within these objects.'''))

        if can_remove:
            group.append(
                "remover",
                cps.RemoveSettingButton("", "Remove this image", self.images,
                                        group))
        self.images.append(group)
Exemple #26
0
    def create_settings(self):
        self.objects_name = cps.ObjectNameSubscriber(
            "Select the input objects",
            cps.NONE,
            doc="""\
Select the objects you would like to split or merge (that is,
whose object numbers you want to reassign). You can
use any objects that were created in previous modules, such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**.""")

        self.output_objects_name = cps.ObjectNameProvider(
            "Name the new objects",
            "RelabeledNuclei",
            doc="""\
Enter a name for the objects that have been split or merged (that is,
whose numbers have been reassigned).
You can use this name in subsequent modules that take objects as inputs.""")

        self.relabel_option = cps.Choice("Operation",
                                         [OPTION_MERGE, OPTION_SPLIT],
                                         doc="""\
You can choose one of the following options:

-  *%(OPTION_MERGE)s:* Assign adjacent or nearby objects the same label
   based on certain criteria. It can be useful, for example, to merge
   together touching objects that were incorrectly split into two pieces
   by an **Identify** module.
-  *%(OPTION_SPLIT)s:* Assign a unique number to separate objects that
   currently share the same label. This can occur if you applied certain
   operations in the **Morph** module to objects.""" % globals())

        self.merge_option = cps.Choice("Merging method",
                                       [UNIFY_DISTANCE, UNIFY_PARENT],
                                       doc="""\
*(Used only with the "%(OPTION_MERGE)s" option)*

You can merge objects in one of two ways:

-  *%(UNIFY_DISTANCE)s:* All objects within a certain pixel radius from
   each other will be merged.
-  *%(UNIFY_PARENT)s:* All objects which share the same parent
   relationship to another object will be merged. This is not to be
   confused with using the **RelateObjects** module, in which the
   related objects remain as individual objects. See **RelateObjects**
   for more details.""" % globals())

        self.merging_method = cps.Choice("Output object type",
                                         [UM_DISCONNECTED, UM_CONVEX_HULL],
                                         doc="""\
*(Used only with the "%(UNIFY_PARENT)s" merging method)*

**SplitOrMergeObjects** can either merge the child objects and keep them
disconnected or it can find the smallest convex polygon (the convex
hull) that encloses all of a parent’s child objects. The convex hull
will be truncated to include only those pixels in the parent - in that
case it may not truly be convex. Choose *%(UM_DISCONNECTED)s* to leave
the children as disconnected pieces. Choose *%(UM_CONVEX_HULL)s* to
create an output object that is the convex hull around them all.""" %
                                         globals())

        self.parent_object = cps.Choice("Select the parent object", [cps.NONE],
                                        choices_fn=self.get_parent_choices,
                                        doc="""\
Select the parent object that will be used to merge the child objects.
Please note the following:

-  You must have established a parent-child relationship between the
   objects using a prior **RelateObjects** module.
-  Primary objects and their associated secondary objects are already in
   a one-to-one parent-child relationship, so it makes no sense to merge
   them here.""")

        self.distance_threshold = cps.Integer(
            "Maximum distance within which to merge objects",
            0,
            minval=0,
            doc="""\
*(Used only with the "%(OPTION_MERGE)s" option and the "%(UNIFY_DISTANCE)s"
method)*

Objects that are less than or equal to the distance you enter here, in
pixels, will be merged. If you choose zero (the default), only objects
that are touching will be merged. Note that *%(OPTION_MERGE)s* will
not actually connect or bridge the two objects by adding any new pixels;
it simply assigns the same object number to the portions of the object.
The new, merged object may therefore consist of two or more unconnected
components. If you want to add pixels around objects, see
**ExpandOrShrink** or **Morph**.""" % globals())

        self.wants_image = cps.Binary("Merge using a grayscale image?",
                                      False,
                                      doc="""\
*(Used only with the "%(OPTION_MERGE)s" option)*

Select *%(YES)s* to use the objects’ intensity features to determine
whether two objects should be merged. If you choose to use a grayscale
image, *%(OPTION_MERGE)s* will merge two objects only if they are
within the distance you have specified *and* certain criteria about the
objects within the grayscale image are met.""" % globals())

        self.image_name = cps.ImageNameSubscriber(
            "Select the grayscale image to guide merging",
            cps.NONE,
            doc="""\
*(Used only if a grayscale image is to be used as a guide for
merging)*

Select the name of an image loaded or created by a previous module.""")

        self.minimum_intensity_fraction = cps.Float(
            "Minimum intensity fraction",
            .9,
            minval=0,
            maxval=1,
            doc="""\
*(Used only if a grayscale image is to be used as a guide for
merging)*

Select the minimum acceptable intensity fraction. This will be used as
described for the method you choose in the next setting.""")

        self.where_algorithm = cps.Choice("Method to find object intensity",
                                          [CA_CLOSEST_POINT, CA_CENTROIDS],
                                          doc="""\
*(Used only if a grayscale image is to be used as a guide for
merging)*

You can use one of two methods to determine whether two objects should
merged, assuming they meet the distance criteria (as specified
above):

-  *%(CA_CENTROIDS)s:* When the module considers merging two objects,
   this method identifies the centroid of each object, records the
   intensity value of the dimmer of the two centroids, multiplies this
   value by the *minimum intensity fraction* to generate a threshold,
   and draws a line between the centroids. The method will merge the two
   objects only if the intensity of every point along the line is above
   the threshold. For instance, if the intensity of one centroid is 0.75
   and the other is 0.50 and the *minimum intensity fraction* has been
   chosen to be 0.9, all points along the line would need to have an
   intensity of min(0.75, 0.50) \* 0.9 = 0.50 \* 0.9 = 0.45.
   This method works well for round cells whose maximum intensity is in
   the center of the cell: a single cell that was incorrectly segmented
   into two objects will typically not have a dim line between the
   centroids of the two halves and will be correctly merged.
-  *%(CA_CLOSEST_POINT)s:* This method is useful for unifying
   irregularly shaped cells that are connected. It starts by assigning
   background pixels in the vicinity of the objects to the nearest
   object. Objects are then merged if each object has background pixels
   that are:

   -  Within a distance threshold from each object;
   -  Above the minimum intensity fraction of the nearest object pixel;
   -  Adjacent to background pixels assigned to a neighboring object.

   An example of a feature that satisfies the above constraints is a
   line of pixels that connects two neighboring objects and is roughly
   the same intensity as the boundary pixels of both (such as an axon
   connecting two neurons' soma).""" % globals())
Exemple #27
0
    def create_settings(self):
        '''Create the settings that control this module'''
        self.object_name = cps.ObjectNameSubscriber(
            "Select objects to be masked",
            cps.NONE,
            doc="""\
Select the objects that will be masked (that is, excluded in whole or in
part based on the other settings in the module). You can choose from any
objects created by a previous object processing module, such as
**IdentifyPrimaryObjects**, **IdentifySecondaryObjects** or
**IdentifyTertiaryObjects**.
""")

        self.remaining_objects = cps.ObjectNameProvider(
            "Name the masked objects",
            "MaskedNuclei",
            doc="""\
Enter a name for the objects that remain after
the masking operation. You can refer to the masked objects in
subsequent modules by this name.
""")

        self.mask_choice = cps.Choice(
            "Mask using a region defined by other objects or by binary image?",
            [MC_OBJECTS, MC_IMAGE],
            doc="""\
You can mask your objects by defining a region using objects you
previously identified in your pipeline (*%(MC_OBJECTS)s*) or by
defining a region based on the white regions in a binary image
previously loaded or created in your pipeline (*%(MC_IMAGE)s*).
""" % globals())

        self.masking_objects = cps.ObjectNameSubscriber(
            "Select the masking object",
            cps.NONE,
            doc="""\
*(Used only if mask is to be made from objects)*

Select the objects that will be used to define the masking region. You
can choose from any objects created by a previous object processing
module, such as **IdentifyPrimaryObjects**,
**IdentifySecondaryObjects**, or **IdentifyTertiaryObjects**.
""")

        self.masking_image = cps.ImageNameSubscriber(
            "Select the masking image",
            cps.NONE,
            doc="""\
*(Used only if mask is to be made from an image)*

Select an image that was either loaded or created by a previous module.
The image should be a binary image where the white portion of the image
is the region(s) you will use for masking. Binary images can be loaded
from disk using the **NamesAndTypes** module by selecting “Binary mask”
for the image type. You can also create a binary image from a grayscale
image using **ApplyThreshold**.
""")

        self.wants_inverted_mask = cps.Binary("Invert the mask?",
                                              False,
                                              doc="""\
This option reverses the foreground/background relationship of the mask.

-  Select "*%(NO)s*" for the mask to be composed of the foreground (white
   portion) of the masking image or the area within the masking objects.
-  Select "*%(YES)s*" for the mask to instead be composed of the
   *background* (black portions) of the masking image or the area
   *outside* the masking objects.
   """ % globals())

        self.overlap_choice = cps.Choice(
            "Handling of objects that are partially masked",
            [P_MASK, P_KEEP, P_REMOVE, P_REMOVE_PERCENTAGE],
            doc="""\
An object might partially overlap the mask region, with pixels both
inside and outside the region. **MaskObjects** can handle this in one
of three ways:

-  *%(P_MASK)s:* Choosing this option will reduce the size of partially
   overlapping objects. The part of the object that overlaps the masking
   region will be retained. The part of the object that is outside of the
   masking region will be removed.
-  *%(P_KEEP)s:* If you choose this option, **MaskObjects** will keep
   the whole object if any part of it overlaps the masking region.
-  *%(P_REMOVE)s:* Objects that are partially outside of the masking
   region will be completely removed if you choose this option.
-  *%(P_REMOVE_PERCENTAGE)s:* Determine whether to remove or keep an
   object depending on how much of the object overlaps the masking
   region. **MaskObjects** will keep an object if at least a certain
   fraction (which you enter below) of the object falls within the
   masking region. **MaskObjects** completely removes the object if too
   little of it overlaps the masking region.""" % globals())

        self.overlap_fraction = cps.Float(
            "Fraction of object that must overlap",
            .5,
            minval=0,
            maxval=1,
            doc="""\
*(Used only if removing based on overlap)*

Specify the minimum fraction of an object that must overlap the masking
region for that object to be retained. For instance, if the fraction is
0.75, then 3/4 of an object must be within the masking region for that
object to be retained.
""")

        self.retain_or_renumber = cps.Choice("Numbering of resulting objects",
                                             [R_RENUMBER, R_RETAIN],
                                             doc="""\
Choose how to number the objects that remain after masking, which
controls how remaining objects are associated with their predecessors:

-  *%(R_RENUMBER)s:* The objects that remain will be renumbered using
   consecutive numbers. This is a good choice if you do not plan to use
   measurements from the original objects; your object measurements for
   the masked objects will not have gaps (where removed objects are
   missing).
-  *%(R_RETAIN)s:* The original labels for the objects will be
   retained. This allows any measurements you make from the masked
   objects to be directly aligned with measurements you might have made
   of the original, unmasked objects (or objects directly associated
   with them).
""" % globals())
Exemple #28
0
    def create_settings(self):
        self.x_object = cps.ObjectNameSubscriber(
            'Select the object to display on the X-axis',
            cps.NONE,
            doc='''\
Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) 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,
            cps.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',
            cps.NONE,
            doc='''\
Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) 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,
            cps.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 *linear* scale or with a *log*
(base 10) scaling.

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.
''')

        self.yscale = cps.Choice('How should the Y-axis be scaled?',
                                 ['linear', 'log'],
                                 None,
                                 doc='''\
The Y-axis can be scaled either with a *linear* scale or with a *log*
(base 10) scaling.

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.
''')

        self.bins = cps.Choice('How should the colorbar be scaled?',
                               ['linear', 'log'],
                               None,
                               doc='''\
The colorbar can be scaled either with a *linear* scale or with a *log*
(base 10) scaling.

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 page`_ for pictures
of the available colormaps.

.. _this page: http://matplotlib.org/users/colormaps.html
''')

        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 *(cycle N)* where *N* is the current image cycle being
executed.
''')
Exemple #29
0
    def create_settings(self):
        """Create your settings by subclassing this function

        create_settings is called at the end of initialization.
        """
        self.grid_image = cps.GridNameProvider("Name the grid",
                                               doc="""\
This is the name of the grid. You can use this name to
retrieve the grid in subsequent modules.""")

        self.grid_rows = cps.Integer(
            "Number of rows",
            8,
            1,
            doc="""Along the height of the grid, define the number of rows""")

        self.grid_columns = cps.Integer(
            "Number of columns",
            12,
            1,
            doc="""Along the width of the grid, define the number of columns"""
        )

        self.origin = cps.Choice(
            "Location of the first spot",
            [NUM_TOP_LEFT, NUM_BOTTOM_LEFT, NUM_TOP_RIGHT, NUM_BOTTOM_RIGHT],
            doc="""\
Grid cells are numbered consecutively; this option identifies the
origin for the numbering system and the direction for numbering.
For instance, if you choose "*%(NUM_TOP_LEFT)s*", the top left cell is
cell #1 and cells to the right and bottom are indexed with
larger numbers.""" % globals())

        self.ordering = cps.Choice("Order of the spots",
                                   [NUM_BY_ROWS, NUM_BY_COLUMNS],
                                   doc="""\
Grid cells can either be numbered by rows, then columns or by columns,
then rows. For instance, you might ask to start numbering a 96-well
plate at the top left (by specifying the location of the first spot).

-  *%(NUM_BY_ROWS)s:* This option will give well A01 the index 1, B01
   the index 2, and so on up to H01 which receives the index 8. Well A02
   will be assigned the index 9.
-  *%(NUM_BY_COLUMNS)s:* With this option, the well A02 will be
   assigned 2, well A12 will be assigned 12 and well B01 will be
   assigned 13.
""" % globals())

        self.each_or_once = cps.Choice("Define a grid for which cycle?",
                                       [EO_EACH, EO_ONCE],
                                       doc="""\
The setting allows you choose when you want to define a new grid:

-  *%(EO_ONCE)s:* If all of your images are perfectly aligned with each
   other (due to very consistent image acquisition, consistent grid
   location within the plate, and/or automatic cropping precisely within
   each plate), you can define the location of the marker spots once for
   all of the image cycles.
-  *%(EO_EACH)s:* If the location of the grid will vary from one image
   cycle to the next then you should define the location of the marker
   spots for each cycle independently.
""" % globals())

        self.auto_or_manual = cps.Choice(
            "Select the method to define the grid", [AM_AUTOMATIC, AM_MANUAL],
            doc="""\
Select whether you would like to define the grid automatically (based on
objects you have identified in a previous module) or manually. This
setting controls how the grid is defined:

-  *%(AM_MANUAL)s:* In manual mode, you manually indicate known
   locations of marker spots in the grid and have the rest of the
   positions calculated from those marks, no matter what the image
   itself looks like. You can define the grid either by clicking on the
   image with a mouse or by entering coordinates.
-  *%(AM_AUTOMATIC)s:* If you would like the grid to be defined
   automatically, an **IdentifyPrimaryObjects** module must be run prior
   to this module to identify the objects which will be used to define
   the grid. The left-most, right-most, top-most, and bottom-most object
   will be used to define the edges of the grid, and the rows and
   columns will be evenly spaced between these edges. Note that
   Automatic mode requires that the incoming objects are nicely defined:
   for example, if there is an object at the edge of the images that is
   not really an object that ought to be in the grid, a skewed grid will
   result. You might wish to use a **FilterObjects** module to clean up
   badly identified objects prior to defining the grid. If the spots are
   slightly out of alignment with each other from one image cycle to the
   next, this allows the identification to be a bit flexible and adapt
   to the real location of the spots.
""" % globals())

        self.object_name = cps.ObjectNameSubscriber(
            "Select the previously identified objects",
            cps.NONE,
            doc="""\
*(Used only if you selected "%(AM_AUTOMATIC)s" to define the grid)*

Select the previously identified objects you want to use to define the
grid. Use this setting to specify the name of the objects that will be
used to define the grid.
""" % globals())

        self.manual_choice = cps.Choice(
            "Select the method to define the grid manually",
            [MAN_MOUSE, MAN_COORDINATES],
            doc="""\
*(Used only if you selected "%(AM_MANUAL)s" to define the grid)*

Specify whether you want to define the grid using the mouse or by
entering the coordinates of the cells.

-  *%(MAN_MOUSE)s:* The user interface displays the image you specify.
   You will be asked to click in the center of two of the grid cells and
   specify the row and column for each. The grid coordinates will be
   computed from this information.
-  *%(MAN_COORDINATES)s:* Enter the X and Y coordinates of the grid
   cells directly. You can display an image of your grid to find the
   locations of the centers of the cells, then enter the X and Y
   position and cell coordinates for each of two cells.
""" % globals())

        self.manual_image = cps.ImageNameSubscriber(
            "Select the image to display",
            cps.NONE,
            doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_MOUSE)s" to define
the grid)*

Specify the image you want to display when defining the grid. This
setting lets you choose the image to display in the grid definition user
interface.
""" % globals())

        self.first_spot_coordinates = cps.Coordinates(
            "Coordinates of the first cell", (0, 0),
            doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

Enter the coordinates of the first cell on your grid. This setting
defines the location of the first of two cells in your grid. You should
enter the coordinates of the center of the cell. You can display an
image of your grid and use the pixel coordinate display to determine the
coordinates of the center of your cell.
""" % globals())

        self.first_spot_row = cps.Integer("Row number of the first cell",
                                          1,
                                          minval=1,
                                          doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

Enter the row index for the first cell here. Rows are numbered starting
at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your
origin, well A01 will be row number 1 and H01 will be row number 8. If
you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will
be row number 12.
""" % globals())

        self.first_spot_col = cps.Integer("Column number of the first cell",
                                          1,
                                          minval=1,
                                          doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

Enter the column index for the first cell here. Columns are numbered
starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*"
as your origin, well A01 will be column number *1* and A12 will be
column number *12*. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will
be *12* and *1*, respectively.
""" % globals())

        self.second_spot_coordinates = cps.Coordinates(
            "Coordinates of the second cell", (0, 0),
            doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

This setting defines the location of the second of two cells in your
grid. You should enter the coordinates of the center of the cell. You
can display an image of your grid and use use the pixel coordinate
display to determine the coordinates of the center of your cell.
""" % globals())

        self.second_spot_row = cps.Integer("Row number of the second cell",
                                           1,
                                           minval=1,
                                           doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

Enter the row index for the second cell here. Rows are numbered starting
at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your
origin, well A01 will be row number 1 and H01 will be row number 8. If
you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will
be row number 12.
""" % globals())

        self.second_spot_col = cps.Integer("Column number of the second cell",
                                           1,
                                           minval=1,
                                           doc="""\
*(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to
define the grid)*

Enter the column index for the second cell here. Columns are numbered
starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*"
as your origin, well A01 will be column number 1 and A12 will be column
number 12. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will be 12
and 1, respectively.
""" % globals())

        self.wants_image = cps.Binary("Retain an image of the grid?",
                                      False,
                                      doc="""\
Select "*%(YES)s*" to retain an image of the grid for use later in the
pipeline. This module can create an annotated image of the grid that can
be saved using the **SaveImages** module.
""" % globals())

        self.display_image_name = cps.ImageNameSubscriber(
            "Select the image on which to display the grid",
            cps.LEAVE_BLANK,
            can_be_blank=True,
            doc="""\
*(Used only if saving an image of the grid)*

Enter the name of the image that should be used as the background for
annotations (grid lines and grid indexes). This image will be used for
the figure and for the saved image.
""")

        self.save_image_name = cps.ImageNameProvider("Name the output image",
                                                     "Grid",
                                                     doc="""\
*(Used only if retaining an image of the grid for use later in the
pipeline)*

Enter the name you want to use for the output image. You can save this
image using the **SaveImages** module.
""")

        self.failed_grid_choice = cps.Choice(
            "Use a previous grid if gridding fails?",
            [FAIL_NO, FAIL_ANY_PREVIOUS, FAIL_FIRST],
            doc="""\
If the gridding fails, this setting allows you to control how the module
responds to the error:

-  *%(FAIL_NO)s:* The module will stop the pipeline if gridding fails.
-  *%(FAIL_ANY_PREVIOUS)s:*: The module will use the the most recent
   successful gridding.
-  *%(FAIL_FIRST)s:* The module will use the first gridding.

Note that the pipeline will stop in all cases if gridding fails on the
first image.
""" % globals())
    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.object_name = cps.ObjectNameSubscriber(
            "Select the objects to be edited",
            cps.NONE,
            doc="""\
Choose a set of previously identified objects
for editing, such as those produced by one of the
**Identify** modules (e.g., "*IdentifyPrimaryObjects*", "*IdentifySecondaryObjects*" etc.).""",
        )

        self.filtered_objects = cps.ObjectNameProvider(
            "Name the edited objects",
            "EditedObjects",
            doc="""\
Enter the name for the objects that remain
after editing. These objects will be available for use by
subsequent modules.""",
        )

        self.allow_overlap = cps.Binary(
            "Allow overlapping objects?",
            False,
            doc="""\
**EditObjectsManually** can allow you to edit an object so that it
overlaps another or it can prevent you from overlapping one object with
another. Objects such as worms or the neurites of neurons may cross each
other and might need to be edited with overlapping allowed, whereas a
monolayer of cells might be best edited with overlapping off.
Select "*Yes*" to allow overlaps or select "*No*" to prevent them.
""" % globals(),
        )

        self.renumber_choice = cps.Choice(
            "Numbering of the edited objects",
            [R_RENUMBER, R_RETAIN],
            doc="""\
Choose how to number the objects that remain after editing, which
controls how edited objects are associated with their predecessors:

-  *%(R_RENUMBER)s:* The module will number the objects that remain
   using consecutive numbers. This is a good choice if you do not plan
   to use measurements from the original objects and you only want to
   use the edited objects in downstream modules; the objects that remain
   after editing will not have gaps in numbering where removed objects
   are missing.
-  *%(R_RETAIN)s:* This option will retain each object’s original
   number so that the edited object’s number matches its original
   number. This allows any measurements you make from the edited objects
   to be directly aligned with measurements you might have made of the
   original, unedited objects (or objects directly associated with
   them).
""" % globals(),
        )

        self.wants_image_display = cps.Binary(
            "Display a guiding image?",
            True,
            doc="""\
Select "*Yes*" to display an image and outlines of the objects.

Select "*No*" if you do not want a guide image while editing.
""" % globals(),
        )

        self.image_name = cps.ImageNameSubscriber(
            "Select the guiding image",
            cps.NONE,
            doc="""\
*(Used only if a guiding image is desired)*

This is the image that will appear when editing objects. Choose an image
supplied by a previous module.
""",
        )