def create_settings(self):
        self.outputs = []
        self.stain_count = HiddenCount(self.outputs, "Stain count")

        self.input_image_name = ImageSubscriber(
            "Select the input color image",
            "None",
            doc="""\
Choose the name of the histologically stained color image
loaded or created by some prior module.""",
        )

        self.add_image(False)

        self.add_image_button = DoSomething(
            "",
            "Add another stain",
            self.add_image,
            doc="""\
Press this button to add another stain to the list.

You will be able to name the image produced and to either pick
the stain from a list of pre-calibrated stains or to enter
custom values for the stain's red, green and blue absorbance.
            """,
        )
Beispiel #2
0
    def create_settings(self):
        self.flags = []
        self.flag_count = HiddenCount(self.flags)
        self.add_flag_button = DoSomething("", "Add another flag",
                                           self.add_flag)
        self.spacer_1 = Divider()
        self.add_flag(can_delete=False)
        self.ignore_flag_on_last = Binary(
            "Ignore flag skips on last cycle?",
            False,
            doc="""\
When set to *{YES}*, this option allows you to bypass skipping on the last
cycle of an image group.  This behavior is usually not desired, but may be 
useful when using SaveImages 'Save on last cycle' option for an image made
by any other module than MakeProjection, CorrectIlluminationCalculate, and Tile.
""".format(**{"YES": "Yes"}),
        )
