Esempio n. 1
0
    def add_image(self, can_remove=True):
        group = SettingsGroup()

        if can_remove:
            group.append("divider", Divider(line=False))

        group.append(
            "input_image_name",
            ImageSubscriber(
                "Select the additional image?",
                "None",
                doc="""\
What is the name of the additional image to resize? This image will be
resized with the same settings as the first image.""",
            ),
        )

        group.append(
            "output_image_name",
            ImageName(
                "Name the output image",
                "ResizedBlue",
                doc="What is the name of the additional resized image?",
            ),
        )

        if can_remove:
            group.append(
                "remover",
                RemoveSettingButton(
                    "", "Remove above image", self.additional_images, group
                ),
            )

        self.additional_images.append(group)
Esempio n. 2
0
    def prepare_settings(self, setting_values):
        settings_count = int(setting_values[0])

        if settings_count == 0:
            # No params were saved
            return

        # Params were parsed previously and saved
        self.parsed_params = True

        # Looking at the last 5N elements will give the us (value, remover, name, type, io_class) for the N settings
        # We care about the name and type information, since this goes in one of our settings
        settings_info = setting_values[-settings_count * 5:]
        for i in range(0, len(settings_info), 5):
            group = SettingsGroup()
            param_name = settings_info[i + 2]
            param_type = settings_info[i + 3]
            io_class = settings_info[i + 4]
            setting = convert_java_type_to_setting(param_name, param_type, io_class)
            group.append("setting", setting)
            group.append("remover", RemoveSettingButton("", "Remove this variable", self.script_parameter_list, group))
            add_param_info_settings(group, param_name, param_type, io_class)
            self.script_parameter_list.append(group)
            if INPUT_CLASS == io_class:
                self.script_input_settings[param_name] = setting
            elif OUTPUT_CLASS == io_class:
                self.script_output_settings[param_name] = setting
Esempio n. 3
0
    def add_step_parent(self, can_delete=True):
        group = SettingsGroup()

        group.append(
            "step_parent_name",
            Choice(
                "Parent name",
                ["None"],
                choices_fn=self.get_step_parents,
                doc="""\
*(Used only if calculating distances to another parent)*

Choose the name of the other parent. The **RelateObjects** module will
measure the distance from this parent to the child objects in the same
manner as it does to the primary parents. You can only choose the
parents or children of the parent object.""",
            ),
        )

        if can_delete:
            group.append(
                "remove",
                RemoveSettingButton("", "Remove this object",
                                    self.step_parent_names, group),
            )

        self.step_parent_names.append(group)
Esempio n. 4
0
    def add_image_in(self, can_delete=True):
        """Add an image to the image_groups collection
        can_delete - set this to False to keep from showing the "remove"
                     button for images that must be present.
        """
        group = SettingsGroup()
        if can_delete:
            group.append("divider", Divider(line=False))
        group.append(
            "image_name",
            ImageSubscriber('Select an image to send to your macro',
                            "None",
                            doc="Select an image to send to your macro. "))
        group.append(
            "output_filename",
            Text(
                "What should this image temporarily saved as?",
                "None.tiff",
                doc=
                'Enter the filename of the image to be used by the macro. This should be set to the name expected '
                'by the macro file.'),
        )
        if len(self.image_groups_in
               ) == 0:  # Insert space between 1st two images for aesthetics
            group.append("extra_divider", Divider(line=False))

        if can_delete:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this image",
                                    self.image_groups_in, group))

        self.image_groups_in.append(group)
Esempio n. 5
0
    def add_macro_variables(self, can_delete=True):
        group = SettingsGroup()
        if can_delete:
            group.append("divider", Divider(line=False))
        group.append(
            "variable_name",
            Text('What variable name is your macro expecting?',
                 "None",
                 doc='Enter the variable name that your macro is expecting. '))
        group.append(
            "variable_value",
            Text("What value should this variable have?",
                 "None",
                 doc="Enter the desire value for this variable."),
        )
        if len(self.macro_variables_list
               ) == 0:  # Insert space between 1st two images for aesthetics
            group.append("extra_divider", Divider(line=False))

        if can_delete:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this variable",
                                    self.macro_variables_list, group))

        self.macro_variables_list.append(group)
