Esempio n. 1
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. 2
0
def add_param_info_settings(group, param_name, param_type, param_class):
    """
    Each extracted name, type and input/output class is saved into a (hidden) setting. This is useful information to
    have when saving and loading pipelines back into CellProfiler.

    Parameters
    ----------
    group : SettingsGroup, required
        The SettingsGroup for this parameter, to hold the hidden info settings
    param_name : str, required
        The name of the parameter
    param_type : str, required
        The Java class name describing the parameter type
    param_class: str, required
        One of {input_class} or {output_class}, based on the parameter use
    """
    group.append(
        "name",
        Text(
            'Parameter name',
            param_name
        )
    )
    group.append(
        "type",
        Text(
            "Parameter type",
            param_type),
    )
    group.append(
        "io_class",
        Text(
            "Parameter classification",
            param_class),
    )
Esempio n. 3
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)
    def create_settings(self):
        self._ij = None

        self.host = Text(
            "ImageJ server",
            imagej.HOST
        )

        self.connect = DoSomething(
            "",
            "Connect",
            self._connect
        )

        self.divider = cellprofiler_core.setting.Divider(u"———OUTPUTS———")

        # These will get redefined after the module connects to the server.
        self.ij_module = Choice(
            "ImageJ module",
            choices=["-- NONE --"]
        )

        self.input_details = []
        self.input_settings = cellprofiler_core.setting.SettingsGroup()

        self.output_details = []
        self.output_settings = cellprofiler_core.setting.SettingsGroup()

        self.input_count = cellprofiler_core.setting.HiddenCount([], "")
    def create_settings(self):
        """Create the module settings and name the module"""
        self.wants_default_output_directory = Binary(
            "Store batch files in default output folder?",
            True,
            doc="""\
Select "*Yes*" to store batch files in the Default Output folder.
Select "*No*" to enter the path to the folder that will be used to
store these files. The Default Output folder can be set by clicking the "View output settings" button in the main CP window, or in CellProfiler Preferences. """
            % globals(),
        )

        self.custom_output_directory = Text(
            "Output folder path",
            get_default_output_directory(),
            doc=
            "Enter the path to the output folder. (Used only if not using the default output folder)",
        )

        # Worded this way not because I am windows-centric but because it's
        # easier than listing every other OS in the universe except for VMS
        self.remote_host_is_windows = Binary(
            "Are the cluster computers running Windows?",
            False,
            doc="""\
Select "*Yes*" if the cluster computers are running one of the
Microsoft Windows operating systems. In this case, **CreateBatchFiles**
will modify all paths to use the Windows file separator (backslash \\\\ ).
Select "*No*" for **CreateBatchFiles** to modify all paths to use the
Unix or Macintosh file separator (slash / ).""" % globals(),
        )

        self.batch_mode = Binary("Hidden: in batch mode", False)
        self.distributed_mode = Binary("Hidden: in distributed mode", False)
        self.default_image_directory = Setting(
            "Hidden: default input folder at time of save",
            get_default_image_directory(),
        )
        self.revision = Integer("Hidden: revision number", 0)
        self.from_old_matlab = Binary("Hidden: from old matlab", False)
        self.acknowledge_old_matlab = DoSomething(
            "Could not update CP1.0 pipeline to be compatible with CP2.0.  See module notes.",
            "OK",
            self.clear_old_matlab,
        )
        self.mappings = []
        self.add_mapping()
        self.add_mapping_button = DoSomething(
            "",
            "Add another path mapping",
            self.add_mapping,
            doc="""\
Use this option if another path must be mapped because there is a difference
between how the local computer sees a folder location vs. how the cluster
computer sees the folder location.""",
        )
    def create_settings(self):
        super(Noise2Void, self).create_settings()
        self.ml_model = Directory("Path to ML Model",
                                  doc="""\
Select the folder containing the machine learning model to be used.
This model has to be generated via the noise2void training. See
https://github.com/juglab/n2v/blob/master/examples/2D/denoising2D_RGB/01_training.ipynb
for an example of training.
"""
                                  )
        self.color = Binary("Process as color image?",
                            value=False,
                            doc="""\
Select whether your image should be processed as a color image or not.
""")
        self.manual_slicing = Binary("Slice Image manually?",
                                     value=False, doc="""\
If necessary, **Noise2Void** will slice your image into tiles automatically for a better memory fit. 
If you want to manually determine the size of the said tiles, check this setting.

Colored images **do not** support custom slicing as of right now!
""")
        self.slicing_configuration = Text("Tile size", value="(2,2,2)", doc="""\
You can provide an image slicing configuration for Noise2Void for a better memory fit. 
Specify your custom slicing configuration as follows:

- (x,y) for 2D Images
- (x,y,z) for 3D Images, whereas x,y and z are positive integers.

If your input cannot be parsed, no slicing configuration will be provided to n2v.
""")

        self.axes_configuration = Text(text="N2V Axes", value=N2V_AXES_3D, doc="""\
For internal use only.
Communicates axes configuration (2D or 3D, color or not) to n2v.
""")

        self.x_name.doc = """\
Esempio n. 7
0
    def create_settings(self):
        """Create the settings & name the module"""
        self.images_list = ImageListSubscriber(
            "Select images to measure",
            [],
            doc="""Select the grayscale images whose intensity you want to measure.""",
        )

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

        self.objects_list = LabelListSubscriber(
            "Select input object sets",
            [],
            doc="""Select the object sets whose intensity you want to measure.""",
        )

        self.wants_percentiles = Binary(
            text="Calculate custom percentiles",
            value=False,
            doc="""Choose whether to enable measurement of custom percentiles.
            
            Note that the Upper and Lower Quartile measurements are automatically calculated by this module,
            representing the 25th and 75th percentiles.
            """,
        )

        self.percentiles = Text(
            text="Specify percentiles to measure",
            value="10,90",
            doc="""Specify the percentiles to measure. Values should range from 0-100 inclusive and be whole integers.
            Multiple values can be specified by seperating them with a comma,
            eg. "10,90" will measure the 10th and 90th percentiles.
            """,
        )
Esempio n. 8
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. 9
0
    def create_settings(self):
        #
        # The superclass (cellprofiler_core.module.ImageProcessing) defines two
        # settings for image input and output:
        #
        # -  x_name: an ImageSubscriber which "subscribes" to all
        #    ImageNameProviders in prior modules. Modules before yours will
        #    put images into CellProfiler. The ImageSubscriber gives
        #    your user a list of these images which can then be used as inputs
        #    in your module.
        # -  y_name: an text.ImageName makes the image available to subsequent
        #    modules.
        super(Save16BitPngs, self).create_settings()

        #
        # reST help that gets displayed when the user presses the
        # help button to the right of the edit box.
        #
        # The superclass defines some generic help test. You can add
        # module-specific help text by modifying the setting's "doc"
        # string.
        #
        self.x_name.doc = """\