Beispiel #3
0
    def create_settings(self):
        self.scheme_choice = Choice(
            "Select a color scheme",
            [SCHEME_RGB, SCHEME_CMYK, SCHEME_STACK, SCHEME_COMPOSITE],
            doc="""\
This module can use one of two color schemes to combine images:

-  *%(SCHEME_RGB)s*: Each input image determines the intensity of one
   of the color channels: red, green, and blue.
-  *%(SCHEME_CMYK)s*: Three of the input images are combined to
   determine the colors (cyan, magenta, and yellow) and a fourth is used
   only for brightness. The cyan image adds equally to the green and
   blue intensities. The magenta image adds equally to the red and blue
   intensities. The yellow image adds equally to the red and green
   intensities.
-  *%(SCHEME_STACK)s*: The channels are stacked in the order listed,
   from top to bottom. An arbitrary number of channels is allowed.

   For example, you could create a 5-channel image by providing
   5 grayscale images. The first grayscale image you provide will fill
   the first channel, the second grayscale image you provide will fill
   the second channel, and so on.
-  *%(SCHEME_COMPOSITE)s*: A color is assigned to each grayscale image.
   Each grayscale image is converted to color by multiplying the
   intensity by the color and the resulting color images are added
   together. An arbitrary number of channels can be composited into a
   single color image.
"""
            % globals(),
        )

        self.wants_rescale = Binary(
            "Rescale intensity",
            True,
            doc="""\
Choose whether to rescale each channel individually to 
the range of 0-1. This prevents clipping of channels with intensity 
above 1 and can help to balance the brightness of the different channels. 
This option also ensures that channels occupy the full intensity range 
available, which is useful for displaying images in other software.

This rescaling is applied before any multiplication factors set in this 
module's options. Using a multiplication factor >1 would therefore result 
in clipping."""
        )

        # # # # # # # # # # # # # # # #
        #
        # RGB settings
        #
        # # # # # # # # # # # # # # # #
        self.red_image_name = ImageSubscriber(
            "Select the image to be colored red",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Select the input image to be displayed in red.
"""
            % globals(),
        )

        self.green_image_name = ImageSubscriber(
            "Select the image to be colored green",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Select the input image to be displayed in green.
"""
            % globals(),
        )

        self.blue_image_name = ImageSubscriber(
            "Select the image to be colored blue",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Select the input image to be displayed in blue.
"""
            % globals(),
        )

        self.rgb_image_name = ImageName(
            "Name the output image",
            "ColorImage",
            doc="""Enter a name for the resulting image.""",
        )

        self.red_adjustment_factor = Float(
            "Relative weight for the red image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Enter the relative weight for the red image. If all relative weights are
equal, all three colors contribute equally in the final image. To weight
colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        self.green_adjustment_factor = Float(
            "Relative weight for the green image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Enter the relative weight for the green image. If all relative weights
are equal, all three colors contribute equally in the final image. To
weight colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        self.blue_adjustment_factor = Float(
            "Relative weight for the blue image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)*

Enter the relative weight for the blue image. If all relative weights
are equal, all three colors contribute equally in the final image. To
weight colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )
        # # # # # # # # # # # # # #
        #
        # CYMK settings
        #
        # # # # # # # # # # # # # #
        self.cyan_image_name = ImageSubscriber(
            "Select the image to be colored cyan",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Select the input image to be displayed in cyan.
"""
            % globals(),
        )

        self.magenta_image_name = ImageSubscriber(
            "Select the image to be colored magenta",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Select the input image to be displayed in magenta.
"""
            % globals(),
        )

        self.yellow_image_name = ImageSubscriber(
            "Select the image to be colored yellow",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Select the input image to be displayed in yellow.
"""
            % globals(),
        )

        self.gray_image_name = ImageSubscriber(
            "Select the image that determines brightness",
            can_be_blank=True,
            blank_text=LEAVE_THIS_BLACK,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Select the input image that will determine each pixel's brightness.
"""
            % globals(),
        )

        self.cyan_adjustment_factor = Float(
            "Relative weight for the cyan image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Enter the relative weight for the cyan image. If all relative weights
are equal, all colors contribute equally in the final image. To weight
colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        self.magenta_adjustment_factor = Float(
            "Relative weight for the magenta image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Enter the relative weight for the magenta image. If all relative weights
are equal, all colors contribute equally in the final image. To weight
colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        self.yellow_adjustment_factor = Float(
            "Relative weight for the yellow image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Enter the relative weight for the yellow image. If all relative weights
are equal, all colors contribute equally in the final image. To weight
colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        self.gray_adjustment_factor = Float(
            "Relative weight for the brightness image",
            value=1,
            minval=0,
            doc="""\
*(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)*

Enter the relative weight for the brightness image. If all relative
weights are equal, all colors contribute equally in the final image. To
weight colors relative to each other, increase or decrease the relative
weights.
"""
            % globals(),
        )

        # # # # # # # # # # # # # #
        #
        # Stack settings
        #
        # # # # # # # # # # # # # #

        self.stack_channels = []
        self.stack_channel_count = HiddenCount(self.stack_channels)
        self.add_stack_channel_cb(can_remove=False)
        self.add_stack_channel = DoSomething(
            "Add another channel",
            "Add another channel",
            self.add_stack_channel_cb,
            doc="""\
    Press this button to add another image to the stack.
    """,
        )
Beispiel #4
0
    def create_settings(self):
        self.images_list = ImageListSubscriber(
            "Select images to measure",
            [],
            doc=
            """Select the grayscale images whose intensity you want to measure.""",
        )

        self.objects_list = LabelListSubscriber(
            "Select objects to measure",
            [],
            doc="""\
        Select 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.

        Objects specified here will have their texture measured against *all*
        images specified above, which may lead to image-object combinations that
        are unnecessary. If you do not want this behavior, use multiple
        **MeasureTexture** modules to specify the particular image-object
        measures that you want.
        """,
        )

        self.gray_levels = Integer(
            "Enter how many gray levels to measure the texture at",
            256,
            2,
            256,
            doc="""\
        Enter the number of gray levels (ie, total possible values of intensity) 
        you want to measure texture at.  Measuring at more levels gives you 
        _potentially_ more detailed information about your image, but at the cost
        of somewhat decreased processing speed.  

        Before processing, your image will be rescaled from its current pixel values
        to 0 - [gray levels - 1]. The texture features will then be calculated. 

        In all CellProfiler 2 versions, this value was fixed at 8; in all 
        CellProfiler 3 versions it was fixed at 256.  The minimum number of levels is
        2, the maximum is 256.
        """,
        )

        self.scale_groups = []

        self.scale_count = HiddenCount(self.scale_groups)

        self.image_divider = Divider()

        self.object_divider = Divider()

        self.add_scale(removable=False)

        self.add_scales = DoSomething(
            callback=self.add_scale,
            label="Add another scale",
            text="",
            doc="""\
            Add an additional texture scale to measure. Useful when you
            want to measure texture features of different sizes.
            """,
        )

        self.images_or_objects = Choice(
            "Measure whole images or objects?",
            [IO_IMAGES, IO_OBJECTS, IO_BOTH],
            value=IO_BOTH,
            doc="""\
This setting determines whether the module computes image-wide
measurements, per-object measurements or both.

-  *{IO_IMAGES}:* Select if you only want to measure the texture
   across entire images.
-  *{IO_OBJECTS}:* Select if you want to measure the texture
   on a per-object basis only.
-  *{IO_BOTH}:* Select to make both image and object measurements.
""".format(
                **{
                    "IO_IMAGES": IO_IMAGES,
                    "IO_OBJECTS": IO_OBJECTS,
                    "IO_BOTH": IO_BOTH
                }),
        )
Beispiel #5
0
    def create_settings(self):
        super(Resize, self).create_settings()

        self.size_method = Choice(
            "Resizing method",
            R_ALL,
            doc="""\
The following options are available:

-  *Resize by a fraction or multiple of the original size:* Enter a single value which specifies the scaling.
-  *Resize by specifying desired final dimensions:* Enter the new height and width of the resized image, in units of pixels.""",
        )

        self.resizing_factor = Float(
            "Resizing factor",
            0.25,
            minval=0,
            doc="""\
*(Used only if resizing by a fraction or multiple of the original size)*

Numbers less than one (that is, fractions) will shrink the image;
numbers greater than one (that is, multiples) will enlarge the image.""",
        )

        self.use_manual_or_image = Choice(
            "Method to specify the dimensions",
            C_ALL,
            doc="""\
*(Used only if resizing by specifying the dimensions)*

You have two options on how to resize your image:

-  *{C_MANUAL}:* Specify the height and width of the output image.
-  *{C_IMAGE}:* Specify an image and the input image will be resized to the same dimensions.
            """.format(
                **{"C_IMAGE": C_IMAGE, "C_MANUAL": C_MANUAL}
            ),
        )

        self.specific_width = Integer(
            "Width of the final image",
            100,
            minval=1,
            doc="""\
*(Used only if resizing by specifying desired final dimensions)*

Enter the desired width of the final image, in pixels.""",
        )

        self.specific_height = Integer(
            "Height of the final image",
            100,
            minval=1,
            doc="""\
*(Used only if resizing by specifying desired final dimensions)*

Enter the desired height of the final image, in pixels.""",
        )

        self.specific_image = ImageSubscriber(
            "Select the image with the desired dimensions",
            "None",
            doc="""\
*(Used only if resizing by specifying desired final dimensions using an image)*

The input image will be resized to the dimensions of the specified image.""",
        )

        self.interpolation = Choice(
            "Interpolation method",
            I_ALL,
            doc="""\
-  *Nearest Neighbor:* Each output pixel is given the intensity of the
   nearest corresponding pixel in the input image.
-  *Bilinear:* Each output pixel is given the intensity of the weighted
   average of the 2x2 neighborhood at the corresponding position in the
   input image.
-  *Bicubic:* Each output pixel is given the intensity of the weighted
   average of the 4x4 neighborhood at the corresponding position in the
   input image.""",
        )

        self.separator = Divider(line=False)

        self.additional_images = []

        self.additional_image_count = HiddenCount(
            self.additional_images, "Additional image count"
        )

        self.add_button = DoSomething("", "Add another image", self.add_image)
Beispiel #6
0
    def add_flag(self, can_delete=True):
        group = SettingsGroup()
        group.append("divider1", Divider(line=False))
        group.append("measurement_settings", [])
        group.append("measurement_count",
                     HiddenCount(group.measurement_settings))
        group.append(
            "category",
            Text(
                "Name the flag's category",
                "Metadata",
                doc="""\
Name a measurement category by which to categorize the flag. The
*Metadata* category is the default used in CellProfiler to store
information about images (referred to as *metadata*).

The flag is stored as a per-image measurement whose name is a
combination of the flag’s category and the flag name that you choose, separated by
underscores. For instance, if the measurement category is *Metadata* and
the flag name is *QCFlag*, then the default measurement name would be
*Metadata_QCFlag*.
""",
            ),
        )

        group.append(
            "feature_name",
            Text(
                "Name the flag",
                "QCFlag",
                doc="""\
The flag is stored as a per-image measurement whose name is a
combination of the flag’s category and the flag name that you choose, separated by
underscores. For instance, if the measurement category is *Metadata* and
the flag name is *QCFlag*, then the default measurement name would be
*Metadata_QCFlag*.
""",
            ),
        )

        group.append(
            "combination_choice",
            Choice(
                "How should measurements be linked?",
                [C_ANY, C_ALL],
                doc="""\
For combinations of measurements, you can set the criteria under which
an image set is flagged:

-  *%(C_ANY)s:* An image set will be flagged if any of its measurements
   fail. This can be useful for flagging images possessing multiple QC
   flaws; for example, you can flag all bright images and all out of
   focus images with one flag.
-  *%(C_ALL)s:* A flag will only be assigned if all measurements fail.
   This can be useful for flagging images that possess only a
   combination of QC flaws; for example, you can flag only images that
   are both bright and out of focus.
""" % globals(),
            ),
        )

        group.append(
            "wants_skip",
            Binary(
                "Skip image set if flagged?",
                False,
                doc="""\
Select *Yes* to skip the remainder of the pipeline for image sets
that are flagged. CellProfiler will not run subsequent modules in the
pipeline on the images for any image set that is flagged. Select *No*
for CellProfiler to continue to process the pipeline regardless of
flagging.

You may want to skip processing in order to filter out unwanted images.
For instance, you may want to exclude out of focus images when running
**CorrectIllumination_Calculate**. You can do this with a pipeline that
measures image quality and flags inappropriate images before it runs
**CorrectIllumination_Calculate**.
""" % globals(),
            ),
        )

        group.append(
            "add_measurement_button",
            DoSomething(
                "",
                "Add another measurement",
                self.add_measurement,
                group,
                doc="""Add another measurement as a criteria.""",
            ),
        )
        self.add_measurement(group, False if not can_delete else True)
        if can_delete:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this flag", self.flags, group),
            )
        group.append("divider2", Divider(line=True))
        self.flags.append(group)
    def create_settings(self):
        self.images_list = ImageListSubscriber(
            "Select images to measure",
            [],
            doc=
            """Select the grayscale images whose intensity you want to measure.""",
        )

        self.objects_list = LabelListSubscriber(
            "Select objects to measure",
            [],
            doc="""\
        Select 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.

        Objects specified here will have their texture measured against *all*
        images specified above, which may lead to image-object combinations that
        are unnecessary. If you do not want this behavior, use multiple
        **MeasureTexture** modules to specify the particular image-object
        measures that you want.
        """,
        )

        self.scale_groups = []

        self.scale_count = HiddenCount(self.scale_groups)

        self.image_divider = Divider()

        self.object_divider = Divider()

        self.add_scale(removable=False)

        self.add_scales = DoSomething(
            callback=self.add_scale,
            label="Add another scale",
            text="",
            doc="""\
            Add an additional texture scale to measure. Useful when you
            want to measure texture features of different sizes.
            """,
        )

        self.images_or_objects = Choice(
            "Measure whole images or objects?",
            [IO_IMAGES, IO_OBJECTS, IO_BOTH],
            value=IO_BOTH,
            doc="""\
This setting determines whether the module computes image-wide
measurements, per-object measurements or both.

-  *{IO_IMAGES}:* Select if you only want to measure the texture
   across entire images.
-  *{IO_OBJECTS}:* Select if you want to measure the texture
   on a per-object basis only.
-  *{IO_BOTH}:* Select to make both image and object measurements.
""".format(
                **{
                    "IO_IMAGES": IO_IMAGES,
                    "IO_OBJECTS": IO_OBJECTS,
                    "IO_BOTH": IO_BOTH
                }),
        )
Beispiel #8
0
    def create_settings(self):
        module_explanation = [
            "The" + self.module_name + "module allows you to run any supported ImageJ script as part of your workflow.",
            "First, select your desired initialization method and specify the app directory or endpoint(s) if needed.",
            "Then select a script file to be executed by this module.",
            "Click the \"Get parameters from script\" button to detect required inputs for your script:",
            "each input will have its own setting created, allowing you to pass data from CellProfiler to ImageJ.",
            "After filling in any required inputs you can run the module normally.",
            "Note: ImageJ will only be initialized once per CellProfiler session.",
            "Note: only numeric, text and image parameters are currently supported.",
            "See also ImageJ Scripting: https://imagej.net/Scripting."

        ]
        self.set_notes([" ".join(module_explanation)])

        self.init_choice = Choice(
            "Initialization type", [INIT_LOCAL, INIT_ENDPOINT, INIT_LATEST],
            tooltips={INIT_LOCAL: "Use a local ImageJ/Fiji installation", INIT_ENDPOINT: "Specify a particular endpoint",
                      INIT_LATEST: "Use the latest Fiji, downloading if needed."},
            doc="""\
Note that initialization will only occur once per CellProfiler session! After initialization, these options will be
locked for the remainder of the session.

Select the mechanism for initializing ImageJ:
 * {init_local}: Use a local Fiji or ImageJ installation
 * {init_endpoint}: Precisely specify the version of one or more components
 * {init_latest}: Use the latest Fiji version

Note that any option besides {init_local} may result in a download of the requested components.
            """.format(
                init_local=INIT_LOCAL,
                init_endpoint=INIT_ENDPOINT,
                init_latest=INIT_LATEST,
            ),
        )

        self.endpoint_string = Text(
            "Initialization endpoint", "sc.fiji:fiji:2.1.0", doc="""\
Specify an initialization string as described in https://github.com/imagej/pyimagej/blob/master/doc/Initialization.md
            """,
        )

        self.initialized_method = Text("Initialization type", value="Do not use", doc="""\
Indicates the method that was used to initialized ImageJ in this CellProfiler session. 
            """,
        )

        self.convert_types = Binary("Adjust image type?", True, doc="""\
If enabled, ensures images are always converted to unsigned integer types when sent to ImageJ, and back to signed float types when returned to CellProfiler.
This can help common display issues by providing each application a best guess at its "expected" data type.
If you choose to disable this function, your ImageJ script will need to account for images coming in as signed float types.
            """,
        )

        global init_display_string
        if init_display_string:
            # ImageJ thread is already running
            self.initialized_method.set_value(init_display_string)

        self.app_directory = Directory(
            "ImageJ directory", allow_metadata=False, doc="""\
Select the folder containing the desired ImageJ/Fiji application.

{fcht}
""".format(
                fcht=IO_FOLDER_CHOICE_HELP_TEXT
            ),
        )
        if platform != 'darwin':
            self.app_directory.join_parts(ABSOLUTE_FOLDER_NAME, "Fiji.app")

        def set_directory_fn_app(path):
            dir_choice, custom_path = self.app_directory.get_parts_from_path(path)
            self.app_directory.join_parts(dir_choice, custom_path)

        self.app_file = Filename(
            "Local App", "Fiji.app", doc="Select the desired app, such as Fiji.app",
            get_directory_fn=self.app_directory.get_absolute_path,
            set_directory_fn=set_directory_fn_app,
            browse_msg="Choose local application"
        )

        self.script_directory = Directory(
            "Script directory",
            allow_metadata=False,
            doc="""\
Select the folder containing the script.

{fcht}
""".format(
                fcht=IO_FOLDER_CHOICE_HELP_TEXT
            ),
        )

        def set_directory_fn_script(script_path):
            dir_choice, custom_path = self.script_directory.get_parts_from_path(script_path)
            self.script_directory.join_parts(dir_choice, custom_path)
            self.clear_script_parameters()

        self.script_file = Filename(
            "ImageJ Script", "script.py", doc="Select a script file written in any ImageJ-supported scripting language.",
            get_directory_fn=self.script_directory.get_absolute_path,
            set_directory_fn=set_directory_fn_script,
            browse_msg="Choose ImageJ script file",
        )
        self.get_parameters_button = DoSomething("", 'Get parameters from script',
                                                 self.get_parameters_helper,
                                                 doc="""\
Parse parameters from the currently selected script and add the appropriate settings to this CellProfiler module.

Note: this must be done each time you change the script, before running the CellProfiler pipeline!
"""
                                                 )
        self.script_parameter_list = []
        self.script_input_settings = {}  # Map of input parameter names to CellProfiler settings objects
        self.script_output_settings = {}  # Map of output parameter names to CellProfiler settings objects
        self.script_parameter_count = HiddenCount(self.script_parameter_list)
Beispiel #9
0
    def create_settings(self):
        self.image_name = ImageSubscriber(
            "Select the input image",
            "None",
            doc="""Select the multichannel image you want to convert to grayscale.""",
        )

        self.combine_or_split = Choice(
            "Conversion method",
            [COMBINE, SPLIT],
            doc="""\
How do you want to convert the color image?

-  *%(SPLIT)s:* Splits the channels of a color
   image (e.g., red, green, blue) into separate grayscale images.
-  *%(COMBINE)s:* Converts a color image to a grayscale image by
   combining channels together (e.g., red, green, blue)."""
            % globals(),
        )

        self.rgb_or_channels = Choice(
            "Image type",
            [CH_RGB, CH_HSV, CH_CHANNELS],
            doc="""\
This setting provides three options to choose from:

-  *%(CH_RGB)s:* The RGB (red, green, blue) color space is the typical
   model in which color images are stored. Choosing this option will
   split the image into red, green, and blue component images.
-  *%(CH_HSV)s:* The HSV (hue, saturation, value) color space is based
   on color characteristics such as tint, shade, and tone.
   Choosing this option will split the image into the hue,
   saturation, and value component images.
-  *%(CH_CHANNELS)s:* Many images contain color channels other than RGB
   or HSV. For instance, GIF and PNG formats can have an alpha
   channel that encodes transparency. TIF formats can have an arbitrary
   number of channels which represent pixel measurements made by
   different detectors, filters or lighting conditions. This setting
   allows you to handle a more complex model for images that
   have more than three channels."""
            % globals(),
        )

        # The following settings are used for the combine option
        self.grayscale_name = ImageName(
            "Name the output image",
            "OrigGray",
            doc="""\
*(Used only when combining channels)*

Enter a name for the resulting grayscale image.""",
        )

        self.red_contribution = Float(
            "Relative weight of the red channel",
            1,
            0,
            doc="""\
*(Used only when combining channels)*

Relative weights: If all relative weights are equal, all three colors
contribute equally in the final image. To weight colors relative to each
other, increase or decrease the relative weights.""",
        )

        self.green_contribution = Float(
            "Relative weight of the green channel",
            1,
            0,
            doc="""\
*(Used only when combining channels)*

Relative weights: If all relative weights are equal, all three colors
contribute equally in the final image. To weight colors relative to each
other, increase or decrease the relative weights.""",
        )

        self.blue_contribution = Float(
            "Relative weight of the blue channel",
            1,
            0,
            doc="""\
*(Used only when combining channels)*

Relative weights: If all relative weights are equal, all three colors
contribute equally in the final image. To weight colors relative to each
other, increase or decrease the relative weights.""",
        )

        # The following settings are used for the split RGB option
        self.use_red = Binary(
            "Convert red to gray?",
            True,
            doc="""\
*(Used only when splitting RGB images)*

Select *"Yes"* to extract the red channel to grayscale. Otherwise, the
red channel will be ignored.
"""
            % globals(),
        )

        self.red_name = ImageName(
            "Name the output image",
            "OrigRed",
            doc="""\
*(Used only when splitting RGB images)*

Enter a name for the resulting grayscale image coming from the red channel.""",
        )

        self.use_green = Binary(
            "Convert green to gray?",
            True,
            doc="""\
*(Used only when splitting RGB images)*

Select *"Yes"* to extract the green channel to grayscale. Otherwise, the
green channel will be ignored.
"""
            % globals(),
        )

        self.green_name = ImageName(
            "Name the output image",
            "OrigGreen",
            doc="""\
*(Used only when splitting RGB images)*

Enter a name for the resulting grayscale image coming from the green channel.""",
        )

        self.use_blue = Binary(
            "Convert blue to gray?",
            True,
            doc="""\
*(Used only when splitting RGB images)*

Select *"Yes"* to extract the blue channel to grayscale. Otherwise, the
blue channel will be ignored.
"""
            % globals(),
        )

        self.blue_name = ImageName(
            "Name the output image",
            "OrigBlue",
            doc="""\
*(Used only when splitting RGB images)*

Enter a name for the resulting grayscale image coming from the blue channel.""",
        )

        # The following settings are used for the split HSV option
        self.use_hue = Binary(
            "Convert hue to gray?",
            True,
            doc="""\
*(Used only when splitting HSV images)*

Select *"Yes"* to extract the hue to grayscale. Otherwise, the hue
will be ignored.
"""
            % globals(),
        )

        self.hue_name = ImageName(
            "Name the output image",
            "OrigHue",
            doc="""\
*(Used only when splitting HSV images)*

Enter a name for the resulting grayscale image coming from the hue.""",
        )

        self.use_saturation = Binary(
            "Convert saturation to gray?",
            True,
            doc="""\
*(Used only when splitting HSV images)*

Select *"Yes"* to extract the saturation to grayscale. Otherwise, the
saturation will be ignored.
"""
            % globals(),
        )

        self.saturation_name = ImageName(
            "Name the output image",
            "OrigSaturation",
            doc="""\
*(Used only when splitting HSV images)*

Enter a name for the resulting grayscale image coming from the saturation.""",
        )

        self.use_value = Binary(
            "Convert value to gray?",
            True,
            doc="""\
*(Used only when splitting HSV images)*

Select *"Yes"* to extract the value to grayscale. Otherwise, the
value will be ignored.
"""
            % globals(),
        )

        self.value_name = ImageName(
            "Name the output image",
            "OrigValue",
            doc="""\
*(Used only when splitting HSV images)*

Enter a name for the resulting grayscale image coming from the value.""",
        )

        # The alternative model:
        self.channels = []
        self.add_channel(False)
        self.channel_button = DoSomething("", "Add another channel", self.add_channel)

        self.channel_count = HiddenCount(self.channels, "Channel count")
Beispiel #10
0
    def create_settings(self):
        super(FilterObjects, self).create_settings()

        self.x_name.text = """Select the objects to filter"""

        self.x_name.doc = """\
Select the set of objects that you want to filter. This setting also
controls which measurement choices appear for filtering: you can only
filter based on measurements made on the object you select. Be sure
the **FilterObjects** module is downstream of the necessary **Measure**
modules. If you
intend to use a measurement calculated by the **CalculateMath** module
to to filter objects, select the first operand’s object here, because
**CalculateMath** measurements are stored with the first operand’s
object."""

        self.y_name.text = """Name the output objects"""

        self.y_name.doc = "Enter a name for the collection of objects that are retained after applying the filter(s)."

        self.spacer_1 = Divider(line=False)

        self.mode = Choice(
            "Select the filtering mode",
            [MODE_MEASUREMENTS, MODE_RULES, MODE_BORDER, MODE_CLASSIFIERS],
            doc="""\
You can choose from the following options:

-  *{MODE_MEASUREMENTS}*: Specify a per-object measurement made by an
   upstream module in the pipeline.
-  *{MODE_BORDER}*: Remove objects touching the border of the image
   and/or the edges of an image mask.
-  *{MODE_RULES}*: Use a file containing rules generated by
   CellProfiler Analyst. You will need to ensure that the measurements
   specified by the rules file are produced by upstream modules in the
   pipeline. This setting is not compatible with data processed as 3D.
-  *{MODE_CLASSIFIERS}*: Use a file containing a trained classifier from
   CellProfiler Analyst. You will need to ensure that the measurements
   specified by the file are produced by upstream modules in the
   pipeline. This setting is not compatible with data processed as 3D.""".format(
                **{
                    "MODE_MEASUREMENTS": MODE_MEASUREMENTS,
                    "MODE_RULES": MODE_RULES,
                    "MODE_BORDER": MODE_BORDER,
                    "MODE_CLASSIFIERS": MODE_CLASSIFIERS,
                }
            ),
        )

        self.spacer_2 = Divider(line=False)

        self.measurements = []

        self.measurement_count = HiddenCount(self.measurements, "Measurement count")

        self.add_measurement(False)

        self.add_measurement_button = DoSomething(
            "", "Add another measurement", self.add_measurement
        )

        self.filter_choice = Choice(
            "Select the filtering method",
            FI_ALL,
            FI_LIMITS,
            doc="""\
*(Used only if filtering using measurements)*

There are five different ways to filter objects:

-  *{FI_LIMITS}:* Keep an object if its measurement value falls within
   a range you specify.
-  *{FI_MAXIMAL}:* Keep the object with the maximum value for the
   measurement of interest. If multiple objects share a maximal value,
   retain one object selected arbitrarily per image.
-  *{FI_MINIMAL}:* Keep the object with the minimum value for the
   measurement of interest. If multiple objects share a minimal value,
   retain one object selected arbitrarily per image.
-  *{FI_MAXIMAL_PER_OBJECT}:* This option requires you to choose a
   parent object. The parent object might contain several child objects
   of choice (for instance, mitotic spindles within a cell or FISH probe
   spots within a nucleus). Only the child object whose measurements
   equal the maximum child-measurement value among that set of child
   objects will be kept (for example, the longest spindle in each cell).
   You do not have to explicitly relate objects before using this
   module.
-  *{FI_MINIMAL_PER_OBJECT}:* Same as *Maximal per object*, except
   filtering is based on the minimum value.""".format(
                **{
                    "FI_LIMITS": FI_LIMITS,
                    "FI_MAXIMAL": FI_MAXIMAL,
                    "FI_MINIMAL": FI_MINIMAL,
                    "FI_MAXIMAL_PER_OBJECT": FI_MAXIMAL_PER_OBJECT,
                    "FI_MINIMAL_PER_OBJECT": FI_MINIMAL_PER_OBJECT,
                }
            ),
        )

        self.per_object_assignment = Choice(
            "Assign overlapping child to",
            PO_ALL,
            doc="""\
*(Used only if filtering per object)*

A child object can overlap two parent objects and can have the
maximal/minimal measurement of all child objects in both parents. This
option controls how an overlapping maximal/minimal child affects
filtering of other children of its parents and to which parent the
maximal child is assigned. The choices are:

-  *{PO_BOTH}*: The child will be assigned to both parents and all
   other children of both parents will be filtered. Only the maximal
   child per parent will be left, but if **RelateObjects** is used to
   relate the maximal child to its parent, one or the other of the
   overlapping parents will not have a child even though the excluded
   parent may have other child objects. The maximal child can still be
   assigned to both parents using a database join via the relationships
   table if you are using **ExportToDatabase** and separate object
   tables.
-  *{PO_PARENT_WITH_MOST_OVERLAP}*: The child will be assigned to
   the parent with the most overlap and a child with a less
   maximal/minimal measurement, if available, will be assigned to other
   parents. Use this option to ensure that parents with an alternate
   non-overlapping child object are assigned some child object by a
   subsequent **RelateObjects** module.""".format(
                **{
                    "PO_BOTH": PO_BOTH,
                    "PO_PARENT_WITH_MOST_OVERLAP": PO_PARENT_WITH_MOST_OVERLAP,
                }
            ),
        )

        self.enclosing_object_name = LabelSubscriber(
            "Select the objects that contain the filtered objects",
            "None",
            doc="""\
*(Used only if a per-object filtering method is selected)*

This setting selects the container (i.e., parent) objects for the
*{FI_MAXIMAL_PER_OBJECT}* and *{FI_MINIMAL_PER_OBJECT}* filtering
choices.""".format(
                **{
                    "FI_MAXIMAL_PER_OBJECT": FI_MAXIMAL_PER_OBJECT,
                    "FI_MINIMAL_PER_OBJECT": FI_MINIMAL_PER_OBJECT,
                }
            ),
        )

        self.rules_directory = Directory(
            "Select the location of the rules or classifier file",
            doc="""\
*(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})*