Esempio n. 6
0
    def add_channel(self, can_remove=True):
        """Add another channel to the channels list"""
        group = SettingsGroup()
        group.can_remove = can_remove
        group.append(
            "channel_choice",
            Integer(
                text="Channel number",
                value=len(self.channels) + 1,
                minval=1,
                doc="""\
*(Used only when splitting images)*

This setting chooses a channel to be processed. For example, *1*
is the first
channel in a .TIF or the red channel in a traditional image file.
*2* and *3* are the second and third channels of a TIF or
the green and blue channels in other formats. *4* is the
transparency channel for image formats that support transparency and is
channel # 4 for a .TIF file. **ColorToGray** will fail to process an
image if you select a channel that is not supported by that image, for
example, “5” for a three-channel .PNG file.""",
            ),
        )

        group.append(
            "contribution",
            Float(
                "Relative weight of the 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.""",
            ),
        )

        group.append(
            "image_name",
            ImageName(
                "Image name",
                value="Channel%d" % (len(self.channels) + 1),
                doc="""\
*(Used only when splitting images)*

Select the name of the output grayscale image.""",
            ),
        )

        if group.can_remove:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this channel", self.channels, group),
            )
        self.channels.append(group)
Esempio n. 7
0
    def add_stack_channel_cb(self, can_remove=True):
        group = SettingsGroup()
        default_color = DEFAULT_COLORS[len(self.stack_channels) % len(DEFAULT_COLORS)]
        group.append(
            "image_name",
            ImageSubscriber(
                "Image name",
                "None",
                doc="""\
*(Used only if "%(SCHEME_STACK)s" or "%(SCHEME_COMPOSITE)s" is chosen)*

Select the input image to add to the stacked image.
"""
                % globals(),
            ),
        )
        group.append(
            "color",
            Color(
                "Color",
                default_color,
                doc="""\
*(Used only if "%(SCHEME_COMPOSITE)s" is chosen)*

The color to be assigned to the above image.
"""
                % globals(),
            ),
        )
        group.append(
            "weight",
            Float(
                "Weight",
                1.0,
                minval=0.5 / 255,
                doc="""\
*(Used only if "%(SCHEME_COMPOSITE)s" is chosen)*

The weighting of the above image relative to the others. The image’s
pixel values are multiplied by this weight before assigning the color.
"""
                % globals(),
            ),
        )

        if can_remove:
            group.append(
                "remover",
                RemoveSettingButton(
                    "", "Remove this image", self.stack_channels, group
                ),
            )
        self.stack_channels.append(group)
Esempio n. 8
0
    def get_parameters_from_script(self):
        """
        Use PyImageJ to read header text from an ImageJ script and extract inputs/outputs, which are then converted to
        CellProfiler settings for this module
        """
        global stop_progress_thread, imagej_process, to_imagej, from_imagej
        script_filepath = path.join(self.script_directory.get_absolute_path(), self.script_file.value)

        if not self.script_file.value or not path.exists(script_filepath):
            # nothing to do
            stop_progress_thread = True
            return

        # Start pyimagej if needed
        self.init_pyimagej()
        if not imagej_process:
            stop_progress_thread = True
            return

        # Tell pyimagej to parse the script parameters
        to_imagej.put({PYIMAGEJ_KEY_COMMAND: PYIMAGEJ_CMD_SCRIPT_PARSE, PYIMAGEJ_KEY_INPUT: script_filepath})

        ij_return = from_imagej.get()

        # Process pyimagej's output, converting script parameters to settings
        if ij_return != PYIMAGEJ_STATUS_CMD_UNKNOWN:
            input_params = ij_return[PYIMAGEJ_SCRIPT_PARSE_INPUTS]
            output_params = ij_return[PYIMAGEJ_SCRIPT_PARSE_OUTPUTS]

            for param_dict, settings_dict, io_class in ((input_params, self.script_input_settings, INPUT_CLASS),
                                                        (output_params, self.script_output_settings, OUTPUT_CLASS)):
                for param_name in param_dict:
                    param_type = param_dict[param_name]
                    next_setting = convert_java_type_to_setting(param_name, param_type, io_class)
                    if next_setting is not None:
                        settings_dict[param_name] = next_setting
                        group = SettingsGroup()
                        group.append("setting", next_setting)
                        group.append("remover", RemoveSettingButton("", "Remove this variable",
                                                                    self.script_parameter_list, group))
                        add_param_info_settings(group, param_name, param_type, io_class)
                        # Each setting gets a group containing:
                        # 0 - the setting
                        # 1 - its remover
                        # 2 - (hidden) parameter name
                        # 3 - (hidden) parameter type
                        # 4 - (hidden) parameter i/o class
                        self.script_parameter_list.append(group)

            stop_progress_thread = True
Esempio n. 9
0
    def add_image(self, can_remove=True):
        """Add an image + associated questions and buttons"""
        group = SettingsGroup()
        if can_remove:
            group.append("divider", Divider(line=True))

        group.append(
            "input_image_name",
            ImageSubscriber(
                "Select an additional image to tile",
                "None",
                doc="""Select an additional image to tile?""",
            ),
        )
        if can_remove:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove above image",
                                    self.additional_images, group),
            )
        self.additional_images.append(group)