This is the image that the module operates on. You can choose any image
that is made available by a prior module.
**Save16BitPngs** will do something to this image.
"""
        # We use a float setting so that the user can give us a number
        # for the scale. The control will turn red if the user types in
        # an invalid scale.
        #
        self.single_file_name = Text("Enter single file name",
                                     "OrigBlue",
                                     metadata=True,
                                     doc="""\
This sets the image file name - You should use metadata information to fill this name, otherwise the pipeline will simply overwrite images!.
""")
Esempio n. 10
0
    def create_settings(self):
        self.x_source = Choice(
            "Type of measurement to plot on X-axis",
            SOURCE_CHOICE,
            doc="""\
You can plot two types of measurements:

-  *%(SOURCE_IM)s:* For a per-image measurement, one numerical value is
   recorded for each image analyzed. Per-image measurements are produced
   by many modules. Many have **MeasureImage** in the name but others do
   not (e.g., the number of objects in each image is a per-image
   measurement made by the **Identify** modules).
-  *%(SOURCE_OBJ)s:* For a per-object measurement, each identified
   object is measured, so there may be none or many numerical values
   recorded for each image analyzed. These are usually produced by
   modules with **MeasureObject** in the name.
"""
            % globals(),
        )

        self.x_object = LabelSubscriber(
            "Select the object to plot on the X-axis",
            "None",
            doc="""\
*(Used only when plotting objects)*

Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose
measurements are to be displayed on the X-axis.
""",
        )

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

        self.y_source = Choice(
            "Type of measurement to plot on Y-axis",
            SOURCE_CHOICE,
            doc="""\
You can plot two types of measurements:

-  *%(SOURCE_IM)s:* For a per-image measurement, one numerical value is
   recorded for each image analyzed. Per-image measurements are produced
   by many modules. Many have **MeasureImage** in the name but others do
   not (e.g., the number of objects in each image is a per-image
   measurement made by **Identify** modules).
-  *%(SOURCE_OBJ)s:* For a per-object measurement, each identified
   object is measured, so there may be none or many numerical values
   recorded for each image analyzed. These are usually produced by
   modules with **MeasureObject** in the name.
"""
            % globals(),
        )

        self.y_object = LabelSubscriber(
            "Select the object to plot on the Y-axis",
            "None",
            doc="""\
*(Used only when plotting objects)*

Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose
measurements are to be displayed on the Y-axis.
""",
        )

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

        self.xscale = Choice(
            "How should the X-axis be scaled?",
            SCALE_CHOICE,
            None,
            doc="""\
The X-axis can be scaled with either a *linear* scale or a *log* (base
10) scaling.