Select the location of the rules or classifier file that will be used for
filtering.

{IO_FOLDER_CHOICE_HELP_TEXT}
""".format(
                **{
                    "MODE_CLASSIFIERS": MODE_CLASSIFIERS,
                    "MODE_RULES": MODE_RULES,
                    "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT,
                }
            ),
        )

        self.rules_class = Choice(
            "Class number",
            choices=["1", "2"],
            choices_fn=self.get_class_choices,
            doc="""\
*(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})*

Select which of the classes to keep when filtering. The CellProfiler
Analyst classifier user interface lists the names of the classes in
left-to-right order. **FilterObjects** uses the first class from
CellProfiler Analyst if you choose “1”, etc.

Please note the following:

-  The object is retained if the object falls into the selected class.
-  You can make multiple class selections. If you do so, the module will
   retain the object if the object falls into any of the selected
   classes.""".format(
                **{"MODE_CLASSIFIERS": MODE_CLASSIFIERS, "MODE_RULES": MODE_RULES}
            ),
        )

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

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

            self.rules_directory.join_parts(dir_choice, custom_path)

        self.rules_file_name = Filename(
            "Rules or classifier file name",
            "rules.txt",
            get_directory_fn=get_directory_fn,
            set_directory_fn=set_directory_fn,
            doc="""\