Esempio n. 10
0
    def add_scale(self, removable=True):
        """

        Add a scale to the scale_groups collection

        :param removable: set this to False to keep from showing the "remove" button for scales that must be present.

        """
        group = SettingsGroup()

        if removable:
            group.append("divider", Divider(line=False))

        scale = Integer(
            doc="""\
You can specify the scale of texture to be measured, in pixel units; the
texture scale is the distance between correlated intensities in the
image. A higher number for the scale of texture measures larger patterns
of texture whereas smaller numbers measure more localized patterns of
texture. It is best to measure texture on a scale smaller than your
objects’ sizes, so be sure that the value entered for scale of texture
is smaller than most of your objects. For very small objects (smaller
than the scale of texture you are measuring), the texture cannot be
measured and will result in a undefined value in the output file.
""",
            text="Texture scale to measure",
            value=len(self.scale_groups) + 3,
        )

        group.append("scale", scale)

        if removable:
            remove_setting = RemoveSettingButton(entry=group,
                                                 label="Remove this scale",
                                                 list=self.scale_groups,
                                                 text="")

            group.append("remover", remove_setting)

        self.scale_groups.append(group)
Esempio n. 11
0
    def add_image_out(self, can_delete=True):
        """Add an image to the image_groups collection
        can_delete - set this to False to keep from showing the "remove"
                     button for images that must be present.
        """
        group = SettingsGroup()
        if can_delete:
            group.append("divider", Divider(line=False))
        group.append(
            "input_filename",
            Text(
                "What is the image filename CellProfiler should load?",
                "None.tiff",
                doc=
                "Enter the image filename CellProfiler should load. This should be set to the output filename "
                "written in the macro file. The image written by the macro will be saved in a temporary directory "
                "and read by CellProfiler."),
        )

        group.append(
            "image_name",
            ImageName(
                r'What should CellProfiler call the loaded image?',
                "None",
                doc=
                'Enter a name to assign to the new image loaded by CellProfiler. This image will be added to your '
                'workspace. '))

        if len(self.image_groups_out
               ) == 0:  # Insert space between 1st two images for aesthetics
            group.append("extra_divider", Divider(line=False))

        if can_delete:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this image",
                                    self.image_groups_out, group))

        self.image_groups_out.append(group)
Esempio n. 12
0
    def add_additional_object(self):
        group = SettingsGroup()

        group.append(
            "object_name",
            LabelSubscriber("Select additional object to relabel", "None"),
        )

        group.append(
            "target_name", LabelName("Name the relabeled objects", "FilteredGreen"),
        )

        group.append(
            "remover",
            RemoveSettingButton(
                "", "Remove this additional object", self.additional_objects, group
            ),
        )

        group.append("divider", Divider(line=False))

        self.additional_objects.append(group)
Esempio n. 13
0
    def add_outline(self, can_remove=True):
        group = SettingsGroup()
        if can_remove:
            group.append("divider", Divider(line=False))

        group.append(
            "objects_name",
            LabelSubscriber(
                "Select objects to display",
                "None",
                doc="Choose the objects whose outlines you would like to display.",
            ),
        )

        default_color = (
            COLOR_ORDER[len(self.outlines)]
            if len(self.outlines) < len(COLOR_ORDER)
            else COLOR_ORDER[0]
        )

        group.append(
            "color",
            Color(
                "Select outline color",
                default_color,
                doc="Objects will be outlined in this color.",
            ),
        )

        if can_remove:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this outline", self.outlines, group),
            )

        self.outlines.append(group)