Log scaling is useful when one of the measurements being plotted covers
a large range of values; a log scale can bring out features in the
measurements that would not easily be seen if the measurement is plotted
linearly.
""",
        )

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

Log scaling is useful when one of the measurements being plotted covers
a large range of values; a log scale can bring out features in the
measurements that would not easily be seen if the measurement is plotted
linearly.
""",
        )

        self.title = Text(
            "Enter a title for the plot, if desired",
            "",
            doc="""\
Enter a title for the plot. If you leave this blank, the title will
default to *(cycle N)* where *N* is the current image cycle being
executed.
""",
        )
Esempio n. 11
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. 12
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)
Esempio n. 13
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. 14
0
    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)
Esempio n. 15
0
    def create_settings(self):
        self.directory = Directory("Output file location",
                                   dir_choices=[
                                       ABSOLUTE_FOLDER_NAME,
                                       DEFAULT_OUTPUT_FOLDER_NAME,
                                       DEFAULT_OUTPUT_SUBFOLDER_NAME,
                                       DEFAULT_INPUT_FOLDER_NAME,
                                       DEFAULT_INPUT_SUBFOLDER_NAME
                                   ],
                                   doc="""
            This setting lets you choose the folder for the output
            files. %(IO_FOLDER_CHOICE_HELP_TEXT)s
            
            %(IO_WITH_METADATA_HELP_TEXT)s
""" % globals())
        self.directory.dir_choice = DEFAULT_OUTPUT_FOLDER_NAME

        self.wants_file_name_suffix = Binary(
            "Append a suffix to the file name?",
            False,
            doc="""
            Select *"YES"* to add a suffix to the file name.
            Select *"NO"* to use the file name as-is.
""" % globals())

        self.file_name_suffix = Text("Text to append to the file name",
                                     "",
                                     metadata=True,
                                     doc="""
            "*(Used only when constructing the filename from the image filename)*"
            Enter the text that should be appended to the filename specified above.
""")

        self.wants_overwrite_without_warning = Binary(
            "Overwrite without warning?",
            False,
            doc="""This setting either prevents or allows overwriting of
            old .txt files by **ExportToACC** without confirmation.
            Select "*YES*" to overwrite without warning any .txt file 
            that already exists. Select "*NO*" to prompt before overwriting
            when running CellProfiler in the GUI and to fail when running
            headless.
""" % globals())

        self.nan_representation = Choice("Representation of Nan/Inf",
                                         [NANS_AS_NANS, NANS_AS_NULLS],
                                         doc="""
            This setting controls the output for numeric fields
            if the calculated value is infinite (*"Inf"*) or undefined (*"NaN*").
            CellProfiler will produce Inf or NaN values under certain rare
            circumstances, for instance when calculating the mean intensity
            of an object within a masked region of an image.

            - "*%(NANS_AS_NULLS)s:*" Output these values as empty fields.
            - "*%(NANS_AS_NANS)s:*" Output them as the strings "NaN", "Inf" or "-Inf".

""" % globals())

        self.pick_columns = Binary("Select the measurements to export",
                                   False,
                                   doc="""
            Select *"YES"* to provide a button that allows you to select which measurements you want to export.
            This is useful if you know exactly what measurements you want included in the final spreadheet(s). """
                                   % globals())

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

        self.file_image_name = FileImageSubscriber(
            "Select image name for file prefix",
            "None",
            doc="""
            Select an image loaded using **NamesAndTypes**. The original filename will be
            used as the prefix for the output filename.""" % globals())
Esempio n. 16
0
    def create_settings(self):
        """Create the module settings

        create_settings is called at the end of initialization.
        """
        self.object = LabelSubscriber(
            text="Select the object whose measurements will be displayed",
            value="None",
            doc=textwrap.dedent("""\
                Choose the name of objects identified by some previous module (such as
                **IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose
                measurements are to be displayed.
            """),
        )

        self.x_axis = Measurement(
            text="Select the object measurement to plot",
            object_fn=self.get_object,
            value="None",
            doc=
            "Choose the object measurement made by a previous module to plot.",
        )

        self.bins = Integer(
            text="Number of bins",
            value=100,
            minval=1,
            maxval=1000,
            doc=
            "Enter the number of equally-spaced bins that you want used on the X-axis.",
        )

        self.xscale = Choice(
            text="How should the X-axis be scaled?",
            choices=["linear", "log"],
            value=None,
            doc=textwrap.dedent("""\
                The measurement data can be scaled with either a **{LINEAR}** scale or
                a **{LOG_NATURAL}** (natural log) scaling.

                Log scaling is useful when one of the measurements being plotted covers
                a large range of values; a log scale can bring out features in the
                measurements that would not easily be seen if the measurement is plotted
                linearly.
                """.format(
                LINEAR="linear",
                LOG_NATURAL="log",
            )),
        )

        self.yscale = Choice(
            text="How should the Y-axis be scaled?",
            choices=["linear", "log"],
            value=None,
            doc=textwrap.dedent("""\
                The Y-axis can be scaled either with either a **{LINEAR}** scale or a **{LOG_NATURAL}**
                (natural log) scaling.

                Log scaling is useful when one of the measurements being plotted covers
                a large range of values; a log scale can bring out features in the
                measurements that would not easily be seen if the measurement is plotted
                linearly.
                """.format(
                LINEAR="linear",
                LOG_NATURAL="log",
            )),
        )

        self.title = Text(
            text="Enter a title for the plot, if desired",
            value="",
            doc=textwrap.dedent("""\
                Enter a title for the plot. If you leave this blank, the title will
                default to *(cycle N)* where *N* is the current image cycle being
                executed.
                """),
        )

        self.wants_xbounds = Binary(
            text="Specify min/max bounds for the X-axis?",
            value=False,
            doc=textwrap.dedent("""\
                Select "**{YES}**" to specify minimum and maximum values for the plot on
                the X-axis. This is helpful if an outlier bin skews the plot such that
                the bins of interest are no longer visible.
                """.format(YES="Yes")),
        )

        self.xbounds = FloatRange(
            text="Minimum/maximum values for the X-axis",
            doc="Set lower/upper limits for X-axis of the histogram.",
        )