*(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})*

The name of the rules or classifier file.

A rules file is a plain text file containing the complete set of rules.

Each line of the rules file should be a rule naming a measurement to be made
on the object you selected, for instance:

    IF (Nuclei_AreaShape_Area < 351.3, [0.79, -0.79], [-0.94, 0.94])

The above rule will score +0.79 for the positive category and -0.94
for the negative category for nuclei whose area is less than 351.3
pixels and will score the opposite for nuclei whose area is larger.
The filter adds positive and negative and keeps only objects whose
positive score is higher than the negative score.

A classifier file is a trained classifier exported from CellProfiler Analyst.
You will need to ensure that the measurements specified by the file are
produced by upstream modules in the pipeline. This setting is not compatible
with data processed as 3D.
""".format(
                **{"MODE_CLASSIFIERS": MODE_CLASSIFIERS, "MODE_RULES": MODE_RULES}
            ),
        )

        self.additional_objects = []

        self.additional_object_count = HiddenCount(
            self.additional_objects, "Additional object count"
        )

        self.spacer_3 = Divider(line=False)

        self.additional_object_button = DoSomething(
            "Relabel additional objects to match the filtered object?",
            "Add an additional object",
            self.add_additional_object,
            doc="""\
Click this button to add an object to receive the same post-filtering labels as
the filtered object. This is useful in making sure that labeling is maintained
between related objects (e.g., primary and secondary objects) after filtering.""",
        )
    def create_settings(self):

        self.executable_directory = Directory(
            "Executable directory",
            allow_metadata=False,
            doc="""\