Esempio n. 14
0
    def add_image(self, can_remove=True):
        group = SettingsGroup()
        group.can_remove = can_remove
        if can_remove:
            group.append("divider", Divider())
        idx = len(self.outputs)
        default_name = STAINS_BY_POPULARITY[idx % len(STAINS_BY_POPULARITY)]
        default_name = default_name.replace(" ", "")

        group.append(
            "image_name",
            ImageName(
                "Name the output image",
                default_name,
                doc="""\
Use this setting to name one of the images produced by the
module for a particular stain. The image can be used in
subsequent modules in the pipeline.
""",
            ),
        )

        choices = list(sorted(STAIN_DICTIONARY.keys())) + [CHOICE_CUSTOM]

        group.append(
            "stain_choice",
            Choice(
                "Stain",
                choices=choices,
                doc="""\
Use this setting to choose the absorbance values for a particular stain.

The stains are:

|Unmix_image0|

(Information taken from `here`_,
`here <http://en.wikipedia.org/wiki/Staining>`__, and
`here <http://stainsfile.info>`__.)
You can choose *{CHOICE_CUSTOM}* and enter your custom values for the
absorbance (or use the estimator to determine values from single-stain
images).

.. _here: http://en.wikipedia.org/wiki/Histology#Staining
.. |Unmix_image0| image:: {UNMIX_COLOR_CHART}

""".format(
                    **{
                        "UNMIX_COLOR_CHART":
                        cellprofiler.gui.help.content.image_resource(
                            "UnmixColors.png"),
                        "CHOICE_CUSTOM":
                        CHOICE_CUSTOM,
                    }),
            ),
        )

        group.append(
            "red_absorbance",
            Float(
                "Red absorbance",
                0.5,
                0,
                1,
                doc="""\
*(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)*

The red absorbance setting estimates the dye’s absorbance of light in
the red channel.You should enter a value between 0 and 1 where 0 is no
absorbance and 1 is complete absorbance. You can use the estimator to
calculate this value automatically.
""" % globals(),
            ),
        )

        group.append(
            "green_absorbance",
            Float(
                "Green absorbance",
                0.5,
                0,
                1,
                doc="""\
*(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)*

The green absorbance setting estimates the dye’s absorbance of light in
the green channel. You should enter a value between 0 and 1 where 0 is
no absorbance and 1 is complete absorbance. You can use the estimator to
calculate this value automatically.
""" % globals(),
            ),
        )

        group.append(
            "blue_absorbance",
            Float(
                "Blue absorbance",
                0.5,
                0,
                1,
                doc="""\
*(Used only if "%(CHOICE_CUSTOM)s" is selected for the stain)*

The blue absorbance setting estimates the dye’s absorbance of light in
the blue channel. You should enter a value between 0 and 1 where 0 is no
absorbance and 1 is complete absorbance. You can use the estimator to
calculate this value automatically.
""" % globals(),
            ),
        )

        def on_estimate():
            result = self.estimate_absorbance()
            if result is not None:
                (
                    group.red_absorbance.value,
                    group.green_absorbance.value,
                    group.blue_absorbance.value,
                ) = result

        group.append(
            "estimator_button",
            DoSomething(
                "Estimate absorbance from image",
                "Estimate",
                on_estimate,
                doc="""\
Press this button to load an image of a sample stained only with the dye
of interest. **UnmixColors** will estimate appropriate red, green and
blue absorbance values from the image.
            """,
            ),
        )

        if can_remove:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this image", self.outputs,
                                    group),
            )
        self.outputs.append(group)
Esempio n. 15
0
    def add_image(self, removable=True):
        # The text for these settings will be replaced in renumber_settings()
        group = SettingsGroup()
        group.removable = removable
        group.append(
            "image_or_measurement",
            Choice(
                "Image or measurement?",
                [IM_IMAGE, IM_MEASUREMENT],
                doc="""\
You can perform math operations using two images or you can use a
measurement for one of the operands. For instance, to divide the
intensity of one image by another, choose *%(IM_IMAGE)s* for both and
pick the respective images. To divide the intensity of an image by its
median intensity, use **MeasureImageIntensity** prior to this module to
calculate the median intensity, then select *%(IM_MEASUREMENT)s* and
use the median intensity measurement as the denominator.
""" % globals(),
            ),
        )

        group.append(
            "image_name",
            ImageSubscriber(
                "Select the image",
                "None",
                doc="""\
Select the image that you want to use for this operation.""",
            ),
        )

        group.append(
            "measurement",
            Measurement(
                "Measurement",
                lambda: "Image",
                "",
                doc="""\
Select a measurement made on the image. The value of the
measurement is used for the operand for all of the pixels of the
other operand's image.""",
            ),
        )

        group.append(
            "factor",
            Float(
                "Multiply the image by",
                1,
                doc="""\
Enter the number that you would like to multiply the above image by. This multiplication
is applied before other operations.""",
            ),
        )

        if removable:
            group.append(
                "remover",
                RemoveSettingButton("", "Remove this image", self.images,
                                    group),
            )

        group.append("divider", Divider())
        self.images.append(group)
    def add_image(self, can_delete=True):
        """Add an image and its settings to the list of images"""
        image_name = ImageSubscriber(
            "Select the input image", "None", doc="Select the image to be corrected."
        )

        corrected_image_name = ImageName(
            "Name the output image",
            "CorrBlue",
            doc="Enter a name for the corrected image.",
        )

        illum_correct_function_image_name = ImageSubscriber(
            "Select the illumination function",
            "None",
            doc="""\
Select the illumination correction function image that will be used to
carry out the correction. This image is usually produced by another
module or loaded as a .mat or .npy format image using the **Images** module
or a **LoadData** module.

Note that loading .mat format images is deprecated and will be removed in
a future version of CellProfiler. You can export .mat format images as
.npy format images using **SaveImages** to ensure future compatibility.
""",
        )

        divide_or_subtract = Choice(
            "Select how the illumination function is applied",
            [DOS_DIVIDE, DOS_SUBTRACT],
            doc="""\
This choice depends on how the illumination function was calculated and
on your physical model of the way illumination variation affects the
background of images relative to the objects in images; it is also
somewhat empirical.

-  *%(DOS_SUBTRACT)s:* Use this option if the background signal is
   significant relative to the real signal coming from the cells. If you
   created the illumination correction function using
   *Background*, then you will want to choose
   *%(DOS_SUBTRACT)s* here.
-  *%(DOS_DIVIDE)s:* Choose this option if the signal to background
   ratio is high (the cells are stained very strongly). If you created
   the illumination correction function using *Regular*, then
   you will want to choose *%(DOS_DIVIDE)s* here.
"""
            % globals(),
        )

        image_settings = SettingsGroup()
        image_settings.append("image_name", image_name)
        image_settings.append("corrected_image_name", corrected_image_name)
        image_settings.append(
            "illum_correct_function_image_name", illum_correct_function_image_name
        )
        image_settings.append("divide_or_subtract", divide_or_subtract)
        image_settings.append("rescale_option", RE_NONE)

        if can_delete:
            image_settings.append(
                "remover",
                RemoveSettingButton(
                    "", "Remove this image", self.images, image_settings
                ),
            )
        image_settings.append("divider", Divider())
        self.images.append(image_settings)