Esempio n. 17
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)
Esempio n. 18
0
    def create_settings(self):
        self.objects_or_image = Choice(
            "Display object or image measurements?",
            [OI_OBJECTS, OI_IMAGE],
            doc="""\
-  *%(OI_IMAGE)s* allows you to select an image measurement to display
   for each well.
-  *%(OI_OBJECTS)s* allows you to select an object measurement to
   display for each well.
""" % globals(),
        )

        self.object = LabelSubscriber(
            "Select the object whose measurements will be displayed",
            "None",
            doc="""\
Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**)
whose measurements are to be displayed.
""",
        )

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

        self.plate_name = Measurement(
            "Select your plate metadata",
            lambda: IMAGE,
            "Metadata_Plate",
            doc="""\
Choose the metadata tag that corresponds to the plate identifier. That
is, each plate should have a metadata tag containing a specifier
corresponding uniquely to that plate.

{meta_help}
""".format(meta_help=USING_METADATA_HELP_REF),
        )

        self.plate_type = Choice(
            "Multiwell plate format",
            ["96", "384"],
            doc="""\
The module assumes that your data is laid out in a multi-well plate
format common to high-throughput biological screens. Supported formats
are:

-  *96:* A 96-well plate with 8 rows × 12 columns
-  *384:* A 384-well plate with 16 rows × 24 columns
""",
        )

        self.well_format = Choice(
            "Well metadata format",
            [WF_NAME, WF_ROWCOL],
            doc="""\
-  *%(WF_NAME)s* allows you to select an image measurement to display
   for each well.
-  *%(WF_ROWCOL)s* allows you to select an object measurement to
   display for each well.
""" % globals(),
        )

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

%(USING_METADATA_HELP_REF)s
""" % globals(),
        )

        self.well_row = Measurement(
            "Select your well row metadata",
            lambda: IMAGE,
            "Metadata_WellRow",
            doc="""\
Choose the metadata tag that corresponds to the well row identifier,
typically specified as an alphabetical character. For example, a
standard format 96-well plate would span from row “A” to “H”, whereas a
384-well plate (16 rows and 24 columns) would span from row “A” to “P”.

%(USING_METADATA_HELP_REF)s
""" % globals(),
        )

        self.well_col = Measurement(
            "Select your well column metadata",
            lambda: IMAGE,
            "Metadata_WellCol",
            doc="""\
Choose the metadata tag that corresponds to the well column identifier,
typically specified with two integer characters. For example, a standard
format 96-well plate would span from column “01” to “12”, whereas a
384-well plate (16 rows and 24 columns) would span from column “01” to
“24”.

{meta_help}
""".format(meta_help=USING_METADATA_HELP_REF),
        )

        self.agg_method = Choice(
            "How should the values be aggregated?",
            AGG_NAMES,
            AGG_NAMES[0],
            doc="""\
Measurements must be aggregated to a single number for each well so that
they can be represented by a color. Options are:

-  *%(AGG_AVG)s:* Average
-  *%(AGG_STDEV)s:* Standard deviation
-  *%(AGG_MEDIAN)s*
-  *%(AGG_CV)s:* Coefficient of variation, defined as the ratio of the
   standard deviation to the mean. This is useful for comparing between
   data sets with different units or widely different means.
""" % globals(),
        )

        self.title = Text(
            "Enter a title for the plot, if desired",
            "",
            doc="""\
Enter a title for the plot. If you leave this blank, the title will
default to *(cycle N)* where *N* is the current image cycle being
executed.
""",
        )
Esempio n. 19
0
    def create_settings(self):
        self.save_image_or_figure = Choice(
            "Select the type of image to save",
            IF_ALL,
            IF_IMAGE,
            doc="""\
The following types of images can be saved as a file on the hard drive:

-  *{IF_IMAGE}:* Any of the images produced upstream of **SaveImages**
   can be selected for saving. Outlines of objects created by other
   modules such as **Identify** modules, **Watershed**, and various object
   processing modules can also be saved with this option, but you must
   use the **OverlayOutlines** module to create them prior to saving images.
   Likewise, if you wish to save the objects themselves, you must use the
   **ConvertObjectsToImage** module to create a savable image.
-  *{IF_MASK}:* Relevant only if a module that produces masks has been used
   such as **Crop**, **MaskImage**, or **MaskObjects**. These
   modules create a mask of the pixels of interest in the
   image. Saving the mask will produce a binary image in which the
   pixels of interest are set to 1; all other pixels are set to 0.
-  *{IF_CROPPING}:* Relevant only if the **Crop** module is used. The
   **Crop** module also creates a cropping image which is typically the
   same size as the original image. However, since **Crop** permits
   removal of the rows and columns that are left blank, the cropping can
   be of a different size than the mask.
-  *{IF_MOVIE}:* A sequence of images can be saved as a TIFF stack.
            """.format(
                **{
                    "IF_CROPPING": IF_CROPPING,
                    "IF_IMAGE": IF_IMAGE,
                    "IF_MASK": IF_MASK,
                    "IF_MOVIE": IF_MOVIE,
                }
            ),
        )

        self.image_name = ImageSubscriber(
            "Select the image to save", doc="Select the image you want to save."
        )

        self.file_name_method = Choice(
            "Select method for constructing file names",
            [FN_FROM_IMAGE, FN_SEQUENTIAL, FN_SINGLE_NAME],
            FN_FROM_IMAGE,
            doc="""\
*(Used only if saving non-movie files)*

Several choices are available for constructing the image file name:

-  *{FN_FROM_IMAGE}:* The filename will be constructed based on the
   original filename of an input image specified in **NamesAndTypes**.
   You will have the opportunity to prefix or append additional text.

   If you have metadata associated with your images, you can append
   text to the image filename using a metadata tag. This is especially
   useful if you want your output given a unique label according to the
   metadata corresponding to an image group. The name of the metadata to
   substitute can be provided for each image for each cycle using the
   **Metadata** module.
-  *{FN_SEQUENTIAL}:* Same as above, but in addition, each filename
   will have a number appended to the end that corresponds to the image
   cycle number (starting at 1).
-  *{FN_SINGLE_NAME}:* A single name will be given to the file. Since
   the filename is fixed, this file will be overwritten with each cycle.
   In this case, you would probably want to save the image on the last
   cycle (see the *Select how often to save* setting). The exception to
   this is to use a metadata tag to provide a unique label, as mentioned
   in the *{FN_FROM_IMAGE}* option.

{USING_METADATA_TAGS_REF}

{USING_METADATA_HELP_REF}
""".format(
                **{
                    "FN_FROM_IMAGE": FN_FROM_IMAGE,
                    "FN_SEQUENTIAL": FN_SEQUENTIAL,
                    "FN_SINGLE_NAME": FN_SINGLE_NAME,
                    "USING_METADATA_HELP_REF": _help.USING_METADATA_HELP_REF,
                    "USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF,
                }
            ),
        )

        self.file_image_name = FileImageSubscriber(
            "Select image name for file prefix",
            "None",
            doc="""\
*(Used only when “{FN_FROM_IMAGE}” is selected for constructing the filename)*

Select an image loaded using **NamesAndTypes**. The original filename
will be used as the prefix for the output filename.""".format(
                **{"FN_FROM_IMAGE": FN_FROM_IMAGE}
            ),
        )

        self.single_file_name = Text(
            SINGLE_NAME_TEXT,
            "OrigBlue",
            metadata=True,
            doc="""\
*(Used only when “{FN_SEQUENTIAL}” or “{FN_SINGLE_NAME}” are selected
for constructing the filename)*

Specify the filename text here. If you have metadata associated with
your images, enter the filename text with the metadata tags.
{USING_METADATA_TAGS_REF}
Do not enter the file extension in this setting; it will be appended
automatically.""".format(
                **{
                    "FN_SEQUENTIAL": FN_SEQUENTIAL,
                    "FN_SINGLE_NAME": FN_SINGLE_NAME,
                    "USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF,
                }
            ),
        )

        self.number_of_digits = Integer(
            "Number of digits",
            4,
            doc="""\
*(Used only when “{FN_SEQUENTIAL}” is selected for constructing the filename)*

Specify the number of digits to be used for the sequential numbering.
Zeros will be used to left-pad the digits. If the number specified here
is less than that needed to contain the number of image sets, the latter
will override the value entered.""".format(
                **{"FN_SEQUENTIAL": FN_SEQUENTIAL}
            ),
        )

        self.wants_file_name_suffix = Binary(
            "Append a suffix to the image file name?",
            False,
            doc="""\