Select the folder containing the executable. MacOS users should select the directory where Fiji.app lives. Windows users 
should select the directory containing ImageJ-win64.exe (usually corresponding to the Fiji.app folder).

{IO_FOLDER_CHOICE_HELP_TEXT}
""".format(**{"IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT}))

        def set_directory_fn_executable(path):
            dir_choice, custom_path = self.executable_directory.get_parts_from_path(
                path)
            self.executable_directory.join_parts(dir_choice, custom_path)

        self.executable_file = Filename(
            "Executable",
            "ImageJ.exe",
            doc="Select your executable. MacOS users should select the Fiji.app "
            "application. Windows user should select the ImageJ-win64.exe executable",
            get_directory_fn=self.executable_directory.get_absolute_path,
            set_directory_fn=set_directory_fn_executable,
            browse_msg="Choose executable file")

        self.macro_directory = Directory(
            "Macro directory",
            allow_metadata=False,
            doc=f"""Select the folder containing the macro.
{_help.IO_FOLDER_CHOICE_HELP_TEXT}""")

        def set_directory_fn_macro(path):
            dir_choice, custom_path = self.macro_directory.get_parts_from_path(
                path)
            self.macro_directory.join_parts(dir_choice, custom_path)

        self.macro_file = Filename(
            "Macro",
            "macro.py",
            doc="Select your macro file.",
            get_directory_fn=self.macro_directory.get_absolute_path,
            set_directory_fn=set_directory_fn_macro,
            browse_msg="Choose macro file")

        self.add_directory = Text(
            "What variable in your macro defines the folder ImageJ should use?",
            "Directory",
            doc=
            """Because CellProfiler will save the output images in a temporary directory, this directory should be 