Esempio n. 17
0
    def add_measurement(self, can_delete=True):
        """Add another measurement to the filter list"""
        group = SettingsGroup()

        group.append(
            "measurement",
            Measurement(
                "Select the measurement to filter by",
                self.x_name.get_value,
                "AreaShape_Area",
                doc="""\
*(Used only if filtering using {MODE_MEASUREMENTS})*

See the **Measurements** modules help pages for more information on the
features measured.""".format(
                    **{"MODE_MEASUREMENTS": MODE_MEASUREMENTS}
                ),
            ),
        )

        group.append(
            "wants_minimum",
            Binary(
                "Filter using a minimum measurement value?",
                True,
                doc="""\
*(Used only if {FI_LIMITS} is selected for filtering method)*

Select "*{YES}*" to filter the objects based on a minimum acceptable
object measurement value. Objects which are greater than or equal to
this value will be retained.""".format(
                    **{"FI_LIMITS": FI_LIMITS, "YES": "Yes"}
                ),
            ),
        )

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

        group.append(
            "wants_maximum",
            Binary(
                "Filter using a maximum measurement value?",
                True,
                doc="""\
*(Used only if {FI_LIMITS} is selected for filtering method)*

Select "*{YES}*" to filter the objects based on a maximum acceptable
object measurement value. Objects which are less than or equal to this
value will be retained.""".format(
                    **{"FI_LIMITS": FI_LIMITS, "YES": "Yes"}
                ),
            ),
        )

        group.append("max_limit", Float("Maximum value", 1))

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

        self.measurements.append(group)

        if can_delete:
            group.append(
                "remover",
                RemoveSettingButton(
                    "", "Remove this measurement", self.measurements, group
                ),
            )