Select "*{YES}*" to add a suffix to the image’s file name. Select "*{NO}*"
to use the image name as-is.
            """.format(
                **{"NO": "No", "YES": "Yes"}
            ),
        )

        self.file_name_suffix = Text(
            "Text to append to the image name",
            "",
            metadata=True,
            doc="""\
*(Used only when constructing the filename from the image filename)*

Enter the text that should be appended to the filename specified above.
If you have metadata associated with your images, you may use metadata tags.

{USING_METADATA_TAGS_REF}

Do not enter the file extension in this setting; it will be appended
automatically.
""".format(
                **{"USING_METADATA_TAGS_REF": _help.USING_METADATA_TAGS_REF}
            ),
        )

        self.file_format = Choice(
            "Saved file format",
            [FF_JPEG, FF_NPY, FF_PNG, FF_TIFF, FF_H5],
            value=FF_TIFF,
            doc="""\
*(Used only when saving non-movie files)*

Select the format to save the image(s).

Only *{FF_TIFF}* supports saving as 16-bit or 32-bit. *{FF_TIFF}* is a
"lossless" file format.

*{FF_PNG}* is also a "lossless" file format and it tends to produce
smaller files without losing any image data.

*{FF_JPEG}* is also small but is a "lossy" file format and should not be
used for any images that will undergo further quantitative analysis.

Select *{FF_NPY}* to save an illumination correction image generated by
**CorrectIlluminationCalculate**.

Select *{FF_H5}* to save files to be used for Ilastik pixel classificaiton.
The images should be correctly recognized as yxcz images.""".format(
                **{
                    "FF_NPY": FF_NPY,
                    "FF_TIFF": FF_TIFF,
                    "FF_PNG": FF_PNG,
                    "FF_JPEG": FF_JPEG,
                    "FF_H5": FF_H5,
                }
            ),
        )

        self.pathname = SaveImagesDirectoryPath(
            "Output file location",
            self.file_image_name,
            doc="""\
This setting lets you choose the folder for the output files.
{IO_FOLDER_CHOICE_HELP_TEXT}

An additional option is the following:

-  *Same folder as image*: Place the output file in the same folder that
   the source image is located.

{IO_WITH_METADATA_HELP_TEXT}

If the subfolder does not exist when the pipeline is run, CellProfiler
will create it.

If you are creating nested subfolders using the sub-folder options, you
can specify the additional folders separated with slashes. For example,
“Outlines/Plate1” will create a “Plate1” folder in the “Outlines”
folder, which in turn is under the Default Input/Output Folder. The use
of a forward slash (“/”) as a folder separator will avoid ambiguity
between the various operating systems.
""".format(
                **{
                    "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT,
                    "IO_WITH_METADATA_HELP_TEXT": _help.IO_WITH_METADATA_HELP_TEXT,
                }
            ),
        )

        self.bit_depth = Choice(
            "Image bit depth",
            [BIT_DEPTH_8, BIT_DEPTH_16, BIT_DEPTH_FLOAT, BIT_DEPTH_RAW],
            doc=f"""\
Select the bit-depth at which you want to save the images.

*{BIT_DEPTH_FLOAT}* saves the image as floating-point decimals with
32-bit precision. When the input data is integer or binary type, pixel
values are scaled within the range (0, 1). Floating point data is not
rescaled.

*{BIT_DEPTH_16}* and *{BIT_DEPTH_FLOAT}* images are supported only for
TIFF formats.

Data is normally checked and transformed to ensure that it matches the 
selected format's requirements. Selecting *{BIT_DEPTH_RAW}* will attempt 
to automatically save to a compatible format without applying any 
transformations to the data. This could be used to save integer labels 
in 32-bit float format if you had more labels than the 16-bit format can 
handle (without rescaling to the 0-1 range of *{BIT_DEPTH_FLOAT}*). 
Note that because the data validation step is skipped some images may 
fail to save if they contain unusable data.

Note: Opening exported multichannel 16-bit TIFF stacks in ImageJ may require  
the BioFormats Importer plugin due to the compression method used by
CellProfiler.""",
        )

        self.tiff_compress = Binary(
            "Save with lossless compression?",
            value=True,
            doc="""\
*(Used only when saving 2D images as file type tiff)*

Choose whether or not to use lossless compression when saving
images. This will lead to smaller file sizes, but somewhat longer 
module execution time.  Note that the value of this setting will
be ignored when saving 3D tiff images, which have been saved by
default with compression since CellProfiler 3.1. Do not use for
multichannel tiff images created as Stacks in GrayToColor."""
        )

        self.stack_axis = Choice(
            "How to save the series",
            [AXIS_T, AXIS_Z],
            value=AXIS_T,
            doc="""\
*(Used only when saving movie/stack files)*

This setting determines how planes are saved into a movie/stack.
Selecting "T" will save planes as a time series. Selecting "Z"
will save planes as slices in a 3D z-axis. 
""",
        )

        self.overwrite = Binary(
            "Overwrite existing files without warning?",
            False,
            doc="""\