specified as a variable in the macro script. It is assumed that the macro will use this directory variable 
to obtain the full path to the inputted image. Enter the variable name here. CellProfiler will create a 
temporary directory and assign its path as a value to this variable.""")

        self.image_groups_in = []
        self.image_groups_out = []

        self.macro_variables_list = []

        self.image_groups_in_count = HiddenCount(self.image_groups_in)
        self.image_groups_out_count = HiddenCount(self.image_groups_out)
        self.macro_variable_count = HiddenCount(self.macro_variables_list)

        self.add_image_in(can_delete=False)
        self.add_image_button_in = DoSomething("", 'Add another input image',
                                               self.add_image_in)

        self.add_image_out(can_delete=False)
        self.add_image_button_out = DoSomething("", 'Add another output image',
                                                self.add_image_out)

        self.add_variable_button_out = DoSomething(
            "Does your macro expect variables?", "Add another variable",
            self.add_macro_variables)
    def create_settings(self):
        """Create the settings for the module

        Create the settings for the module during initialization.
        """
        self.contrast_choice = 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:

-  *%(BY_SINGLE_MEASUREMENT)s:* Classifies each object based on a
   single measurement.
-  *%(BY_TWO_MEASUREMENTS)s:* Classifies each object based on a pair
   of measurements taken together (that is, an object must meet two
   criteria to belong to a class).
""" % 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 = 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 = DoSomething(
            "", "Add another classification", self.add_single_measurement)
        #
        ############### Two-measurement settings #####################
        #
        # The object for the contrasting method
        #
        self.object_name = LabelSubscriber(
            "Select the object name",
            "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
**IdentifyPrimaryObjects**, **IdentifySecondaryObjects**, **IdentifyTertiaryObjects**, or **Watershed**
""",
        )

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

        self.first_measurement = Measurement(
            "Select the first measurement",
            object_fn,
            doc="""\
*(Used only if using a pair of measurements)*

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 = Choice(
            "Method to select the cutoff",
            [TM_MEAN, TM_MEDIAN, TM_CUSTOM],
            doc="""\
*(Used only if using a pair of measurements)*

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:

-  *%(TM_MEAN)s*: At the mean of the measurement’s value for all
   objects in the image cycle.
-  *%(TM_MEDIAN)s*: At the median of the measurement’s value for all
   objects in the image set.
-  *%(TM_CUSTOM)s*: You specify a custom threshold value.
""" % globals(),
        )

        self.first_threshold = Float(
            "Enter the cutoff value",
            0.5,
            doc="""\
*(Used only if using a pair of measurements)*

This is the cutoff value separating objects in the two classes.""",
        )

        self.second_measurement = Measurement(
            "Select the second measurement",
            object_fn,
            doc="""\
*(Used only if using a pair of measurements)*

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 = Choice(
            "Method to select the cutoff",
            [TM_MEAN, TM_MEDIAN, TM_CUSTOM],
            doc="""\
*(Used only if using a pair of measurements)*

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:

-  *%(TM_MEAN)s:* At the mean of the measurement’s value for all
   objects in the image cycle.
-  *%(TM_MEDIAN)s:* At the median of the measurement’s value for all
   objects in the image set.
-  *%(TM_CUSTOM)s:* You specify a custom threshold value.
""" % globals(),
        )

        self.second_threshold = Float(
            "Enter the cutoff value",
            0.5,
            doc="""\
*(Used only if using a pair of measurements)*

This is the cutoff value separating objects in the two classes.""",
        )

        self.wants_custom_names = Binary(
            "Use custom names for the bins?",
            False,
            doc="""\
*(Used only if using a pair of measurements)*

Select "*Yes*" if you want to specify the names of each bin
measurement.

Select "*No*" 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 = Alphanumeric(
            "Enter the low-low bin name",
            "low_low",
            doc="""\
*(Used only if using a pair of measurements)*

Name of the measurement for objects that fall below the threshold for
both measurements.
""",
        )

        self.low_high_custom_name = Alphanumeric(
            "Enter the low-high bin name",
            "low_high",
            doc="""\
*(Used only if using a pair of measurements)*

Name of the measurement for objects whose
first measurement is below threshold and whose second measurement
is above threshold.
""",
        )

        self.high_low_custom_name = Alphanumeric(
            "Enter the high-low bin name",
            "high_low",
            doc="""\
*(Used only if using a pair of measurements)*

Name of the measurement for objects whose
first measurement is above threshold and whose second measurement
is below threshold.""",
        )

        self.high_high_custom_name = Alphanumeric(
            "Enter the high-high bin name",
            "high_high",
            doc="""\
*(Used only if using a pair of measurements)*

Name of the measurement for objects that
are above the threshold for both measurements.""",
        )

        self.wants_image = Binary(
            "Retain an image of the classified objects?",
            False,
            doc="""\
Select "*Yes*" 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 **SaveImages** module).
""" % globals(),
        )

        self.image_name = ImageName(
            "Enter the image name",
            "None",
            doc="""\
*(Used only if the classified object image is to be retained for later use in the pipeline)*

Enter the name to be given to the classified object image.""",
        )