Esempio n. 18
0
    def add_measurement(self, flag_settings, can_delete=True):
        measurement_settings = flag_settings.measurement_settings

        group = SettingsGroup()
        group.append("divider1", Divider(line=False))
        group.append(
            "source_choice",
            Choice(
                "Flag is based on",
                S_ALL,
                doc="""\
-  *%(S_IMAGE)s:* A per-image measurement, such as intensity or
   granularity.
-  *%(S_AVERAGE_OBJECT)s:* The average of all object measurements in
   the image.
-  *%(S_ALL_OBJECTS)s:* All the object measurements in an image,
   without averaging. In other words, if *any* of the objects meet the
   criteria, the image will be flagged.
-  *%(S_RULES)s:* Use a text file of rules produced by CellProfiler
   Analyst. With this option, you will have to ensure that this pipeline
   produces every measurement in the rules file upstream of this module.
-  *%(S_CLASSIFIER)s:* Use a classifier built by CellProfiler Analyst.
""" % globals(),
            ),
        )

        group.append(
            "object_name",
            LabelSubscriber(
                "Select the object to be used for flagging",
                "None",
                doc="""\
*(Used only when flag is based on an object measurement)*

Select the objects whose measurements you want to use for flagging.
""",
            ),
        )

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

        group.append(
            "rules_directory",
            Directory(
                "Rules file location",
                doc="""\
*(Used only when flagging using "{rules}")*

Select the location of the rules file that will be used for flagging images.
{folder_choice}
""".format(rules=S_RULES, folder_choice=IO_FOLDER_CHOICE_HELP_TEXT),
            ),
        )

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

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

        group.append(
            "rules_file_name",
            Filename(
                "Rules file name",
                "rules.txt",
                get_directory_fn=get_directory_fn,
                set_directory_fn=set_directory_fn,
                doc="""\
*(Used only when flagging using "%(S_RULES)s")*

The name of the rules file, most commonly from CellProfiler Analyst's
Classifier. This file should be a plain text file
containing the complete set of rules.

Each line of this file should be a rule naming a measurement to be made
on an image, for instance:

    IF (Image_ImageQuality_PowerLogLogSlope_DNA < -2.5, [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 images whose power log slope is less
than -2.5 pixels and will score the opposite for images whose slope is
larger. The filter adds positive and negative and flags the images
whose positive score is higher than the negative score.
""" % globals(),
            ),
        )

        def get_rules_class_choices(group=group):
            """Get the available choices from the rules file"""
            try:
                if group.source_choice == S_CLASSIFIER:
                    return self.get_bin_labels(group)
                elif group.source_choice == S_RULES:
                    rules = self.get_rules(group)
                    nclasses = len(rules.rules[0].weights[0])
                    return [str(i) for i in range(1, nclasses + 1)]
                else:
                    return ["None"]
                rules = self.get_rules(group)
                nclasses = len(rules.rules[0].weights[0])
                return [str(i) for i in range(1, nclasses + 1)]
            except:
                return [str(i) for i in range(1, 3)]

        group.append(
            "rules_class",
            MultiChoice(
                "Class number",
                choices=["1", "2"],
                doc="""\
*(Used only when flagging using "%(S_RULES)s")*

Select which classes to flag when filtering. The CellProfiler Analyst
Classifier user interface lists the names of the classes in order. By
default, these are the positive (class 1) and negative (class 2)
classes. **FlagImage** uses the first class from CellProfiler Analyst
if you choose “1”, etc.

Please note the following:

-  The flag is set if the image falls into the selected class.
-  You can make multiple class selections. If you do so, the module will
   set the flag if the image falls into any of the selected classes.
""" % globals(),
            ),
        )

        group.rules_class.get_choices = get_rules_class_choices

        group.append(
            "measurement",
            Measurement(
                "Which measurement?",
                object_fn,
                doc="""Choose the measurement to be used as criteria.""",
            ),
        )

        group.append(
            "wants_minimum",
            Binary(
                "Flag images based on low values?",
                True,
                doc="""\
Select *Yes* to flag images with measurements below the specified
cutoff. If the measurement evaluates to Not-A-Number (NaN), then the
image is not flagged.
""" % globals(),
            ),
        )

        group.append(
            "minimum_value",
            Float("Minimum value", 0, doc="""Set a value as a lower limit."""),
        )

        group.append(
            "wants_maximum",
            Binary(
                "Flag images based on high values?",
                True,
                doc="""\
Select *Yes* to flag images with measurements above the specified
cutoff. If the measurement evaluates to Not-A-Number (NaN), then the
image is not flagged.
""" % globals(),
            ),
        )

        group.append(
            "maximum_value",
            Float("Maximum value", 1,
                  doc="""Set a value as an upper limit."""),
        )

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

        group.append("divider2", Divider(line=True))
        measurement_settings.append(group)
Esempio n. 19
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)
Esempio n. 20
0
    def add_function(self, can_remove=True):
        group = MorphSettingsGroup()
        group.can_remove = can_remove
        if can_remove:
            group.append("divider", Divider(line=False))
        group.append(
            "function",
            Choice(
                "Select the operation to perform",
                F_ALL,
                doc="""Choose one of the operations described in this module's help.""",
            ),
        )

        group.append(
            "repeats_choice",
            Choice(
                "Number of times to repeat operation",
                R_ALL,
                doc="""\
This setting controls the number of times that the same operation is
applied successively to the image.

-  *%(R_ONCE)s:* Perform the operation once on the image.
-  *%(R_FOREVER)s:* Perform the operation on the image until successive
   iterations yield the same image.
-  *%(R_CUSTOM)s:* Perform the operation a custom number of times."""
                % globals(),
            ),
        )

        group.append(
            "custom_repeats",
            Integer(self.CUSTOM_REPEATS_TEXT, 2, 1, doc=self.CUSTOM_REPEATS_DOC),
        )

        group.append(
            "rescale_values",
            Binary(
                "Rescale values from 0 to 1?",
                True,
                doc="""\
*(Used only for the "%(F_DISTANCE)s" operation).*

Select "*Yes*" to rescale the transformed values to lie between 0 and
1. This is the option to use if the distance transformed image is to be
used for thresholding by an **Identify** module or the like, which
assumes a 0-1 scaling.

Select "*No*" to leave the values in absolute pixel units. This useful
in cases where the actual pixel distances are to be used downstream as
input for a measurement module."""
                % globals(),
            ),
        )

        if can_remove:
            group.append(
                "remove",
                RemoveSettingButton("", "Remove this operation", self.functions, group),
            )
        self.functions.append(group)