Select "*{YES}*" to automatically overwrite a file if it already exists.
Select "*{NO}*" to be prompted for confirmation first.

If you are running the pipeline on a computing cluster, select "*{YES}*"
since you will not be able to intervene and answer the confirmation
prompt.""".format(
                **{"NO": "No", "YES": "Yes"}
            ),
        )

        self.when_to_save = Choice(
            "When to save",
            [WS_EVERY_CYCLE, WS_FIRST_CYCLE, WS_LAST_CYCLE],
            WS_EVERY_CYCLE,
            doc="""\
*(Used only when saving non-movie files)*

Specify at what point during pipeline execution to save file(s).

-  *{WS_EVERY_CYCLE}:* Useful for when the image of interest is
   created every cycle and is not dependent on results from a prior
   cycle.
-  *{WS_FIRST_CYCLE}:* Useful for when you are saving an aggregate
   image created on the first cycle, e.g.,
   **CorrectIlluminationCalculate** with the *All* setting used on
   images obtained directly from **NamesAndTypes**.
-  *{WS_LAST_CYCLE}:* Useful for when you are saving an aggregate image
   completed on the last cycle, e.g., **CorrectIlluminationCalculate**
   with the *All* setting used on intermediate images generated during
   each cycle.""".format(
                **{
                    "WS_EVERY_CYCLE": WS_EVERY_CYCLE,
                    "WS_FIRST_CYCLE": WS_FIRST_CYCLE,
                    "WS_LAST_CYCLE": WS_LAST_CYCLE,
                }
            ),
        )

        self.update_file_names = Binary(
            "Record the file and path information to the saved image?",
            False,
            doc="""\
Select "*{YES}*" to store filename and pathname data for each of the new
files created via this module as a per-image measurement.

Instances in which this information may be useful include:

-  Exporting measurements to a database, allowing access to the saved
   image. If you are using the machine-learning tools or image viewer in
   CellProfiler Analyst, for example, you will want to enable this
   setting if you want the saved images to be displayed along with the
   original images.""".format(
                **{"YES": "Yes"}
            ),
        )

        self.create_subdirectories = Binary(
            "Create subfolders in the output folder?",
            False,
            doc="""
Select "*{YES}*" to create subfolders to match the input image folder structure. 
            
For example, if your input images are organized into subfolders (e.g., for each plate, well, animal, etc.), 
this option allows you to mirror some or all of that nested folder structure in the output folder.""".format(
                **{"YES": "Yes"}
            ),
        )

        self.root_dir = Directory(
            "Base image folder",
            doc="""\
*Used only if creating subfolders in the output folder*

In subfolder mode, **SaveImages** determines the folder for an output image file by
examining the path of the matching input file. 

You should choose as **Base image folder** the input folder that has the structure you'd like 
to mirror in the output folder. 

Consider an example where your input images are stored in a nested folder structure of 
"images\/experiment-name\/plate-name" (i.e., your files are in folders for each plate, nested
inside of folders for each experiment, nested in a parent folder called "images"). 
If you select the base image folder to be **images**, **SaveImages** will go to your "Output file
location" and save images in subfolders "experiment-name\/plate-name" that corresponds to each 
input image. If the base image folder chosen is one level deeper at "images\/experiment-name", 
**SaveImages** will store images in subfolders for each "plate-name" they belong to.

**Warning**: Do not select the same folder you selected for "Output file location" as this can lead
to unexpected behavior like saving in the original input file directory. For safety, ensure 
"Overwrite existing files without warning?" is set to "No" while testing this option. """,
        )
Esempio n. 20
0
    def create_settings(self):
        self.x_object = LabelSubscriber(
            "Select the object to display on the X-axis",
            "None",
            doc="""\
Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose
measurements are to be displayed on the X-axis.
""",
        )

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

        self.y_object = LabelSubscriber(
            "Select the object to display on the Y-axis",
            "None",
            doc="""\
Choose the name of objects identified by some previous module (such as
**IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose
measurements are to be displayed on the Y-axis.
""",
        )

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

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

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

Using a log scaling is useful when one of the measurements being plotted
covers a large range of values; a log scale can bring out features in
the measurements that would not easily be seen if the measurement is
plotted linearly.
""",
        )

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

