def create_settings(self): """Create the settings for the module at startup. """ self.image_groups = [] self.image_count = cps.HiddenCount(self.image_groups) self.add_image_cb(can_remove=False) self.add_images = DoSomething("", "Add another image", self.add_image_cb) self.image_divider = cps.Divider() self.object_groups = [] self.object_count = cps.HiddenCount(self.object_groups) self.add_object_cb(can_remove=True) self.add_objects = DoSomething("", "Add another object", self.add_object_cb) self.object_divider = cps.Divider() self.moms = MultiChoice( "Moments to compute", MOM_ALL, MOM_ALL, doc= """Moments are statistics describing the distribution of values in the set of pixels of interest: <p><ul> <li><i>%(MOM_1)s</i> - the first image moment, which corresponds to the central value of the collection of pixels of interest.</li> <li><i>%(MOM_2)s</i> - the second image moment, which measures the amount of variation or dispersion of pixel values about its mean.</li> <li><i>%(MOM_3)s</i> - a scaled version of the third moment, which measures the asymmetry of the pixel values distribution about its mean.</li> <li><i>%(MOM_4)s</i> - a scaled version of the fourth moment, which measures the "peakedness" of the pixel values distribution.</li> </ul><p> Choose one or more moments to measure.""" % globals())
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): """Create the settings for the module at startup. The module allows for an unlimited number of measured objects, each of which has an entry in self.object_groups. """ self.image_groups = [] self.object_groups = [] self.scale_groups = [] self.image_count = cps.HiddenCount(self.image_groups) self.object_count = cps.HiddenCount(self.object_groups) self.scale_count = cps.HiddenCount(self.scale_groups) self.add_image_cb(can_remove = False) self.add_images = DoSomething("", "Add another image", self.add_image_cb) self.image_divider = cps.Divider() self.add_object_cb(can_remove = True) self.add_objects = DoSomething("", "Add another object", self.add_object_cb) self.object_divider = cps.Divider() self.add_scale_cb(can_remove = False) self.add_scales = DoSomething("", "Add another scale", self.add_scale_cb) self.scale_divider = cps.Divider() self.wants_gabor = cps.Binary( "Measure Gabor features?", True, doc = """The Gabor features measure striped texture in an object. They take a substantial time to calculate. Check this setting to measure the Gabor features. Uncheck this setting to skip the Gabor feature calculation if it is not informative for your images""") self.gabor_angles = Integer("Number of angles to compute for Gabor",4,2, doc=""" <i>(Used only if Gabor features are measured)</i><br> How many angles do you want to use for each Gabor texture measurement? The default value is 4 which detects bands in the horizontal, vertical and diagonal orientations.""") self.gabor_divider = cps.Divider() self.wants_tamura = cps.Binary( "Measure Tamura features?", True, doc = """The Tamura features are very ugly.""") self.tamura_feats=MultiChoice( "Features to compute", F_ALL, F_ALL, doc = """Tamura Features: <p><ul> <li><i>%(F_1)s</i> - bla.</li> <li><i>%(F_2)s</i> - bla.</li> <li><i>%(F_3)s</i> - bla.</li> </ul><p> Choose one or more features to compute.""" % globals())
def create_settings(self): self.image_name = ImageSubscriber( "Select the input image", "None", doc="""\ Select the image that you want to perform a morphological operation on. A grayscale image can be converted to binary using the **Threshold** module. Objects can be converted to binary using the **ConvertToImage** module.""", ) self.output_image_name = ImageName( "Name the output image", "MorphBlue", doc="""Enter the name for the output image. It will be of the same type as the input image.""", ) self.add_button = DoSomething( "", "Add another operation", self.add_function, doc="""\ Press this button to add an operation that will be applied to the image resulting from the previous operation(s). The module repeats the previous operation the number of times you select before applying the operation added by this button.""", ) self.functions = [] self.add_function(can_remove=False)
def create_settings(self): """Make settings here (and set the module name)""" self.images = [] self.add_image(can_delete=False) self.add_image_button = DoSomething("", "Add another image", self.add_image) self.clip = Binary("Clip intensity values", False, doc="Clip the values in the illumination function between 0 and 1")
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): self.outputs = [] self.stain_count = HiddenCount(self.outputs, "Stain count") self.input_image_name = ImageSubscriber( "Select the input color image", "None", doc="""\ Choose the name of the histologically stained color image loaded or created by some prior module.""", ) self.add_image(False) self.add_image_button = DoSomething( "", "Add another stain", self.add_image, doc="""\ Press this button to add another stain to the list. You will be able to name the image produced and to either pick the stain from a list of pre-calibrated stains or to enter custom values for the stain's red, green and blue absorbance. """, )
def create_settings(self): """Create the settings for the module at startup. """ self.image_groups = [] self.image_count = cps.HiddenCount(self.image_groups) self.add_image_cb(can_remove=False) self.add_images = DoSomething("", "Add another image", self.add_image_cb) self.image_divider = cps.Divider() self.object_groups = [] self.object_count = cps.HiddenCount(self.object_groups) self.add_object_cb(can_remove=True) self.add_objects = DoSomething("", "Add another object", self.add_object_cb) self.object_divider = cps.Divider() self.bins_groups = [] self.bins_count = cps.HiddenCount(self.bins_groups) self.add_bins_cb(can_remove=False) self.add_bins = DoSomething("", "Add another histogram", self.add_bins_cb)
def create_settings(self): """Create your settings by subclassing this function create_settings is called at the end of initialization. You should create the setting variables for your module here: # Ask the user for the input image self.image_name = .ImageSubscriber(...) # Ask the user for the name of the output image self.output_image = .ImageName(...) # Ask the user for a parameter self.smoothing_size = .Float(...)""" self.grouping_values = Measurement( "Select the image measurement describing the positive and negative control status", lambda: IMAGE, doc="""\ The Z’ factor, a measure of assay quality, is calculated by this module based on measurements from images that are specified as positive controls and images that are specified as negative controls. Images that are neither are ignored. The module assumes that all of the negative controls are specified by a minimum value, all of the positive controls are specified by a maximum value, and all other images have an intermediate value; this might allow you to use your dosing information to also specify the positive and negative controls. If you don’t use actual dose data to designate your controls, a common practice is to designate -1 as a negative control, 0 as an experimental sample, and 1 as a positive control. In other words, positive controls should all be specified by a single high value (for instance, 1) and negative controls should all be specified by a single low value (for instance, -1). Other samples should have an intermediate value to exclude them from the Z’ factor analysis. The typical way to provide this information in the pipeline is to create a text comma-delimited (CSV) file outside of CellProfiler and then load that file into the pipeline using the **Metadata** module or the legacy **LoadData** module. In that case, choose the measurement that matches the column header of the measurement in the input file. See the main module help for this module or for the **Metadata** module for an example text file. """, ) self.dose_values = [] self.add_dose_value(can_remove=False) self.add_dose_button = DoSomething( "", "Add another dose specification", self.add_dose_value )
def create_settings(self): self.flags = [] self.flag_count = HiddenCount(self.flags) self.add_flag_button = DoSomething("", "Add another flag", self.add_flag) self.spacer_1 = Divider() self.add_flag(can_delete=False) self.ignore_flag_on_last = Binary( "Ignore flag skips on last cycle?", False, doc="""\ When set to *{YES}*, this option allows you to bypass skipping on the last cycle of an image group. This behavior is usually not desired, but may be useful when using SaveImages 'Save on last cycle' option for an image made by any other module than MakeProjection, CorrectIlluminationCalculate, and Tile. """.format(**{"YES": "Yes"}), )
def create_settings(self): """Make settings here (and set the module name)""" self.images = [] self.add_image(can_delete=False) self.add_image_button = DoSomething("", "Add another image", self.add_image) self.truncate_low = Binary( "Set output image values less than 0 equal to 0?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *"Yes"* to set negative values to 0, which was previously done automatically without ability to override. """) self.truncate_high = Binary( "Set output image values greater than 1 equal to 1?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *"Yes"* to set values greater than 1 to a maximum value of 1. """)
def create_settings(self): super(Resize, self).create_settings() self.size_method = Choice( "Resizing method", R_ALL, doc="""\ The following options are available: - *Resize by a fraction or multiple of the original size:* Enter a single value which specifies the scaling. - *Resize by specifying desired final dimensions:* Enter the new height and width of the resized image, in units of pixels.""", ) self.resizing_factor = Float( "Resizing factor", 0.25, minval=0, doc="""\ *(Used only if resizing by a fraction or multiple of the original size)* Numbers less than one (that is, fractions) will shrink the image; numbers greater than one (that is, multiples) will enlarge the image.""", ) self.use_manual_or_image = Choice( "Method to specify the dimensions", C_ALL, doc="""\ *(Used only if resizing by specifying the dimensions)* You have two options on how to resize your image: - *{C_MANUAL}:* Specify the height and width of the output image. - *{C_IMAGE}:* Specify an image and the input image will be resized to the same dimensions. """.format( **{"C_IMAGE": C_IMAGE, "C_MANUAL": C_MANUAL} ), ) self.specific_width = Integer( "Width of the final image", 100, minval=1, doc="""\ *(Used only if resizing by specifying desired final dimensions)* Enter the desired width of the final image, in pixels.""", ) self.specific_height = Integer( "Height of the final image", 100, minval=1, doc="""\ *(Used only if resizing by specifying desired final dimensions)* Enter the desired height of the final image, in pixels.""", ) self.specific_image = ImageSubscriber( "Select the image with the desired dimensions", "None", doc="""\ *(Used only if resizing by specifying desired final dimensions using an image)* The input image will be resized to the dimensions of the specified image.""", ) self.interpolation = Choice( "Interpolation method", I_ALL, doc="""\ - *Nearest Neighbor:* Each output pixel is given the intensity of the nearest corresponding pixel in the input image. - *Bilinear:* Each output pixel is given the intensity of the weighted average of the 2x2 neighborhood at the corresponding position in the input image. - *Bicubic:* Each output pixel is given the intensity of the weighted average of the 4x4 neighborhood at the corresponding position in the input image.""", ) self.separator = Divider(line=False) self.additional_images = [] self.additional_image_count = HiddenCount( self.additional_images, "Additional image count" ) self.add_button = DoSomething("", "Add another image", self.add_image)
def add_flag(self, can_delete=True): group = SettingsGroup() group.append("divider1", Divider(line=False)) group.append("measurement_settings", []) group.append("measurement_count", HiddenCount(group.measurement_settings)) group.append( "category", Text( "Name the flag's category", "Metadata", doc="""\ Name a measurement category by which to categorize the flag. The *Metadata* category is the default used in CellProfiler to store information about images (referred to as *metadata*). The flag is stored as a per-image measurement whose name is a combination of the flag’s category and the flag name that you choose, separated by underscores. For instance, if the measurement category is *Metadata* and the flag name is *QCFlag*, then the default measurement name would be *Metadata_QCFlag*. """, ), ) group.append( "feature_name", Text( "Name the flag", "QCFlag", doc="""\ The flag is stored as a per-image measurement whose name is a combination of the flag’s category and the flag name that you choose, separated by underscores. For instance, if the measurement category is *Metadata* and the flag name is *QCFlag*, then the default measurement name would be *Metadata_QCFlag*. """, ), ) group.append( "combination_choice", Choice( "How should measurements be linked?", [C_ANY, C_ALL], doc="""\ For combinations of measurements, you can set the criteria under which an image set is flagged: - *%(C_ANY)s:* An image set will be flagged if any of its measurements fail. This can be useful for flagging images possessing multiple QC flaws; for example, you can flag all bright images and all out of focus images with one flag. - *%(C_ALL)s:* A flag will only be assigned if all measurements fail. This can be useful for flagging images that possess only a combination of QC flaws; for example, you can flag only images that are both bright and out of focus. """ % globals(), ), ) group.append( "wants_skip", Binary( "Skip image set if flagged?", False, doc="""\ Select *Yes* to skip the remainder of the pipeline for image sets that are flagged. CellProfiler will not run subsequent modules in the pipeline on the images for any image set that is flagged. Select *No* for CellProfiler to continue to process the pipeline regardless of flagging. You may want to skip processing in order to filter out unwanted images. For instance, you may want to exclude out of focus images when running **CorrectIllumination_Calculate**. You can do this with a pipeline that measures image quality and flags inappropriate images before it runs **CorrectIllumination_Calculate**. """ % globals(), ), ) group.append( "add_measurement_button", DoSomething( "", "Add another measurement", self.add_measurement, group, doc="""Add another measurement as a criteria.""", ), ) self.add_measurement(group, False if not can_delete else True) if can_delete: group.append( "remover", RemoveSettingButton("", "Remove this flag", self.flags, group), ) group.append("divider2", Divider(line=True)) self.flags.append(group)
def create_settings(self): super(RelateObjects, self).create_settings() self.x_name.text = "Parent objects" self.x_name.doc = """\ Parent objects are defined as those objects which encompass the child object. For example, when relating speckles to the nuclei that contain them, the nuclei are the parents. """ self.y_name = LabelSubscriber( "Child objects", doc="""\ Child objects are defined as those objects contained within the parent object. For example, when relating speckles to the nuclei that contains them, the speckles are the children. """, ) self.find_parent_child_distances = Choice( "Calculate child-parent distances?", D_ALL, doc="""\ Choose the method to calculate distances of each child to its parent. For example, these measurements can tell you whether nuclear speckles are located more closely to the center of the nucleus or to the nuclear periphery. - *{D_NONE}:* Do not calculate any distances. This saves computation time. - *{D_MINIMUM}:* The distance from the centroid of the child object to the closest perimeter point on the parent object. - *{D_CENTROID}:* The distance from the centroid of the child object to the centroid of the parent. - *{D_BOTH}:* Calculate both the *{D_MINIMUM}* and *{D_CENTROID}* distances.""".format( **{ "D_NONE": D_NONE, "D_MINIMUM": D_MINIMUM, "D_CENTROID": D_CENTROID, "D_BOTH": D_BOTH, }), ) self.wants_step_parent_distances = Binary( "Calculate distances to other parents?", False, doc="""\ *(Used only if calculating distances)* Select "*{YES}*" to calculate the distances of the child objects to some other objects. These objects must be either parents or children of your parent object in order for this module to determine the distances. For instance, you might find “Nuclei” using **IdentifyPrimaryObjects**, find “Cells” using **IdentifySecondaryObjects** and find “Cytoplasm” using **IdentifyTertiaryObjects**. You can use **Relate** to relate speckles to cells and then measure distances to nuclei and cytoplasm. You could not use **RelateObjects** to relate speckles to cytoplasm and then measure distances to nuclei, because nuclei are neither a direct parent nor child of cytoplasm.""".format(**{"YES": "Yes"}), ) self.step_parent_names = [] self.add_step_parent(can_delete=False) self.add_step_parent_button = DoSomething("", "Add another parent", self.add_step_parent) self.wants_per_parent_means = Binary( "Calculate per-parent means for all child measurements?", False, doc="""\ Select "*{YES}*" to calculate the per-parent mean values of every upstream measurement made with the children objects and store them as a measurement for the parent; the nomenclature of this new measurement is “Mean_<child>_<category>_<feature>”. This module must be placed *after* all **Measure** modules that make measurements of the children objects.""".format(**{"YES": "Yes"}), ) self.wants_child_objects_saved = Binary( "Do you want to save the children with parents as a new object set?", False, doc="""\ Select "*{YES}*" to save the children objects that do have parents as new object set. Objects with no parents will be discarded""".format( **{"YES": "Yes"}), ) self.output_child_objects_name = LabelName( "Name the output object", "RelateObjects", doc="""\ Enter the name you want to call the object produced by this module. """, )
def create_settings(self): self.blank_image = Binary( "Display outlines on a blank image?", False, doc="""\ Select "*{YES}*" to produce an image of the outlines on a black background. Select "*{NO}*" to overlay the outlines on an image you choose. """.format( **{"YES": "Yes", "NO": "No"} ), ) self.image_name = ImageSubscriber( "Select image on which to display outlines", "None", doc="""\ *(Used only when a blank image has not been selected)* Choose the image to serve as the background for the outlines. You can choose from images that were loaded or created by modules previous to this one. """, ) self.line_mode = Choice( "How to outline", ["Inner", "Outer", "Thick"], value="Inner", doc="""\ Specify how to mark the boundaries around an object: - *Inner:* outline the pixels just inside of objects, leaving background pixels untouched. - *Outer:* outline pixels in the background around object boundaries. When two objects touch, their boundary is also marked. - *Thick:* any pixel not completely surrounded by pixels of the same label is marked as a boundary. This results in boundaries that are 2 pixels thick. """, ) self.output_image_name = ImageName( "Name the output image", "OrigOverlay", doc="""\ Enter the name of the output image with the outlines overlaid. This image can be selected in later modules (for instance, **SaveImages**). """, ) self.wants_color = Choice( "Outline display mode", [WANTS_COLOR, WANTS_GRAYSCALE], doc="""\ Specify how to display the outline contours around your objects. Color outlines produce a clearer display for images where the cell borders have a high intensity, but take up more space in memory. Grayscale outlines are displayed with either the highest possible intensity or the same intensity as the brightest pixel in the image. """, ) self.spacer = Divider(line=False) self.max_type = Choice( "Select method to determine brightness of outlines", [MAX_IMAGE, MAX_POSSIBLE], doc="""\ *(Used only when outline display mode is grayscale)* The following options are possible for setting the intensity (brightness) of the outlines: - *{MAX_IMAGE}:* Set the brightness to the the same as the brightest point in the image. - *{MAX_POSSIBLE}:* Set to the maximum possible value for this image format. If your image is quite dim, then putting bright white lines onto it may not be useful. It may be preferable to make the outlines equal to the maximal brightness already occurring in the image. """.format( **{"MAX_IMAGE": MAX_IMAGE, "MAX_POSSIBLE": MAX_POSSIBLE} ), ) self.outlines = [] self.add_outline(can_remove=False) self.add_outline_button = DoSomething( "", "Add another outline", self.add_outline )
def create_settings(self): super(RunCellpose, self).create_settings() self.expected_diameter = Integer( text="Expected object diameter", value=15, minval=0, doc="""\ The average diameter of the objects to be detected. Setting this to 0 will attempt to automatically detect object size. Note that automatic diameter mode does not work when running on 3D images. Cellpose models come with a pre-defined object diameter. Your image will be resized during detection to attempt to match the diameter expected by the model. The default models have an expected diameter of ~16 pixels, if trying to detect much smaller objects it may be more efficient to resize the image first using the Resize module. """, ) self.mode = Choice( text="Detection mode", choices=[MODE_NUCLEI, MODE_CELLS, MODE_CUSTOM], value=MODE_NUCLEI, doc="""\ CellPose comes with models for detecting nuclei or cells. Alternatively, you can supply a custom-trained model generated using the command line or Cellpose GUI. Custom models can be useful if working with unusual cell types. """, ) self.use_gpu = Binary(text="Use GPU", value=False, doc=f"""\ If enabled, Cellpose will attempt to run detection on your system's graphics card (GPU). Note that you will need a CUDA-compatible GPU and correctly configured PyTorch version, see this link for details: {CUDA_LINK} If disabled or incorrectly configured, Cellpose will run on your CPU instead. This is much slower but more compatible with different hardware setups. Note that, particularly when in 3D mode, lack of GPU memory can become a limitation. If a model crashes you may need to re-start CellProfiler to release GPU memory. Resizing large images prior to running them through the model can free up GPU memory. """) self.use_averaging = Binary(text="Use averaging", value=True, doc="""\ If enabled, CellPose will run it's 4 inbuilt models and take a consensus to determine the results. If disabled, only a single model will be called to produce results. Disabling averaging is faster to run but less accurate.""" ) self.supply_nuclei = Binary(text="Supply nuclei image as well?", value=False, doc=""" When detecting whole cells, you can provide a second image featuring a nuclear stain to assist the model with segmentation. This can help to split touching cells.""") self.nuclei_image = ImageSubscriber( "Select the nuclei image", doc="Select the image you want to use as the nuclear stain.") self.save_probabilities = Binary( text="Save probability image?", value=False, doc=""" If enabled, the probability scores from the model will be recorded as a new image. Probability >0 is considered as being part of a cell. You may want to use a higher threshold to manually generate objects.""", ) self.probabilities_name = ImageName( "Name the probability image", "Probabilities", doc= "Enter the name you want to call the probability image produced by this module.", ) self.model_directory = Directory( "Location of the pre-trained model file", doc=f"""\ *(Used only when using a custom pre-trained model)* Select the location of the pre-trained CellPose model file that will be used for detection.""" ) def get_directory_fn(): """Get the directory for the rules file name""" return self.model_directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.model_directory.get_parts_from_path( path) self.model_directory.join_parts(dir_choice, custom_path) self.model_file_name = Filename("Pre-trained model file name", "cyto_0", get_directory_fn=get_directory_fn, set_directory_fn=set_directory_fn, doc=f"""\ *(Used only when using a custom pre-trained model)* This file can be generated by training a custom model withing the CellPose GUI or command line applications.""" ) self.gpu_test = DoSomething( "", "Test GPU", self.do_check_gpu, doc=f"""\ Press this button to check whether a GPU is correctly configured. If you have a dedicated GPU, a failed test usually means that either your GPU does not support deep learning or the required dependencies are not installed. If you have multiple GPUs on your system, this button will only test the first one. """, ) self.flow_threshold = Float( text="Flow threshold", value=0.4, minval=0, doc= """Flow error threshold. All cells with errors below this threshold are kept. Recommended default is 0.4""", ) self.dist_threshold = Float( text="Cell probability threshold", value=0.0, minval=0, doc=f"""\ Cell probability threshold (all pixels with probability above threshold kept for masks). Recommended default is 0.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)
def create_settings(self): """Make settings here (and set the module name)""" self.images = [] self.add_image(can_delete=False) self.add_image_button = DoSomething("", "Add another image", self.add_image)
def create_settings(self): super(FilterObjects, self).create_settings() self.x_name.text = """Select the objects to filter""" self.x_name.doc = """\ Select the set of objects that you want to filter. This setting also controls which measurement choices appear for filtering: you can only filter based on measurements made on the object you select. Be sure the **FilterObjects** module is downstream of the necessary **Measure** modules. If you intend to use a measurement calculated by the **CalculateMath** module to to filter objects, select the first operand’s object here, because **CalculateMath** measurements are stored with the first operand’s object.""" self.y_name.text = """Name the output objects""" self.y_name.doc = "Enter a name for the collection of objects that are retained after applying the filter(s)." self.spacer_1 = Divider(line=False) self.mode = Choice( "Select the filtering mode", [MODE_MEASUREMENTS, MODE_RULES, MODE_BORDER, MODE_CLASSIFIERS], doc="""\ You can choose from the following options: - *{MODE_MEASUREMENTS}*: Specify a per-object measurement made by an upstream module in the pipeline. - *{MODE_BORDER}*: Remove objects touching the border of the image and/or the edges of an image mask. - *{MODE_RULES}*: Use a file containing rules generated by CellProfiler Analyst. You will need to ensure that the measurements specified by the rules file are produced by upstream modules in the pipeline. This setting is not compatible with data processed as 3D. - *{MODE_CLASSIFIERS}*: Use a file containing a trained classifier from CellProfiler Analyst. You will need to ensure that the measurements specified by the file are produced by upstream modules in the pipeline. This setting is not compatible with data processed as 3D.""".format( **{ "MODE_MEASUREMENTS": MODE_MEASUREMENTS, "MODE_RULES": MODE_RULES, "MODE_BORDER": MODE_BORDER, "MODE_CLASSIFIERS": MODE_CLASSIFIERS, } ), ) self.spacer_2 = Divider(line=False) self.measurements = [] self.measurement_count = HiddenCount(self.measurements, "Measurement count") self.add_measurement(False) self.add_measurement_button = DoSomething( "", "Add another measurement", self.add_measurement ) self.filter_choice = Choice( "Select the filtering method", FI_ALL, FI_LIMITS, doc="""\ *(Used only if filtering using measurements)* There are five different ways to filter objects: - *{FI_LIMITS}:* Keep an object if its measurement value falls within a range you specify. - *{FI_MAXIMAL}:* Keep the object with the maximum value for the measurement of interest. If multiple objects share a maximal value, retain one object selected arbitrarily per image. - *{FI_MINIMAL}:* Keep the object with the minimum value for the measurement of interest. If multiple objects share a minimal value, retain one object selected arbitrarily per image. - *{FI_MAXIMAL_PER_OBJECT}:* This option requires you to choose a parent object. The parent object might contain several child objects of choice (for instance, mitotic spindles within a cell or FISH probe spots within a nucleus). Only the child object whose measurements equal the maximum child-measurement value among that set of child objects will be kept (for example, the longest spindle in each cell). You do not have to explicitly relate objects before using this module. - *{FI_MINIMAL_PER_OBJECT}:* Same as *Maximal per object*, except filtering is based on the minimum value.""".format( **{ "FI_LIMITS": FI_LIMITS, "FI_MAXIMAL": FI_MAXIMAL, "FI_MINIMAL": FI_MINIMAL, "FI_MAXIMAL_PER_OBJECT": FI_MAXIMAL_PER_OBJECT, "FI_MINIMAL_PER_OBJECT": FI_MINIMAL_PER_OBJECT, } ), ) self.per_object_assignment = Choice( "Assign overlapping child to", PO_ALL, doc="""\ *(Used only if filtering per object)* A child object can overlap two parent objects and can have the maximal/minimal measurement of all child objects in both parents. This option controls how an overlapping maximal/minimal child affects filtering of other children of its parents and to which parent the maximal child is assigned. The choices are: - *{PO_BOTH}*: The child will be assigned to both parents and all other children of both parents will be filtered. Only the maximal child per parent will be left, but if **RelateObjects** is used to relate the maximal child to its parent, one or the other of the overlapping parents will not have a child even though the excluded parent may have other child objects. The maximal child can still be assigned to both parents using a database join via the relationships table if you are using **ExportToDatabase** and separate object tables. - *{PO_PARENT_WITH_MOST_OVERLAP}*: The child will be assigned to the parent with the most overlap and a child with a less maximal/minimal measurement, if available, will be assigned to other parents. Use this option to ensure that parents with an alternate non-overlapping child object are assigned some child object by a subsequent **RelateObjects** module.""".format( **{ "PO_BOTH": PO_BOTH, "PO_PARENT_WITH_MOST_OVERLAP": PO_PARENT_WITH_MOST_OVERLAP, } ), ) self.enclosing_object_name = LabelSubscriber( "Select the objects that contain the filtered objects", "None", doc="""\ *(Used only if a per-object filtering method is selected)* This setting selects the container (i.e., parent) objects for the *{FI_MAXIMAL_PER_OBJECT}* and *{FI_MINIMAL_PER_OBJECT}* filtering choices.""".format( **{ "FI_MAXIMAL_PER_OBJECT": FI_MAXIMAL_PER_OBJECT, "FI_MINIMAL_PER_OBJECT": FI_MINIMAL_PER_OBJECT, } ), ) self.rules_directory = Directory( "Select the location of the rules or classifier file", doc="""\ *(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})* Select the location of the rules or classifier file that will be used for filtering. {IO_FOLDER_CHOICE_HELP_TEXT} """.format( **{ "MODE_CLASSIFIERS": MODE_CLASSIFIERS, "MODE_RULES": MODE_RULES, "IO_FOLDER_CHOICE_HELP_TEXT": _help.IO_FOLDER_CHOICE_HELP_TEXT, } ), ) self.rules_class = Choice( "Class number", choices=["1", "2"], choices_fn=self.get_class_choices, doc="""\ *(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})* Select which of the classes to keep when filtering. The CellProfiler Analyst classifier user interface lists the names of the classes in left-to-right order. **FilterObjects** uses the first class from CellProfiler Analyst if you choose “1”, etc. Please note the following: - The object is retained if the object falls into the selected class. - You can make multiple class selections. If you do so, the module will retain the object if the object falls into any of the selected classes.""".format( **{"MODE_CLASSIFIERS": MODE_CLASSIFIERS, "MODE_RULES": MODE_RULES} ), ) def get_directory_fn(): """Get the directory for the rules file name""" return self.rules_directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.rules_directory.get_parts_from_path(path) self.rules_directory.join_parts(dir_choice, custom_path) self.rules_file_name = Filename( "Rules or classifier file name", "rules.txt", get_directory_fn=get_directory_fn, set_directory_fn=set_directory_fn, doc="""\ *(Used only when filtering using {MODE_RULES} or {MODE_CLASSIFIERS})* The name of the rules or classifier file. A rules file is a plain text file containing the complete set of rules. Each line of the rules file should be a rule naming a measurement to be made on the object you selected, for instance: IF (Nuclei_AreaShape_Area < 351.3, [0.79, -0.79], [-0.94, 0.94]) The above rule will score +0.79 for the positive category and -0.94 for the negative category for nuclei whose area is less than 351.3 pixels and will score the opposite for nuclei whose area is larger. The filter adds positive and negative and keeps only objects whose positive score is higher than the negative score. A classifier file is a trained classifier exported from CellProfiler Analyst. You will need to ensure that the measurements specified by the file are produced by upstream modules in the pipeline. This setting is not compatible with data processed as 3D. """.format( **{"MODE_CLASSIFIERS": MODE_CLASSIFIERS, "MODE_RULES": MODE_RULES} ), ) self.additional_objects = [] self.additional_object_count = HiddenCount( self.additional_objects, "Additional object count" ) self.spacer_3 = Divider(line=False) self.additional_object_button = DoSomething( "Relabel additional objects to match the filtered object?", "Add an additional object", self.add_additional_object, doc="""\ Click this button to add an object to receive the same post-filtering labels as the filtered object. This is useful in making sure that labeling is maintained between related objects (e.g., primary and secondary objects) after filtering.""", )
def create_settings(self): self.input_image = ImageSubscriber( "Select an input image", "None", doc= """Select the image to be tiled. Additional images within the cycle can be added later by choosing the "*%(T_ACROSS_CYCLES)s*" option below. """ % globals(), ) self.output_image = ImageName( "Name the output image", "TiledImage", doc="""Enter a name for the final tiled image.""", ) self.additional_images = [] self.add_button = DoSomething( "", "Add another image", self.add_image, doc="""Add images from other channels to perform similar tiling""", ) self.tile_method = Choice( "Tile assembly method", T_ALL, doc="""\ This setting controls the method by which the final tiled image is assembled: - *%(T_WITHIN_CYCLES)s:* If you have loaded more than one image for each cycle using modules upstream in the pipeline, the images can be tiled. For example, you may tile three different channels (OrigRed, OrigBlue, and OrigGreen), and a new tiled image will be created for every image cycle. - *%(T_ACROSS_CYCLES)s:* If you want to tile images from multiple cycles together, select this option. For example, you may tile all the images of the same type (e.g., OrigBlue) across all fields of view in your experiment, which will result in one final tiled image when processing is complete. """ % globals(), ) self.rows = Integer( "Final number of rows", 8, doc="""\ Specify the number of rows would you like to have in the tiled image. For example, if you want to show your images in a 96-well format, enter 8. *Special cases:* Let *M* be the total number of slots for images (i.e, number of rows x number of columns) and *N* be the number of actual images. - If *M* > *N*, blanks will be used for the empty slots. - If the *M* < *N*, an error will occur since there are not enough image slots. Check “Automatically calculate number of rows?” to avoid this error. """, ) self.columns = Integer( "Final number of columns", 12, doc="""\ Specify the number of columns you like to have in the tiled image. For example, if you want to show your images in a 96-well format, enter 12. *Special cases:* Let *M* be the total number of slots for images (i.e, number of rows x number of columns) and *N* be the number of actual images. - If *M* > *N*, blanks will be used for the empty slots. - If the *M* < *N*, an error will occur since there are not enough image slots. Check “Automatically calculate number of columns?” to avoid this error. """, ) self.place_first = Choice( "Image corner to begin tiling", P_ALL, doc= """Where do you want the first image to be placed? Begin in the upper left-hand corner for a typical multi-well plate format where the first image is A01. """, ) self.tile_style = Choice( "Direction to begin tiling", S_ALL, doc= """This setting specifies the order that the images are to be arranged. For example, if your images are named A01, A02, etc, enter "*%(S_ROW)s*". """ % globals(), ) self.meander = Binary( "Use meander mode?", False, doc="""\ Select "*Yes*" to tile adjacent images in one direction, then the next row/column is tiled in the opposite direction. Some microscopes capture images in this fashion. The default mode is “comb”, or “typewriter” mode; in this mode, when one row is completely tiled in one direction, the next row starts near where the first row started and tiles again in the same direction. """ % globals(), ) self.wants_automatic_rows = Binary( "Automatically calculate number of rows?", False, doc="""\ **Tile** can automatically calculate the number of rows in the grid based on the number of image cycles that will be processed. Select "*Yes*" to create a grid that has the number of columns that you entered and enough rows to display all of your images. Select "*No*" to specify the number of rows. If you check both automatic rows and automatic columns, **Tile** will create a grid that has roughly the same number of rows and columns. """ % globals(), ) self.wants_automatic_columns = Binary( "Automatically calculate number of columns?", False, doc="""\ **Tile** can automatically calculate the number of columns in the grid from the number of image cycles that will be processed. Select "*Yes*" to create a grid that has the number of rows that you entered and enough columns to display all of your images. Select "*No*" to specify the number of rows. If you check both automatic rows and automatic columns, **Tile** will create a grid that has roughly the same number of rows and columns. """ % globals(), )
def create_settings(self): """Create the settings for the module Create the settings for the module during initialization. """ self.contrast_choice = Choice( "Make each classification decision on how many measurements?", [BY_SINGLE_MEASUREMENT, BY_TWO_MEASUREMENTS], doc="""\ This setting controls how many measurements are used to make a classifications decision for each object: - *%(BY_SINGLE_MEASUREMENT)s:* Classifies each object based on a single measurement. - *%(BY_TWO_MEASUREMENTS)s:* Classifies each object based on a pair of measurements taken together (that is, an object must meet two criteria to belong to a class). """ % globals(), ) ############### Single measurement settings ################## # # A list holding groupings for each of the single measurements # to be done # self.single_measurements = [] # # A count of # of measurements # self.single_measurement_count = HiddenCount(self.single_measurements) # # Add one single measurement to start off # self.add_single_measurement(False) # # A button to press to get another measurement # self.add_measurement_button = DoSomething( "", "Add another classification", self.add_single_measurement) # ############### Two-measurement settings ##################### # # The object for the contrasting method # self.object_name = LabelSubscriber( "Select the object name", "None", doc="""\ Choose the object that you want to measure from the list. This should be an object created by a previous module such as **IdentifyPrimaryObjects**, **IdentifySecondaryObjects**, **IdentifyTertiaryObjects**, or **Watershed** """, ) # # The two measurements for the contrasting method # def object_fn(): return self.object_name.value self.first_measurement = Measurement( "Select the first measurement", object_fn, doc="""\ *(Used only if using a pair of measurements)* Choose a measurement made on the above object. This is the first of two measurements that will be contrasted together. The measurement should be one made on the object in a prior module. """, ) self.first_threshold_method = Choice( "Method to select the cutoff", [TM_MEAN, TM_MEDIAN, TM_CUSTOM], doc="""\ *(Used only if using a pair of measurements)* Objects are classified as being above or below a cutoff value for a measurement. You can set this cutoff threshold in one of three ways: - *%(TM_MEAN)s*: At the mean of the measurement’s value for all objects in the image cycle. - *%(TM_MEDIAN)s*: At the median of the measurement’s value for all objects in the image set. - *%(TM_CUSTOM)s*: You specify a custom threshold value. """ % globals(), ) self.first_threshold = Float( "Enter the cutoff value", 0.5, doc="""\ *(Used only if using a pair of measurements)* This is the cutoff value separating objects in the two classes.""", ) self.second_measurement = Measurement( "Select the second measurement", object_fn, doc="""\ *(Used only if using a pair of measurements)* Select a measurement made on the above object. This is the second of two measurements that will be contrasted together. The measurement should be one made on the object in a prior module.""", ) self.second_threshold_method = Choice( "Method to select the cutoff", [TM_MEAN, TM_MEDIAN, TM_CUSTOM], doc="""\ *(Used only if using a pair of measurements)* Objects are classified as being above or below a cutoff value for a measurement. You can set this cutoff threshold in one of three ways: - *%(TM_MEAN)s:* At the mean of the measurement’s value for all objects in the image cycle. - *%(TM_MEDIAN)s:* At the median of the measurement’s value for all objects in the image set. - *%(TM_CUSTOM)s:* You specify a custom threshold value. """ % globals(), ) self.second_threshold = Float( "Enter the cutoff value", 0.5, doc="""\ *(Used only if using a pair of measurements)* This is the cutoff value separating objects in the two classes.""", ) self.wants_custom_names = Binary( "Use custom names for the bins?", False, doc="""\ *(Used only if using a pair of measurements)* Select "*Yes*" if you want to specify the names of each bin measurement. Select "*No*" to create names based on the measurements. For instance, for “Intensity_MeanIntensity_Green” and “Intensity_TotalIntensity_Blue”, the module generates measurements such as “Classify_Intensity_MeanIntensity_Green_High_Intensity_TotalIntensity_Low”. """ % globals(), ) self.low_low_custom_name = Alphanumeric( "Enter the low-low bin name", "low_low", doc="""\ *(Used only if using a pair of measurements)* Name of the measurement for objects that fall below the threshold for both measurements. """, ) self.low_high_custom_name = Alphanumeric( "Enter the low-high bin name", "low_high", doc="""\ *(Used only if using a pair of measurements)* Name of the measurement for objects whose first measurement is below threshold and whose second measurement is above threshold. """, ) self.high_low_custom_name = Alphanumeric( "Enter the high-low bin name", "high_low", doc="""\ *(Used only if using a pair of measurements)* Name of the measurement for objects whose first measurement is above threshold and whose second measurement is below threshold.""", ) self.high_high_custom_name = Alphanumeric( "Enter the high-high bin name", "high_high", doc="""\ *(Used only if using a pair of measurements)* Name of the measurement for objects that are above the threshold for both measurements.""", ) self.wants_image = Binary( "Retain an image of the classified objects?", False, doc="""\ Select "*Yes*" to retain the image of the objects color-coded according to their classification, for use later in the pipeline (for example, to be saved by a **SaveImages** module). """ % globals(), ) self.image_name = ImageName( "Enter the image name", "None", doc="""\ *(Used only if the classified object image is to be retained for later use in the pipeline)* Enter the name to be given to the classified object image.""", )
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)
def create_settings(self): super(RunStarDist, self).create_settings() self.model = Choice( text="Model", choices=MODEL_OPTIONS, value=GREY_1, doc="""\ StarDist comes with models for detecting nuclei. Alternatively, you can supply a custom-trained model generated outside of CellProfiler within Python. Custom models can be useful if working with unusual cell types. The inbuilt fluorescent and DSB models expect greyscale images. The H&E model expects a color image as input (from brightfield). Custom models will require images of the type they were trained with. It should be noted that the models supplied with StarDist do not support 3D images, but it's possible to train and use your own. """, ) self.tile_image = Binary( text="Tile input image?", value=False, doc="""\ If enabled, the input image will be broken down into overlapping tiles. This can help to conserve memory when working with large images. The image is split into a set number of vertical and horizontal tiles. The total number of tiles will be the result of multiplying the horizontal and vertical tile number.""", ) self.n_tiles_x = Integer(text="Horizontal tiles", value=1, minval=1, doc="""\ Specify the number of tiles to break the image down into along the x-axis (horizontal).""" ) self.n_tiles_y = Integer(text="Vertical tiles", value=1, minval=1, doc="""\ Specify the number of tiles to break the image down into along the y-axis (vertical).""" ) self.save_probabilities = Binary( text="Save probability image?", value=False, doc=""" If enabled, the probability scores from the model will be recorded as a new image. Probability scales from 0-1, with 1 representing absolute certainty of a pixel being in a cell. You may want to use a custom threshold to manually generate objects.""", ) self.probabilities_name = ImageName( "Name the probability image", "Probabilities", doc= "Enter the name you want to call the probability image produced by this module.", ) self.model_directory = Directory("Model folder", doc=f"""\ *(Used only when using a custom pre-trained model)* Select the folder containing your StarDist model. This should have the config, threshold and weights files exported after training.""") self.gpu_test = DoSomething( "", "Test GPU", self.do_check_gpu, doc=f"""\ Press this button to check whether a GPU is correctly configured. If you have a dedicated GPU, a failed test usually means that either your GPU does not support deep learning or the required dependencies are not installed. Make sure you followed the setup instructions here: https://www.tensorflow.org/install/gpu If you don't have a GPU or it's not configured, StarDist will instead run on the CPU. This will be slower but should work on any system. """, )
def create_settings(self): # the list of per image settings (name & scaling factor) self.images = [] # create the first two images (the default number) self.add_image(False) self.add_image(False) # other settings self.operation = Choice( "Operation", [ O_ADD, O_SUBTRACT, O_DIFFERENCE, O_MULTIPLY, O_DIVIDE, O_AVERAGE, O_MINIMUM, O_MAXIMUM, O_INVERT, O_LOG_TRANSFORM, O_LOG_TRANSFORM_LEGACY, O_AND, O_OR, O_NOT, O_EQUALS, O_NONE, ], doc="""\ Select the operation to perform. Note that if more than two images are chosen, then operations will be performed sequentially from first to last, e.g., for “Divide”, (Image1 / Image2) / Image3 - *%(O_ADD)s:* Adds the first image to the second, and so on. - *%(O_SUBTRACT)s:* Subtracts the second image from the first. - *%(O_DIFFERENCE)s:* The absolute value of the difference between the first and second images. - *%(O_MULTIPLY)s:* Multiplies the first image by the second. - *%(O_DIVIDE)s:* Divides the first image by the second. - *%(O_AVERAGE)s:* Calculates the mean intensity of the images loaded in the module. This is equivalent to the Add option divided by the number of images loaded by this module. If you would like to average all of the images in an entire pipeline, i.e., across cycles, you should instead use the **CorrectIlluminationCalculate** module and choose the *All* (vs. *Each*) option. - *%(O_MINIMUM)s:* Returns the element-wise minimum value at each pixel location. - *%(O_MAXIMUM)s:* Returns the element-wise maximum value at each pixel location. - *%(O_INVERT)s:* Subtracts the image intensities from 1. This makes the darkest color the brightest and vice-versa. Note that if a mask has been applied to the image, the mask will also be inverted. - *%(O_LOG_TRANSFORM)s:* Log transforms each pixel’s intensity. The actual function is log\ :sub:`2`\ (image + 1), transforming values from 0 to 1 into values from 0 to 1. - *%(O_LOG_TRANSFORM_LEGACY)s:* Log\ :sub:`2` transform for backwards compatibility. - *%(O_NONE)s:* This option is useful if you simply want to select some of the later options in the module, such as adding, multiplying, or exponentiating your image by a constant. The following are operations that produce binary images. In a binary image, the foreground has a truth value of “true” (ones) and the background has a truth value of “false” (zeros). The operations, *%(O_OR)s, %(O_AND)s and %(O_NOT)s* will convert the input images to binary by changing all zero values to background (false) and all other values to foreground (true). - *%(O_AND)s:* a pixel in the output image is in the foreground only if all corresponding pixels in the input images are also in the foreground. - *%(O_OR)s:* a pixel in the output image is in the foreground if a corresponding pixel in any of the input images is also in the foreground. - *%(O_NOT)s:* the foreground of the input image becomes the background of the output image and vice-versa. - *%(O_EQUALS)s:* a pixel in the output image is in the foreground if the corresponding pixels in the input images have the same value. Note that *%(O_INVERT)s*, *%(O_LOG_TRANSFORM)s*, *%(O_LOG_TRANSFORM_LEGACY)s* and *%(O_NONE)s* operate on only a single image. """ % globals(), ) self.divider_top = Divider(line=False) self.exponent = Float( "Raise the power of the result by", 1, doc="""\ Enter an exponent to raise the result to *after* the chosen operation.""", ) self.after_factor = Float( "Multiply the result by", 1, doc="""\ Enter a factor to multiply the result by *after* the chosen operation.""", ) self.addend = Float( "Add to result", 0, doc="""\ Enter a number to add to the result *after* the chosen operation.""", ) self.truncate_low = Binary( "Set values less than 0 equal to 0?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *Yes* to set negative values to 0. """ % globals(), ) self.truncate_high = Binary( "Set values greater than 1 equal to 1?", True, doc="""\ Values outside the range 0 to 1 might not be handled well by other modules. Select *Yes* to set values greater than 1 to a maximum value of 1. """ % globals(), ) self.replace_nan = Binary( "Replace invalid values with 0?", True, doc="""\ Certain operations are mathematically invalid (divide by zero, raise a negative number to the power of a fraction, etc.). This setting will set pixels with invalid values to zero. Disabling this setting will represent these pixels as "nan" ("Not A Number"). "nan" pixels cannot be displayed properly and may cause errors in other modules. """ % globals(), ) self.ignore_mask = Binary( "Ignore the image masks?", False, doc="""\ Select *Yes* to set equal to zero all previously masked pixels and operate on the masked images as if no mask had been applied. Otherwise, the smallest image mask is applied after image math has been completed. """ % globals(), ) self.output_image_name = ImageName( "Name the output image", "ImageAfterMath", doc="""\ Enter a name for the resulting image.""", ) self.add_button = DoSomething("", "Add another image", self.add_image) self.divider_bottom = Divider(line=False)
def create_settings(self): self.images_list = ImageListSubscriber( "Select images to measure", [], doc= """Select the grayscale images whose intensity you want to measure.""", ) self.objects_list = LabelListSubscriber( "Select objects to measure", [], doc="""\ Select the objects whose texture you want to measure. If you only want to measure the texture for the image overall, you can remove all objects using the “Remove this object” button. Objects specified here will have their texture measured against *all* images specified above, which may lead to image-object combinations that are unnecessary. If you do not want this behavior, use multiple **MeasureTexture** modules to specify the particular image-object measures that you want. """, ) self.gray_levels = Integer( "Enter how many gray levels to measure the texture at", 256, 2, 256, doc="""\ Enter the number of gray levels (ie, total possible values of intensity) you want to measure texture at. Measuring at more levels gives you _potentially_ more detailed information about your image, but at the cost of somewhat decreased processing speed. Before processing, your image will be rescaled from its current pixel values to 0 - [gray levels - 1]. The texture features will then be calculated. In all CellProfiler 2 versions, this value was fixed at 8; in all CellProfiler 3 versions it was fixed at 256. The minimum number of levels is 2, the maximum is 256. """, ) self.scale_groups = [] self.scale_count = HiddenCount(self.scale_groups) self.image_divider = Divider() self.object_divider = Divider() self.add_scale(removable=False) self.add_scales = DoSomething( callback=self.add_scale, label="Add another scale", text="", doc="""\ Add an additional texture scale to measure. Useful when you want to measure texture features of different sizes. """, ) self.images_or_objects = Choice( "Measure whole images or objects?", [IO_IMAGES, IO_OBJECTS, IO_BOTH], value=IO_BOTH, doc="""\ This setting determines whether the module computes image-wide measurements, per-object measurements or both. - *{IO_IMAGES}:* Select if you only want to measure the texture across entire images. - *{IO_OBJECTS}:* Select if you want to measure the texture on a per-object basis only. - *{IO_BOTH}:* Select to make both image and object measurements. """.format( **{ "IO_IMAGES": IO_IMAGES, "IO_OBJECTS": IO_OBJECTS, "IO_BOTH": IO_BOTH }), )
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)
def create_settings(self): self.images_list = ImageListSubscriber( "Select images to measure", [], doc= """Select the grayscale images whose intensity you want to measure.""", ) self.objects_list = LabelListSubscriber( "Select objects to measure", [], doc="""\ Select the objects whose texture you want to measure. If you only want to measure the texture for the image overall, you can remove all objects using the “Remove this object” button. Objects specified here will have their texture measured against *all* images specified above, which may lead to image-object combinations that are unnecessary. If you do not want this behavior, use multiple **MeasureTexture** modules to specify the particular image-object measures that you want. """, ) self.scale_groups = [] self.scale_count = HiddenCount(self.scale_groups) self.image_divider = Divider() self.object_divider = Divider() self.add_scale(removable=False) self.add_scales = DoSomething( callback=self.add_scale, label="Add another scale", text="", doc="""\ Add an additional texture scale to measure. Useful when you want to measure texture features of different sizes. """, ) self.images_or_objects = Choice( "Measure whole images or objects?", [IO_IMAGES, IO_OBJECTS, IO_BOTH], value=IO_BOTH, doc="""\ This setting determines whether the module computes image-wide measurements, per-object measurements or both. - *{IO_IMAGES}:* Select if you only want to measure the texture across entire images. - *{IO_OBJECTS}:* Select if you want to measure the texture on a per-object basis only. - *{IO_BOTH}:* Select to make both image and object measurements. """.format( **{ "IO_IMAGES": IO_IMAGES, "IO_OBJECTS": IO_OBJECTS, "IO_BOTH": IO_BOTH }), )
def create_settings(self): self.image_name = ImageSubscriber( "Select the input image", "None", doc="""Select the multichannel image you want to convert to grayscale.""", ) self.combine_or_split = Choice( "Conversion method", [COMBINE, SPLIT], doc="""\ How do you want to convert the color image? - *%(SPLIT)s:* Splits the channels of a color image (e.g., red, green, blue) into separate grayscale images. - *%(COMBINE)s:* Converts a color image to a grayscale image by combining channels together (e.g., red, green, blue).""" % globals(), ) self.rgb_or_channels = Choice( "Image type", [CH_RGB, CH_HSV, CH_CHANNELS], doc="""\ This setting provides three options to choose from: - *%(CH_RGB)s:* The RGB (red, green, blue) color space is the typical model in which color images are stored. Choosing this option will split the image into red, green, and blue component images. - *%(CH_HSV)s:* The HSV (hue, saturation, value) color space is based on color characteristics such as tint, shade, and tone. Choosing this option will split the image into the hue, saturation, and value component images. - *%(CH_CHANNELS)s:* Many images contain color channels other than RGB or HSV. For instance, GIF and PNG formats can have an alpha channel that encodes transparency. TIF formats can have an arbitrary number of channels which represent pixel measurements made by different detectors, filters or lighting conditions. This setting allows you to handle a more complex model for images that have more than three channels.""" % globals(), ) # The following settings are used for the combine option self.grayscale_name = ImageName( "Name the output image", "OrigGray", doc="""\ *(Used only when combining channels)* Enter a name for the resulting grayscale image.""", ) self.red_contribution = Float( "Relative weight of the red channel", 1, 0, doc="""\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.""", ) self.green_contribution = Float( "Relative weight of the green channel", 1, 0, doc="""\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.""", ) self.blue_contribution = Float( "Relative weight of the blue channel", 1, 0, doc="""\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.""", ) # The following settings are used for the split RGB option self.use_red = Binary( "Convert red to gray?", True, doc="""\ *(Used only when splitting RGB images)* Select *"Yes"* to extract the red channel to grayscale. Otherwise, the red channel will be ignored. """ % globals(), ) self.red_name = ImageName( "Name the output image", "OrigRed", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the red channel.""", ) self.use_green = Binary( "Convert green to gray?", True, doc="""\ *(Used only when splitting RGB images)* Select *"Yes"* to extract the green channel to grayscale. Otherwise, the green channel will be ignored. """ % globals(), ) self.green_name = ImageName( "Name the output image", "OrigGreen", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the green channel.""", ) self.use_blue = Binary( "Convert blue to gray?", True, doc="""\ *(Used only when splitting RGB images)* Select *"Yes"* to extract the blue channel to grayscale. Otherwise, the blue channel will be ignored. """ % globals(), ) self.blue_name = ImageName( "Name the output image", "OrigBlue", doc="""\ *(Used only when splitting RGB images)* Enter a name for the resulting grayscale image coming from the blue channel.""", ) # The following settings are used for the split HSV option self.use_hue = Binary( "Convert hue to gray?", True, doc="""\ *(Used only when splitting HSV images)* Select *"Yes"* to extract the hue to grayscale. Otherwise, the hue will be ignored. """ % globals(), ) self.hue_name = ImageName( "Name the output image", "OrigHue", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the hue.""", ) self.use_saturation = Binary( "Convert saturation to gray?", True, doc="""\ *(Used only when splitting HSV images)* Select *"Yes"* to extract the saturation to grayscale. Otherwise, the saturation will be ignored. """ % globals(), ) self.saturation_name = ImageName( "Name the output image", "OrigSaturation", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the saturation.""", ) self.use_value = Binary( "Convert value to gray?", True, doc="""\ *(Used only when splitting HSV images)* Select *"Yes"* to extract the value to grayscale. Otherwise, the value will be ignored. """ % globals(), ) self.value_name = ImageName( "Name the output image", "OrigValue", doc="""\ *(Used only when splitting HSV images)* Enter a name for the resulting grayscale image coming from the value.""", ) # The alternative model: self.channels = [] self.add_channel(False) self.channel_button = DoSomething("", "Add another channel", self.add_channel) self.channel_count = HiddenCount(self.channels, "Channel count")
def create_settings(self): self.scheme_choice = Choice( "Select a color scheme", [SCHEME_RGB, SCHEME_CMYK, SCHEME_STACK, SCHEME_COMPOSITE], doc="""\ This module can use one of two color schemes to combine images: - *%(SCHEME_RGB)s*: Each input image determines the intensity of one of the color channels: red, green, and blue. - *%(SCHEME_CMYK)s*: Three of the input images are combined to determine the colors (cyan, magenta, and yellow) and a fourth is used only for brightness. The cyan image adds equally to the green and blue intensities. The magenta image adds equally to the red and blue intensities. The yellow image adds equally to the red and green intensities. - *%(SCHEME_STACK)s*: The channels are stacked in the order listed, from top to bottom. An arbitrary number of channels is allowed. For example, you could create a 5-channel image by providing 5 grayscale images. The first grayscale image you provide will fill the first channel, the second grayscale image you provide will fill the second channel, and so on. - *%(SCHEME_COMPOSITE)s*: A color is assigned to each grayscale image. Each grayscale image is converted to color by multiplying the intensity by the color and the resulting color images are added together. An arbitrary number of channels can be composited into a single color image. """ % globals(), ) self.wants_rescale = Binary( "Rescale intensity", True, doc="""\ Choose whether to rescale each channel individually to the range of 0-1. This prevents clipping of channels with intensity above 1 and can help to balance the brightness of the different channels. This option also ensures that channels occupy the full intensity range available, which is useful for displaying images in other software. This rescaling is applied before any multiplication factors set in this module's options. Using a multiplication factor >1 would therefore result in clipping.""" ) # # # # # # # # # # # # # # # # # # RGB settings # # # # # # # # # # # # # # # # # self.red_image_name = ImageSubscriber( "Select the image to be colored red", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in red. """ % globals(), ) self.green_image_name = ImageSubscriber( "Select the image to be colored green", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in green. """ % globals(), ) self.blue_image_name = ImageSubscriber( "Select the image to be colored blue", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Select the input image to be displayed in blue. """ % globals(), ) self.rgb_image_name = ImageName( "Name the output image", "ColorImage", doc="""Enter a name for the resulting image.""", ) self.red_adjustment_factor = Float( "Relative weight for the red image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the red image. If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.green_adjustment_factor = Float( "Relative weight for the green image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the green image. If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.blue_adjustment_factor = Float( "Relative weight for the blue image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_RGB)s" is selected as the color scheme)* Enter the relative weight for the blue image. If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) # # # # # # # # # # # # # # # # CYMK settings # # # # # # # # # # # # # # # self.cyan_image_name = ImageSubscriber( "Select the image to be colored cyan", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in cyan. """ % globals(), ) self.magenta_image_name = ImageSubscriber( "Select the image to be colored magenta", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in magenta. """ % globals(), ) self.yellow_image_name = ImageSubscriber( "Select the image to be colored yellow", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image to be displayed in yellow. """ % globals(), ) self.gray_image_name = ImageSubscriber( "Select the image that determines brightness", can_be_blank=True, blank_text=LEAVE_THIS_BLACK, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Select the input image that will determine each pixel's brightness. """ % globals(), ) self.cyan_adjustment_factor = Float( "Relative weight for the cyan image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the cyan image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.magenta_adjustment_factor = Float( "Relative weight for the magenta image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the magenta image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.yellow_adjustment_factor = Float( "Relative weight for the yellow image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the yellow image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) self.gray_adjustment_factor = Float( "Relative weight for the brightness image", value=1, minval=0, doc="""\ *(Used only if "%(SCHEME_CMYK)s" is selected as the color scheme)* Enter the relative weight for the brightness image. If all relative weights are equal, all colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights. """ % globals(), ) # # # # # # # # # # # # # # # # Stack settings # # # # # # # # # # # # # # # self.stack_channels = [] self.stack_channel_count = HiddenCount(self.stack_channels) self.add_stack_channel_cb(can_remove=False) self.add_stack_channel = DoSomething( "Add another channel", "Add another channel", self.add_stack_channel_cb, doc="""\ Press this button to add another image to the stack. """, )
def create_settings(self): '''Create the settings for the ExportToCellH5 module''' self.directory = Directory("Output file location", doc=""" This setting lets you choose the folder for the output files. %(IO_FOLDER_CHOICE_HELP_TEXT)s """ % globals()) def get_directory_fn(): '''Get the directory for the CellH5 file''' return self.directory.get_absolute_path() def set_directory_fn(path): dir_choice, custom_path = self.directory.get_parts_from_path(path) self.directory.join_parts(dir_choice, custom_path) self.file_name = cps.text.Filename("Output file name", "DefaultOut.ch5", get_directory_fn=get_directory_fn, set_directory_fn=set_directory_fn, metadata=True, browse_msg="Choose CellH5 file", mode=cps.text.Filename.MODE_APPEND, exts=[("CellH5 file (*.cellh5)", "*.ch5"), ("HDF5 file (*.h5)", "*.h5"), ("All files (*.*", "*.*")], doc=""" This setting lets you name your CellH5 file. If you choose an existing file, CellProfiler will add new data to the file or overwrite existing locations. <p>%(IO_WITH_METADATA_HELP_TEXT)s %(USING_METADATA_TAGS_REF)s. For instance, if you have a metadata tag named "Plate", you can create a per-plate folder by selecting one the subfolder options and then specifying the subfolder name as "\g<Plate>". The module will substitute the metadata values for the current image set for any metadata tags in the folder name.%(USING_METADATA_HELP_REF)s.</p> """ % globals()) self.overwrite_ok = cps.Binary( "Overwrite existing data without warning?", False, doc=""" Select <i>"Yes"</i> to automatically overwrite any existing data for a site. Select <i>"No"</i> to be prompted first. If you are running the pipeline on a computing cluster, select <i>"Yes"</i> unless you want execution to stop because you will not be prompted to intervene. Also note that two instances of CellProfiler cannot write to the same file at the same time, so you must ensure that separate names are used on a cluster. """ % globals()) self.repack = cps.Binary("Repack after analysis", True, doc=""" This setting determines whether CellProfiler in multiprocessing mode repacks the data at the end of analysis. If you select <i>"Yes"</i>, CellProfiler will combine all of the satellite files into a single file upon completion. This option requires some extra temporary disk space and takes some time at the end of analysis, but results in a single file which may occupy less disk space. If you select <i>"No"</i>, CellProfiler will create a master file using the name that you give and this file will have links to individual data files that contain the actual data. Using the data generated by this option requires that you keep the master file and the linked files together when copying them to a new folder. """ % globals()) self.plate_metadata = Choice("Plate metadata", [], value="Plate", choices_fn=self.get_metadata_choices, doc=""" This is the metadata tag that identifies the plate name of the images for the current cycle. Choose <i>None</i> if your assay does not have metadata for plate name. If your assay is slide-based, you can use a metadata item that identifies the slide as the choice for this setting and set the well and site metadata items to <i>None</i>.""") self.well_metadata = Choice( "Well metadata", [], value="Well", choices_fn=self.get_metadata_choices, doc="""This is the metadata tag that identifies the well name for the images in the current cycle. Choose <i>None</i> if your assay does not have metadata for the well.""") self.site_metadata = Choice( "Site metadata", [], value="Site", choices_fn=self.get_metadata_choices, doc="""This is the metadata tag that identifies the site name for the images in the current cycle. Choose <i>None</i> if your assay doesn't divide wells up into sites or if this tag is not required for other reasons.""") self.divider = cps.Divider() self.wants_to_choose_measurements = cps.Binary("Choose measurements?", False, doc=""" This setting lets you choose between exporting all measurements or just the ones that you choose. Select <i>"Yes"</i> to pick the measurements to be exported. Select <i>"No"</i> to automatically export all measurements available at this stage of the pipeline. """ % globals()) self.measurements = MeasurementMultiChoice("Measurements to export", doc=""" <i>(Used only if choosing measurements.)</i> <br> This setting lets you choose individual measurements to be exported. Check the measurements you want to export. """) self.objects_to_export = [] self.add_objects_button = DoSomething("Add objects to export", "Add objects", self.add_objects) self.images_to_export = [] self.add_image_button = DoSomething("Add an image to export", "Add image", self.add_image) self.objects_count = cps.HiddenCount(self.objects_to_export) self.images_count = cps.HiddenCount(self.images_to_export)