Esempio n. 21
0
    def add_single_measurement(self, can_delete=True):
        """Add a single measurement to the group of single measurements

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

        group.append(
            "object_name",
            LabelSubscriber(
                "Select the object to be classified",
                "None",
                doc="""\
The name of the objects to be classified. You can choose from objects
created by any previous module. See **IdentifyPrimaryObjects**,
**IdentifySecondaryObjects**, **IdentifyTertiaryObjects**, or **Watershed**
""",
            ),
        )

        def object_fn():
            return group.object_name.value

        group.append(
            "measurement",
            Measurement(
                "Select the measurement to classify by",
                object_fn,
                doc="""\
*(Used only if using a single measurement)*

Select a measurement made by a previous module. The objects will be
classified according to their values for this measurement.
""",
            ),
        )

        group.append(
            "bin_choice",
            Choice(
                "Select bin spacing",
                [BC_EVEN, BC_CUSTOM],
                doc="""\
*(Used only if using a single measurement)*

Select how you want to define the spacing of the bins. You have the
following options:

-  *%(BC_EVEN)s:* Choose this if you want to specify bins of equal
   size, bounded by upper and lower limits. If you want two bins, choose
   this option and then provide a single threshold when asked.
-  *%(BC_CUSTOM)s:* Choose this option to create the indicated number
   of bins at evenly spaced intervals between the low and high
   threshold. You also have the option to create bins for objects that
   fall below or above the low and high threshold.
""" % globals(),
            ),
        )

        group.append(
            "bin_count",
            Integer(
                "Number of bins",
                3,
                minval=1,
                doc="""\
*(Used only if using a single measurement)*

This is the number of bins that will be created between
the low and high threshold""",
            ),
        )

        group.append(
            "low_threshold",
            Float(
                "Lower threshold",
                0,
                doc="""\
*(Used only if using a single measurement and "%(BC_EVEN)s" selected)*

This is the threshold that separates the lowest bin from the others. The
lower threshold, upper threshold, and number of bins define the
thresholds of bins between the lowest and highest.
""" % globals(),
            ),
        )

        group.append(
            "wants_low_bin",
            Binary(
                "Use a bin for objects below the threshold?",
                False,
                doc="""\
*(Used only if using a single measurement)*

Select "*Yes*" if you want to create a bin for objects whose values
fall below the low threshold. Select "*No*" if you do not want a bin
for these objects.
""" % globals(),
            ),
        )

        group.append(
            "high_threshold",
            Float(
                "Upper threshold",
                1,
                doc="""\
*(Used only if using a single measurement and "%(BC_EVEN)s" selected)*

This is the threshold that separates the last bin from the others. Note
that if you would like two bins, you should select "*%(BC_CUSTOM)s*".
""" % globals(),
            ),
        )

        group.append(
            "wants_high_bin",
            Binary(
                "Use a bin for objects above the threshold?",
                False,
                doc="""\
*(Used only if using a single measurement)*

Select "*Yes*" if you want to create a bin for objects whose values
are above the high threshold.

Select "*No*" if you do not want a bin for these objects.
""" % globals(),
            ),
        )

        group.append(
            "custom_thresholds",
            Text(
                "Enter the custom thresholds separating the values between bins",
                "0,1",
                doc="""\
*(Used only if using a single measurement and "%(BC_CUSTOM)s" selected)*

This setting establishes the threshold values for the bins. You should
enter one threshold between each bin, separating thresholds with commas
(for example, *0.3, 1.5, 2.1* for four bins). The module will create one
more bin than there are thresholds.
""" % globals(),
            ),
        )

        group.append(
            "wants_custom_names",
            Binary(
                "Give each bin a name?",
                False,
                doc="""\
*(Used only if using a single measurement)*

Select "*Yes*" to assign custom names to bins you have specified.

Select "*No*" for the module to automatically assign names based on
the measurements and the bin number.
""" % globals(),
            ),
        )

        group.append(
            "bin_names",
            Text(
                "Enter the bin names separated by commas",
                "None",
                doc="""\
*(Used only if "Give each bin a name?" is checked)*

Enter names for each of the bins, separated by commas.
An example including three bins might be *First,Second,Third*.""",
            ),
        )

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

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

        group.can_delete = can_delete

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

        group.number_of_bins = number_of_bins

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

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

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

        group.bin_feature_names = bin_feature_names

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

        group.validate_group = validate_group

        if can_delete:
            group.remove_settings_button = RemoveSettingButton(
                "", "Remove this classification", self.single_measurements,
                group)
        self.single_measurements.append(group)
Esempio n. 22
0
    def add_mapping(self):
        group = SettingsGroup()
        group.append(
            "local_directory",
            Text(
                "Local root path",
                get_default_image_directory(),
                doc="""\