Using a log scaling is useful when one of the measurements being plotted
covers a large range of values; a log scale can bring out features in
the measurements that would not easily be seen if the measurement is
plotted linearly.
""",
        )

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

Using a log scaling is useful when one of the measurements being plotted
covers a large range of values; a log scale can bring out features in
the measurements that would not easily be seen if the measurement is
plotted linearly.
""",
        )

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

        self.colormap = Choice(
            "Select the color map",
            maps,
            "jet",
            doc="""\
Select the color map for the density plot. See `this page`_ for pictures
of the available colormaps.

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

        self.title = Text(
            "Enter a title for the plot, if desired",
            "",
            doc="""\
Enter a title for the plot. If you leave this blank, the title will
default to *(cycle N)* where *N* is the current image cycle being
executed.
""",
        )
Esempio n. 21
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. 22
0
    def create_settings(self):
        """Create the UI settings for the module"""
        self.seed_objects_name = LabelSubscriber(
            "Select the seed objects",
            "None",
            doc="""\
Select the previously identified objects that you want to use as the
seeds for measuring branches and distances. Branches and trunks are assigned
per seed object. Seed objects are typically not single points/pixels but
instead are usually objects of varying sizes.""",
        )

        self.image_name = ImageSubscriber(
            "Select the skeletonized image",
            "None",
            doc="""\
Select the skeletonized image of the dendrites and/or axons as produced
by the **Morph** module’s *Skel* operation.""",
        )

        self.wants_branchpoint_image = Binary(
            "Retain the branchpoint image?",
            False,
            doc="""\
Select "*Yes*" if you want to save the color image of branchpoints and
trunks. This is the image that is displayed in the output window for
this module."""
            % globals(),
        )

        self.branchpoint_image_name = ImageName(
            "Name the branchpoint image",
            "BranchpointImage",
            doc="""\
*(Used only if a branchpoint image is to be retained)*

Enter a name for the branchpoint image here. You can then use this image
in a later module, such as **SaveImages**.""",
        )

        self.wants_to_fill_holes = Binary(
            "Fill small holes?",
            True,
            doc="""\
The algorithm reskeletonizes the image and this can leave artifacts
caused by small holes in the image prior to skeletonizing. These holes
result in false trunks and branchpoints. Select "*Yes*" to fill in
these small holes prior to skeletonizing."""
            % globals(),
        )

        self.maximum_hole_size = Integer(
            "Maximum hole size",
            10,
            minval=1,
            doc="""\
*(Used only when filling small holes)*

This is the area of the largest hole to fill, measured in pixels. The
algorithm will fill in any hole whose area is this size or smaller.""",
        )

        self.wants_objskeleton_graph = Binary(
            "Export the skeleton graph relationships?",
            False,
            doc="""\
Select "*Yes*" to produce an edge file and a vertex file that gives the
relationships between vertices (trunks, branchpoints and endpoints)."""
            % globals(),
        )

        self.intensity_image_name = ImageSubscriber(
            "Intensity image",
            "None",
            doc="""\
Select the image to be used to calculate
the total intensity along the edges between the vertices (trunks, branchpoints, and endpoints).""",
        )

        self.directory = Directory(
            "File output directory",
            doc="Select the directory you want to save the graph relationships to.",
            dir_choices=[
                DEFAULT_OUTPUT_FOLDER_NAME,
                DEFAULT_INPUT_FOLDER_NAME,
                ABSOLUTE_FOLDER_NAME,
                DEFAULT_OUTPUT_SUBFOLDER_NAME,
                DEFAULT_INPUT_SUBFOLDER_NAME,
            ],
        )
        self.directory.dir_choice = DEFAULT_OUTPUT_FOLDER_NAME

        self.vertex_file_name = Text(
            "Vertex file name",
            "vertices.csv",
            doc="""\
*(Used only when exporting graph relationships)*

Enter the name of the file that will hold the edge information. You can
use metadata tags in the file name.

Each line of the file is a row of comma-separated values. The first
row is the header; this names the file’s columns. Each subsequent row
represents a vertex in the skeleton graph: either a trunk, a
branchpoint or an endpoint. The file has the following columns:

-  *image\_number:* The image number of the associated image.
-  *vertex\_number:* The number of the vertex within the image.
-  *i:* The I coordinate of the vertex.
-  *j:* The J coordinate of the vertex.
-  *label:* The label of the seed object associated with the vertex.
-  *kind:* The vertex type, with the following choices:

   -  **T:** Trunk
   -  **B:** Branchpoint
   -  **E:** Endpoint
""",
        )

        self.edge_file_name = Text(
            "Edge file name",
            "edges.csv",
            doc="""\
*(Used only when exporting graph relationships)*

Enter the name of the file that will hold the edge information. You can
use metadata tags in the file name. Each line of the file is a row of
comma-separated values. The first row is the header; this names the
file’s columns. Each subsequent row represents an edge or connection
between two vertices (including between a vertex and itself for certain
loops). Note that vertices include trunks, branchpoints, and endpoints.

The file has the following columns:

-  *image\_number:* The image number of the associated image.
-  *v1:* The zero-based index into the vertex table of the first vertex
   in the edge.
-  *v2:* The zero-based index into the vertex table of the second vertex
   in the edge.
-  *length:* The number of pixels in the path connecting the two
   vertices, including both vertex pixels.
-  *total\_intensity:* The sum of the intensities of the pixels in the
   edge, including both vertex pixel intensities.
""",
        )