Enter the path to files on this computer. This is the root path on the
local machine (i.e., the computer setting up the batch files).

For instance, a Windows machine might access files images by mounting the file system using a drive
letter, like this:

``Z:\your_data\images``

and the cluster computers access the same file system like this:

``/server_name/your_name/your_data/images``

In this case, since the ``your_data\images`` portion of the path is
the same for both, the local root path is the portion prior, i.e.,
``Z:\`` and similarly for the cluster root path, i.e.,
``/server_name/your_name/``.

If **CreateBatchFiles** finds any pathname that matches the local root path
at the beginning, it will replace that matching portion with the cluster root path.

For example, if you have mapped the remote cluster machine like this:

``Z:\your_data\images``

(on a Windows machine, for instance) and the cluster machine sees the same folder like this:

``/server_name/your_name/your_data/images``

you would enter ``Z:\`` here for the local root path and ``/server_name/your_name/`` for the
cluster root path in the next setting.""",
            ),
        )

        group.append(
            "remote_directory",
            Text(
                "Cluster root path",
                get_default_image_directory(),
                doc="""\
Enter the path to files on the cluster. This is the cluster root path,
i.e., how the cluster machine sees the top-most folder where your
input/output files are stored.

For instance, a Windows machine might access files images by mounting the file system using a drive
letter, like this:

``Z:\your_data\images``

and the cluster computers access the same file system like this:

``/server_name/your_name/your_data/images``

In this case, since the ``your_data\images`` portion of the path is
the same for both, the local root path is the portion prior, i.e.,
``Z:\`` and similarly for the cluster root path, i.e.,
``/server_name/your_name/``.

If **CreateBatchFiles** finds any pathname that matches the local root path
at the beginning, it will replace that matching portion with the cluster root path.

For example, if you have mapped the remote cluster machine like this:

``Z:\your_data\images``

(on a Windows machine, for instance) and the cluster machine sees the same folder like this:

``/server_name/your_name/your_data/images``

you would enter ``Z:\`` in the previous setting for the local root
path and ``/server_name/your_name/`` here for the cluster root path.""",
            ),
        )
        group.append(
            "remover",
            RemoveSettingButton("", "Remove this path mapping", self.mappings,
                                group),
        )
        group.append("divider", Divider(line=False))
        self.mappings.append(group)
Esempio n. 23
0
    def add_dose_value(self, can_remove=True):
        """Add a dose value measurement to the list

        can_delete - set this to False to keep from showing the "remove"
                     button for images that must be present."""
        group = SettingsGroup()
        group.append(
            "measurement",
            Measurement(
                "Select the image measurement describing the treatment dose",
                lambda: IMAGE,
                doc="""\
The V and Z’ factors, metrics of assay quality, and the EC50,
indicating dose-response, are calculated by this module based on each
image being specified as a particular treatment dose. Choose a
measurement that gives the dose of some treatment for each of your
images. See the help for the previous setting for details.""",
            ),
        )

        group.append(
            "log_transform",
            Binary(
                "Log-transform the dose values?",
                False,
                doc="""\
Select *Yes* if you have dose-response data and you want to
log-transform the dose values before fitting a sigmoid curve.

Select *No* if your data values indicate only positive vs. negative
controls.
"""
                % globals(),
            ),
        )

        group.append(
            "wants_save_figure",
            Binary(
                """Create dose-response plots?""",
                False,
                doc="""Select *Yes* if you want to create and save dose-response plots.
You will be asked for information on how to save the plots."""
                % globals(),
            ),
        )

        group.append(
            "figure_name",
            Text(
                "Figure prefix",
                "",
                doc="""\
*(Used only when creating dose-response plots)*

CellProfiler will create a file name by appending the measurement name
to the prefix you enter here. For instance, if you specify a prefix
of “Dose\_”, when saving a file related to objects you have chosen (for
example, *Cells*) and a particular measurement (for example, *AreaShape_Area*),
CellProfiler will save the figure as *Dose_Cells_AreaShape_Area.m*.
Leave this setting blank if you do not want a prefix.
""",
            ),
        )
        group.append(
            "pathname",
            Directory(
                "Output file location",
                dir_choices=[
                    DEFAULT_OUTPUT_FOLDER_NAME,
                    DEFAULT_INPUT_FOLDER_NAME,
                    ABSOLUTE_FOLDER_NAME,
                    DEFAULT_OUTPUT_SUBFOLDER_NAME,
                    DEFAULT_INPUT_SUBFOLDER_NAME,
                ],
                doc="""\
*(Used only when creating dose-response plots)*

This setting lets you choose the folder for the output files. {fcht}

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

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

        group.append(
            "remover",
            RemoveSettingButton(
                "", "Remove this dose measurement", self.dose_values, group
            ),
        )
        self.dose_values.append(group)