def create_settings(self): self.site_count = cps.Integer( "Number of image sites per well", 1, minval=1, doc="""\ Enter the number of image sets (fields of view) corresponding to each well.""") self.column_count = cps.Integer( "Number of columns per plate", 12, minval=1, doc="""\ Enter the number of columns per plate.""") self.row_count = cps.Integer( "Number of rows per plate", 8, minval=1, doc="""\ Enter the number of rows per plate.""") self.order = cps.Choice( "Order of image data", [O_ROW, O_COLUMN], doc="""\ This setting specifies how the input data is ordered (assuming that sites within a well are ordered consecutively): - *%(O_ROW)s:* The data appears by row and then by column. That is, all columns for a given row (e.g., A01, A02, A03…) appear consecutively, for each row in consecutive order. - *%(O_COLUMN)s:* The data appears by column and then by row. That is, all rows for a given column (e.g., A01, B01, C01…) appear consecutively, for each column in consecutive order. For instance, the SBS Bioimage example (available `here`_) has files that are named: Channel1-01-A01.tif, Channel1-02-A02.tif, …, Channel1-12-A12.tif, Channel1-13-B01.tif, … You would use “%(O_ROW)s” to label these because the ordering is by row and then by column. .. _here: http://cellprofiler.org/examples.html#SBS_Bioimage_CNT """ % globals())
def create_settings(self): self.object_name = cps.ObjectNameSubscriber( "Input objects", "None", doc = """Enter the name of the objects whose population context is to be measured.""") self.operation = cps.Choice( "Operation", choices= (O_POPULATION_DENSITY, O_DISTANCE_TO_EDGE, O_BOTH), doc = """Select the measurements you wish to perform. The choices are:<br><ul> <li><i>%(O_POPULATION_DENSITY)s</i> - calculate the population density within a radius from each cell.</li> <li><i>%(O_DISTANCE_TO_EDGE)s</i> - calculate the distance of each cell from the edge of a binary mask.</li> <li><i>%(O_BOTH)s</i> - make both measurements"""%globals()) self.radius = cps.Integer( "Search radius", 50, minval=1, doc = """Count all objects within this radius""") self.object_diameter = cps.Integer( "Object diameter", 20, minval=0, doc = """The average diameter of objects in the image. This number is used to adjust the area of the image to account for objects that would otherwise be excluded because they were touching the border.""") self.edge_image = cps.ImageNameSubscriber( "Edge image", doc = """For measuring distance to an edge, this is the reference image. Cell distances will be computed to the nearest foreground / background edge in the reference image.""")
def add_bin_count(self, can_remove=True): '''Add another radial bin count at which to measure''' group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) group.append( "wants_scaled", cps.Binary("Scale the bins?", True, doc=""" <p>Select <i>%(YES)s</i> to divide the object radially into the number of bins that you specify. </p> <p>Select <i>%(NO)s</i> to create the number of bins you specify based on distance. For this option, the user will be asked to specify a maximum distance so that each object will have the same measurements (which might be zero for small objects) and so that the measurements can be taken without knowing the maximum object radius before the run starts.</p>""" % globals())) group.append( "bin_count", cps.Integer("Number of bins", 4, 2, doc=""" Specify the number of bins that you want to use to measure the distribution. Radial distribution is measured with respect to a series of concentric rings starting from the object center (or more generally, between contours at a normalized distance from the object center). This number specifies the number of rings into which the distribution is to be divided. Additional ring counts can be specified by clicking the <i>Add another set of bins</i> button.""")) group.append( "maximum_radius", cps.Integer("Maximum radius", 100, minval=1, doc=""" Specify the maximum radius for the unscaled bins. The unscaled binning method creates the number of bins that you specify and creates equally spaced bin boundaries up to the maximum radius. Parts of the object that are beyond this radius will be counted in an overflow bin. The radius is measured in pixels.""" )) group.can_remove = can_remove if can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove this set of bins", self.bin_counts, group)) self.bin_counts.append(group)
def test_01_02_set_value(self): s = cps.Integer("foo", value=5) for test_case in ("06", "-1"): s.value_text = test_case self.assertEqual(s, int(test_case)) self.assertEqual(s.value_text, test_case) s.test_valid(None)
def create_settings(self): self.input_object_name = cps.ObjectNameSubscriber( "Select objects to measure", cps.NONE, doc= """Select the objects whose radial entropy you want to measure.""") self.input_image_name = cps.ImageNameSubscriber( "Select an image to measure", cps.NONE, doc="""Select the grayscale image you want to measure the entropy of.""") self.bin_number = cps.Integer( "Input number of bins", 6, minval=3, maxval=60, doc= """Number of radial bins to divide your object into. The minimum number of bins allowed is 3, the maximum number is 60.""") self.intensity_measurement = cps.Choice( "Which intensity measurement should be used?", ['Mean', 'Median', 'Integrated'], value='Mean', doc=""" Whether each wedge's mean, median, or integrated intensity should be used to calculate the entropy.""")
def add_channel(self, can_remove=True): """Add another channel to the channels list""" group = cps.SettingsGroup() group.can_remove = can_remove group.append( "channel_choice", cps.Integer( text="Channel number", value=len(self.channels) + 1, minval=1, doc="""\ *(Used only when splitting images)* This setting chooses a channel to be processed. For example, *1* is the first channel in a .TIF or the red channel in a traditional image file. *2* and *3* are the second and third channels of a TIF or the green and blue channels in other formats. *4* is the transparency channel for image formats that support transparency and is channel # 4 for a .TIF file. **ColorToGray** will fail to process an image if you select a channel that is not supported by that image, for example, “5” for a three-channel .PNG file.""", ), ) group.append( "contribution", cps.Float( "Relative weight of the channel", 1, 0, doc="""\ *(Used only when combining channels)* Relative weights: If all relative weights are equal, all three colors contribute equally in the final image. To weight colors relative to each other, increase or decrease the relative weights.""", ), ) group.append( "image_name", cps.ImageNameProvider( "Image name", value="Channel%d" % (len(self.channels) + 1), doc="""\ *(Used only when splitting images)* Select the name of the output grayscale image.""", ), ) if group.can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove this channel", self.channels, group), ) self.channels.append(group)
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 = cps.DoSomething("", "Add another image", self.add_image_cb) self.image_divider = cps.Divider() self.add_object_cb(can_remove=True) self.add_objects = cps.DoSomething("", "Add another object", self.add_object_cb) self.object_divider = cps.Divider() self.add_scale_cb(can_remove=False) self.add_scales = cps.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 = cps.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 = cps.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): """Create the module settings and name the module""" self.wants_default_output_directory = cps.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 = cps.Text( "Output folder path", cpprefs.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 = cps.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 = cps.Binary("Hidden: in batch mode", False) self.distributed_mode = cps.Binary("Hidden: in distributed mode", False) self.default_image_directory = cps.Setting( "Hidden: default input folder at time of save", cpprefs.get_default_image_directory(), ) self.revision = cps.Integer("Hidden: revision number", 0) self.from_old_matlab = cps.Binary("Hidden: from old matlab", False) self.acknowledge_old_matlab = cps.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 = cps.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 add_function(self, can_remove=True): group = MorphSettingsGroup() group.can_remove = can_remove if can_remove: group.append("divider", cps.Divider(line=False)) group.append( "function", cps.Choice( "Select the operation to perform", F_ALL, doc= """Choose one of the operations described in this module's help.""" )) group.append( "repeats_choice", cps.Choice("Number of times to repeat operation", R_ALL, doc="""\ This setting controls the number of times that the same operation is applied successively to the image. - *%(R_ONCE)s:* Perform the operation once on the image. - *%(R_FOREVER)s:* Perform the operation on the image until successive iterations yield the same image. - *%(R_CUSTOM)s:* Perform the operation a custom number of times.""" % globals())) group.append( "custom_repeats", cps.Integer(self.CUSTOM_REPEATS_TEXT, 2, 1, doc=self.CUSTOM_REPEATS_DOC)) group.append( "rescale_values", cps.Binary("Rescale values from 0 to 1?", True, doc="""\ *(Used only for the "%(F_DISTANCE)s" operation).* Select "*%(YES)s*" to rescale the transformed values to lie between 0 and 1. This is the option to use if the distance transformed image is to be used for thresholding by an **Identify** module or the like, which assumes a 0-1 scaling. Select "*%(NO)s*" to leave the values in absolute pixel units. This useful in cases where the actual pixel distances are to be used downstream as input for a measurement module.""" % globals())) if can_remove: group.append( "remove", cps.RemoveSettingButton("", "Remove this operation", self.functions, group)) self.functions.append(group)
def create_settings(self): self.omero_host = cps.Text( "Host address", DEFAULT_OMERO_HOST, doc= """Host address of an omero server. Can be an ip-address or a hostname.""", ) self.omero_port = cps.Integer("Port", DEFAULT_OMERO_PORT, doc="""Port of an omero server.""") self.omero_username = cps.Text( "Username", DEFAULT_OMERO_USERNAME, doc="""Username is required for login into an omero server.""", ) self.omero_password = cps.Text( "Password", DEFAULT_OMERO_PASSWORD, doc="""Password is required for login into an omero server.""", ) self.omero_object = cps.Choice("Object to load", [MS_IMAGE, MS_DATASET, MS_PLATE], DEFAULT_OMERO_OBJECT) self.omero_object_id = cps.Integer( "Object id", DEFAULT_OMERO_OBJECT_ID, doc= """This is a number that omero uses to uniquely identify an object, be it a dataset, plate, or image.""", ) self.load_channels = cps.DoSomething("", "Load channels from OMERO", self.load_channels) # All the omero images that are loaded are assumed to have # as many or more channels than the highest channel number # the user specifies. self.channels = [] self.channel_count = cps.HiddenCount(self.channels, "Channel count") # Add the first channel self.add_channelfn(False) # Button for adding other channels self.add_channel = cps.DoSomething("", "Add another channel", self.add_channelfn)
def add_image_measurement(self, can_remove=True): group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider()) group.append( "image_name", cps.ImageNameSubscriber("Select the image to measure", cps.NONE, doc="""\ Choose an image name from the drop-down menu to calculate intensity for that image. Use the *Add another image* button below to add additional images to be measured. You can add the same image multiple times if you want to measure the intensity within several different objects.""")) group.append( "nchannels", cps.Integer("How many channels does the image have?", 1, doc=""" Indicate how many planes this image have. This is needed as the cellprofiler pipeline needs to be independent of the actuall image data. """)) group.append( "wants_objects", cps.Binary( "Measure the intensity only from areas enclosed by objects?", False, doc="""\ Select *%(YES)s* to measure only those pixels within an object type you choose, identified by a prior module. Note that this module will aggregate intensities across all objects in the image: to measure each object individually, see **MeasureObjectIntensity** instead. """ % globals())) group.append( "object_name", cps.ObjectNameSubscriber("Select the input objects", cps.NONE, doc="""\ *(Used only when measuring intensity from area occupied by objects)* Select the objects that the intensity will be aggregated within. The intensity measurement will be restricted to the pixels within these objects.""")) if can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove this image", self.images, group)) self.images.append(group)
def create_settings(self): '''Create the module settings and name the module''' self.wants_default_output_directory = cps.Binary( "Store batch files in default output folder?", True, doc=""" Select <i>%(YES)s</i> to store batch files in the Default Output folder. <br> Select <i>%(NO)s</i> to enter the path to the folder that will be used to store these files.""" % globals()) self.custom_output_directory = cps.Text( "Output folder path", cpprefs.get_default_output_directory(), doc=""" Enter the path to the 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 = cps.Binary( "Are the cluster computers running Windows?", False, doc=""" Select <i>%(YES)s</i> if the cluster computers are running one of the Microsoft Windows operating systems. In this case, <b>CreateBatchFiles</b> will modify all paths to use the Windows file separator (backslash \). <br> Select <i>%(NO)s</i> for <b>CreateBatchFiles</b> to modify all paths to use the Unix or Macintosh file separator (slash /).""" % globals()) self.batch_mode = cps.Binary("Hidden: in batch mode", False) self.distributed_mode = cps.Binary("Hidden: in distributed mode", False) self.default_image_directory = cps.Setting("Hidden: default input folder at time of save", cpprefs.get_default_image_directory()) self.revision = cps.Integer("Hidden: revision number", 0) self.from_old_matlab = cps.Binary("Hidden: from old matlab", False) self.acknowledge_old_matlab = cps.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 = cps.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.""") self.go_to_website = cps.Binary( "Launch BatchProfiler", True, doc="""Launch BatchProfiler after creating the batch file. This setting will launch a web browser to the BatchProfiler URL to allow you to create batch jobs to run the analysis on a cluster. """) self.check_path_button = cps.DoSomething( "Press this button to check pathnames on the remote server", "Check paths", self.check_paths, doc=""" This button will start a routine that will ask the webserver to check whether the default input and default output folders exist. It will also check whether all remote path mappings exist.""")
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 = cps.DoSomething("", "Add another image", self.add_image_cb) self.image_divider = cps.Divider() self.add_object_cb(can_remove=True) self.add_objects = cps.DoSomething("", "Add another object", self.add_object_cb) self.object_divider = cps.Divider() self.add_scale_cb(can_remove=False) self.add_scales = cps.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, and can take a substantial time to calculate. <p>Select <i>%(YES)s</i> to measure the Gabor features. Select <i>%(NO)s</i> to skip the Gabor feature calculation if it is not informative for your images.</p>""" % globals()) self.gabor_angles = cps.Integer( "Number of angles to compute for Gabor", 4, 2, doc=""" <i>(Used only if Gabor features are measured)</i><br> Enter the number of angles to use for each Gabor texture measurement. The default value is 4 which detects bands in the horizontal, vertical and diagonal orientations.""") self.images_or_objects = cps.Choice( "Measure 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. <ul> <li><i>%(IO_IMAGES)s:</i> Select if you only want to measure the texture of objects.</li> <li><i>%(IO_OBJECTS)s:</i> Select if your pipeline does not contain objects or if you only want to make per-image measurements.</li> <li><i>%(IO_BOTH)s:</i> Select to make both image and object measurements.</li> </ul>""" % globals())
def create_settings(self): self.site_count = cps.Integer("Number of image sites per well", 1, minval=1, doc=""" This setting controls the number of image sets for each well""") self.column_count = cps.Integer("Number of columns per plate", 12, minval=1, doc=""" Enter the number of columns per plate""") self.row_count = cps.Integer("Number of rows per plate", 8, minval=1, doc=""" The number of rows per plate""") self.order = cps.Choice("Order of image data", [O_ROW, O_COLUMN], doc=""" This setting specifies how the input data is ordered (assuming that sites within a well are ordered consecutively): <ul> <li><i>%(O_ROW)s:</i>: The data appears by row and then by column. That is, all columns for a given row (e.g. A01, A02, A03...) appear consecutively, for each row in consecutive order.</li> <li><i>%(O_COLUMN)s:</i> The data appears by column and then by row. That is, all rows for a given column (e.g. A01, B01, C01...) appear consecutively, for each column in consecutive order.</li> </ul> <p>For instance, the SBS Bioimage example (available <a href="http://cellprofiler.org/examples.html#SBS_Bioimage_CNT">here</a>) has files that are named:<br> Channel1-01-A01.tif<br> Channel1-02-A02.tif<br> ...<br> Channel1-12-A12.tif<br> Channel1-13-B01.tif<br> ...<br> You would use "%(O_ROW)s" to label these because the ordering is by row and then by column.</p>""" % globals())
def create_settings(self): self.images = [] self.objects = [] self.bin_counts = [] self.heatmaps = [] self.image_count = cps.HiddenCount(self.images) self.object_count = cps.HiddenCount(self.objects) self.bin_counts_count = cps.HiddenCount(self.bin_counts) self.heatmap_count = cps.HiddenCount(self.heatmaps) self.wants_zernikes = cps.Choice( "Calculate intensity Zernikes?", Z_ALL, doc="""This setting determines whether the intensity Zernike moments are calculated. Choose <i>%(Z_NONE)s</i> to save computation time by not calculating the Zernike moments. Choose <i>%(Z_MAGNITUDES)s</i> to only save the magnitude information and discard information related to the object's angular orientation. Choose <i>%(Z_MAGNITUDES_AND_PHASE)s</i> to save the phase information as well. The last option lets you recover each object's rough appearance from the Zernikes but may not contribute useful information if used to classify phenotypes.""" % globals()) self.zernike_degree = cps.Integer( "Maximum zernike moment", value=9, minval=1, maxval=20, doc="""(<i>Only if "%s" is %s or %s</i>)<br> This is the maximum radial moment that will be calculated. There are increasing numbers of azimuthal moments as you increase the radial moment, so higher values are increasingly expensive to calculate.""" % (self.wants_zernikes.text, Z_MAGNITUDES, Z_MAGNITUDES_AND_PHASE)) self.add_image_button = cps.DoSomething("", "Add another image", self.add_image) self.spacer_1 = cps.Divider() self.add_object_button = cps.DoSomething("", "Add another object", self.add_object) self.spacer_2 = cps.Divider() self.add_bin_count_button = cps.DoSomething("", "Add another set of bins", self.add_bin_count) self.spacer_3 = cps.Divider() self.add_heatmap_button = cps.DoSomething( "", "Add another heatmap display", self.add_heatmap, doc=""" Press this button to add a display of one of the radial distribution measurements. Each radial band of the object is colored using a heatmap according to the measurement value for that band.""") self.add_image(can_remove=False) self.add_object(can_remove=False) self.add_bin_count(can_remove=False)
def create_settings(self): '''Create the module settings and name the module''' self.runname = cps.Text( "Run Name", "Run_name", doc= "Enter a recognizable identifier for the run (spaces will be replaced by undescores)", ) self.n_images_per_measurement = cellprofiler.setting.Integer( "Number of images per measurement", 1, minval=1, doc= "The number of image files in each measurement that must be present for the pipeline to run correctly. This is usually the number of image types in the NamesAndTypes module." ) self.type_first = cellprofiler.setting.Binary( text="Image type first", value=True, doc= "Wether the images are ordered by image type first. If not, ordering by measurement first is assumed." ) self.is_archive = cellprofiler.setting.Binary( text="Is image archive", value=False, doc= "Set to Yes if the the images are included as a single image archive, such as an Ism file." ) self.measurements_in_archive = cellprofiler.setting.Integer( "Number of measurements in the archive", 1, minval=1, doc="The number of measurements in the archive file.") self.max_walltime = cellprofiler.setting.Integer( "Maximum Runtime (hours)", 24, doc= "The maximum time for reserving a node on the cluster. Should be higher than the actual runtime, or the run may not compelte. Runs with lower values will pass the queue more quickly." ) self.account = cps.Text( "Project Code", "", doc= "Enter a project code of an Supercomputing Wales project you wish to run under. This can be left empty if you have only one project.", ) self.cluster_settings_button = cps.DoSomething( "", "Cluster Settings", update_cluster_parameters, doc="Change cluster and edit cluster settings.") self.batch_mode = cps.Binary("Hidden: in batch mode", False) self.revision = cps.Integer("Hidden: revision number", 0)
def add_scale_cb(self, can_remove=True): '''Add a scale to the scale_groups collection can_delete - set this to False to keep from showing the "remove" button for scales that must be present. ''' group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) group.append( 'scale', cps.Integer( "Texture scale to measure", len(self.scale_groups) + 3, doc= """You can specify the scale of texture to be measured, in pixel units; the texture scale is the distance between correlated intensities in the image. A higher number for the scale of texture measures larger patterns of texture whereas smaller numbers measure more localized patterns of texture. It is best to measure texture on a scale smaller than your objects' sizes, so be sure that the value entered for scale of texture is smaller than most of your objects. For very small objects (smaller than the scale of texture you are measuring), the texture cannot be measured and will result in a undefined value in the output file.""" )) group.append( 'angles', cps.MultiChoice( "Angles to measure", H_ALL, H_ALL, doc= """The Haralick texture measurements are based on the correlation between pixels offset by the scale in one of four directions: <p><ul> <li><i>%(H_HORIZONTAL)s</i> - the correlated pixel is "scale" pixels to the right of the pixel of interest.</li> <li><i>%(H_VERTICAL)s</i> - the correlated pixel is "scale" pixels below the pixel of interest.</li> <li><i>%(H_DIAGONAL)s</i> - the correlated pixel is "scale" pixels to the right and "scale" pixels below the pixel of interest.</li> <li><i>%(H_ANTIDIAGONAL)s</i> - the correlated pixel is "scale" pixels to the left and "scale" pixels below the pixel of interest.</li> </ul><p> Choose one or more directions to measure.""" % globals())) if can_remove: group.append( "remover", cps.RemoveSettingButton("", "Remove this scale", self.scale_groups, group)) self.scale_groups.append(group)
def add_bins_cb(self, can_remove = True): '''Add an histogram to the bin_groups collection can_delete - set this to False to keep from showing the "remove" button for histograms that must be present. ''' group = cps.SettingsGroup() if can_remove: group.append("divider", cps.Divider(line=False)) group.append('bins', cps.Integer("Number of bins", len(self.bins_groups)+3, doc="""How much bins do you want in your histogram? You can calculate several histograms with different number of bins using the "Add another histogram" button.""")) if can_remove: group.append("remover", cps.RemoveSettingButton("", "Remove this histogram", self.bins_groups, group)) self.bins_groups.append(group)
def create_settings(self): # # The ImageNameSubscriber "subscribes" to all ImageNameProviders in # prior modules. Modules before yours will put images into CellProfiler. # The ImageSubscriber gives your user a list of these images # which can then be used as inputs in your module. # self.input_image_name = cps.ImageNameSubscriber( # The text to the left of the edit box "Input image name:", # HTML help that gets displayed when the user presses the # help button to the right of the edit box doc="""This is the image that the module operates on. You can choose any image that is made available by a prior module. <br> <b>ImageTemplate</b> will do something to this image. """) # # The ObjectNameSubscriber is similar - it will ask the user # which object to pick from the list of objects provided by # upstream modules. # self.input_object_name = cps.ObjectNameSubscriber( "Input object name", doc="""These are the objects that the module operates on.""") # # The radial degree is the "N" parameter in the Zernike - how many # inflection points there are, radiating out from the center. Higher # N means more features and a more detailed description # # The setting is an integer setting, bounded between 1 and 50. # N = 50 generates 1200 features! # self.radial_degree = cps.Integer( "Radial degree", 10, minval=1, maxval=50, doc="""Calculate all Zernike features up to the given radial degree. The Zernike function is parameterized by a radial and azimuthal degree. The module will calculate all Zernike features for all azimuthal degrees up to and including the radial degree you enter here.""")
def create_settings(self) -> None: self.input_mask_name = cps.ObjectNameSubscriber( text="Select the input mask", value=cps.NONE, doc="") self.padding = cps.Integer(text="Enter padding size (px)", value=20, doc="") self.output_mask_name = cps.ObjectNameProvider( text="Name the output mask", value="PaddedMask", doc="Enter the name of the output mask", ) self.custom = cps.Binary(text="Use custom settings?", value="No", doc="Use custom settings") self.divider = cps.Divider(line=True) self.image_name = cps.ImageNameSubscriber( text="Select image to overlay on", value=cps.LEAVE_BLANK, doc="""\ Choose the image_name upon which a padded mask constructed from the input_mask is laid. """, can_be_blank=True, ) self.input_mask_color = cps.Color( text="Select the input mask color", value="red", doc="Select the input mask color", ) self.output_mask_color = cps.Color( text="Select the output mask color", value="blue", doc="Select the output mask color", )
def create_settings(self): """Create your settings by subclassing this function create_settings is called at the end of initialization. """ self.grid_image = cps.GridNameProvider("Name the grid", doc="""\ This is the name of the grid. You can use this name to retrieve the grid in subsequent modules.""") self.grid_rows = cps.Integer( "Number of rows", 8, 1, doc="""Along the height of the grid, define the number of rows""") self.grid_columns = cps.Integer( "Number of columns", 12, 1, doc="""Along the width of the grid, define the number of columns""" ) self.origin = cps.Choice( "Location of the first spot", [NUM_TOP_LEFT, NUM_BOTTOM_LEFT, NUM_TOP_RIGHT, NUM_BOTTOM_RIGHT], doc="""\ Grid cells are numbered consecutively; this option identifies the origin for the numbering system and the direction for numbering. For instance, if you choose "*%(NUM_TOP_LEFT)s*", the top left cell is cell #1 and cells to the right and bottom are indexed with larger numbers.""" % globals()) self.ordering = cps.Choice("Order of the spots", [NUM_BY_ROWS, NUM_BY_COLUMNS], doc="""\ Grid cells can either be numbered by rows, then columns or by columns, then rows. For instance, you might ask to start numbering a 96-well plate at the top left (by specifying the location of the first spot). - *%(NUM_BY_ROWS)s:* This option will give well A01 the index 1, B01 the index 2, and so on up to H01 which receives the index 8. Well A02 will be assigned the index 9. - *%(NUM_BY_COLUMNS)s:* With this option, the well A02 will be assigned 2, well A12 will be assigned 12 and well B01 will be assigned 13. """ % globals()) self.each_or_once = cps.Choice("Define a grid for which cycle?", [EO_EACH, EO_ONCE], doc="""\ The setting allows you choose when you want to define a new grid: - *%(EO_ONCE)s:* If all of your images are perfectly aligned with each other (due to very consistent image acquisition, consistent grid location within the plate, and/or automatic cropping precisely within each plate), you can define the location of the marker spots once for all of the image cycles. - *%(EO_EACH)s:* If the location of the grid will vary from one image cycle to the next then you should define the location of the marker spots for each cycle independently. """ % globals()) self.auto_or_manual = cps.Choice( "Select the method to define the grid", [AM_AUTOMATIC, AM_MANUAL], doc="""\ Select whether you would like to define the grid automatically (based on objects you have identified in a previous module) or manually. This setting controls how the grid is defined: - *%(AM_MANUAL)s:* In manual mode, you manually indicate known locations of marker spots in the grid and have the rest of the positions calculated from those marks, no matter what the image itself looks like. You can define the grid either by clicking on the image with a mouse or by entering coordinates. - *%(AM_AUTOMATIC)s:* If you would like the grid to be defined automatically, an **IdentifyPrimaryObjects** module must be run prior to this module to identify the objects which will be used to define the grid. The left-most, right-most, top-most, and bottom-most object will be used to define the edges of the grid, and the rows and columns will be evenly spaced between these edges. Note that Automatic mode requires that the incoming objects are nicely defined: for example, if there is an object at the edge of the images that is not really an object that ought to be in the grid, a skewed grid will result. You might wish to use a **FilterObjects** module to clean up badly identified objects prior to defining the grid. If the spots are slightly out of alignment with each other from one image cycle to the next, this allows the identification to be a bit flexible and adapt to the real location of the spots. """ % globals()) self.object_name = cps.ObjectNameSubscriber( "Select the previously identified objects", cps.NONE, doc="""\ *(Used only if you selected "%(AM_AUTOMATIC)s" to define the grid)* Select the previously identified objects you want to use to define the grid. Use this setting to specify the name of the objects that will be used to define the grid. """ % globals()) self.manual_choice = cps.Choice( "Select the method to define the grid manually", [MAN_MOUSE, MAN_COORDINATES], doc="""\ *(Used only if you selected "%(AM_MANUAL)s" to define the grid)* Specify whether you want to define the grid using the mouse or by entering the coordinates of the cells. - *%(MAN_MOUSE)s:* The user interface displays the image you specify. You will be asked to click in the center of two of the grid cells and specify the row and column for each. The grid coordinates will be computed from this information. - *%(MAN_COORDINATES)s:* Enter the X and Y coordinates of the grid cells directly. You can display an image of your grid to find the locations of the centers of the cells, then enter the X and Y position and cell coordinates for each of two cells. """ % globals()) self.manual_image = cps.ImageNameSubscriber( "Select the image to display", cps.NONE, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_MOUSE)s" to define the grid)* Specify the image you want to display when defining the grid. This setting lets you choose the image to display in the grid definition user interface. """ % globals()) self.first_spot_coordinates = cps.Coordinates( "Coordinates of the first cell", (0, 0), doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the coordinates of the first cell on your grid. This setting defines the location of the first of two cells in your grid. You should enter the coordinates of the center of the cell. You can display an image of your grid and use the pixel coordinate display to determine the coordinates of the center of your cell. """ % globals()) self.first_spot_row = cps.Integer("Row number of the first cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the row index for the first cell here. Rows are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be row number 1 and H01 will be row number 8. If you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will be row number 12. """ % globals()) self.first_spot_col = cps.Integer("Column number of the first cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the column index for the first cell here. Columns are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be column number *1* and A12 will be column number *12*. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will be *12* and *1*, respectively. """ % globals()) self.second_spot_coordinates = cps.Coordinates( "Coordinates of the second cell", (0, 0), doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* This setting defines the location of the second of two cells in your grid. You should enter the coordinates of the center of the cell. You can display an image of your grid and use use the pixel coordinate display to determine the coordinates of the center of your cell. """ % globals()) self.second_spot_row = cps.Integer("Row number of the second cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the row index for the second cell here. Rows are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be row number 1 and H01 will be row number 8. If you chose "*%(NUM_BOTTOM_LEFT)s*", A01 will be row number 8 and H01 will be row number 12. """ % globals()) self.second_spot_col = cps.Integer("Column number of the second cell", 1, minval=1, doc="""\ *(Used only if you selected "%(AM_MANUAL)s" and "%(MAN_COORDINATES)s" to define the grid)* Enter the column index for the second cell here. Columns are numbered starting at the origin. For instance, if you chose "*%(NUM_TOP_LEFT)s*" as your origin, well A01 will be column number 1 and A12 will be column number 12. If you chose "*%(NUM_TOP_RIGHT)s*", A01 and A12 will be 12 and 1, respectively. """ % globals()) self.wants_image = cps.Binary("Retain an image of the grid?", False, doc="""\ Select "*%(YES)s*" to retain an image of the grid for use later in the pipeline. This module can create an annotated image of the grid that can be saved using the **SaveImages** module. """ % globals()) self.display_image_name = cps.ImageNameSubscriber( "Select the image on which to display the grid", cps.LEAVE_BLANK, can_be_blank=True, doc="""\ *(Used only if saving an image of the grid)* Enter the name of the image that should be used as the background for annotations (grid lines and grid indexes). This image will be used for the figure and for the saved image. """) self.save_image_name = cps.ImageNameProvider("Name the output image", "Grid", doc="""\ *(Used only if retaining an image of the grid for use later in the pipeline)* Enter the name you want to use for the output image. You can save this image using the **SaveImages** module. """) self.failed_grid_choice = cps.Choice( "Use a previous grid if gridding fails?", [FAIL_NO, FAIL_ANY_PREVIOUS, FAIL_FIRST], doc="""\ If the gridding fails, this setting allows you to control how the module responds to the error: - *%(FAIL_NO)s:* The module will stop the pipeline if gridding fails. - *%(FAIL_ANY_PREVIOUS)s:*: The module will use the the most recent successful gridding. - *%(FAIL_FIRST)s:* The module will use the first gridding. Note that the pipeline will stop in all cases if gridding fails on the first image. """ % globals())
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=""" Choose the image to be cropped.""") self.cropped_image_name = cps.CroppingNameProvider( "Name the output image", "CropBlue", doc=""" Enter the name to be given to cropped image.""") self.shape = cps.Choice( "Select the cropping shape", [SH_RECTANGLE, SH_ELLIPSE, SH_IMAGE, SH_OBJECTS, SH_CROPPING], SH_RECTANGLE, doc=""" Select the shape into which you would like to crop: <ul> <li><i>%(SH_RECTANGLE)s:</i> Self-explanatory.</li> <li><i>%(SH_ELLIPSE)s:</i> Self-explanatory.</li> <li><i>%(SH_IMAGE)s:</i> Cropping will occur based on a binary image you specify. A choice box with available images will appear from which you can select an image. To crop into an arbitrary shape that you define, choose <i>%(SH_IMAGE)s</i> and use the <b>LoadSingleImage</b> module to load a black and white image that you have already prepared from a file. If you have created this image in a program such as Photoshop, this binary image should contain only the values 0 and 255, with zeros (black) for the parts you want to remove and 255 (white) for the parts you want to retain. Alternately, you may have previously generated a binary image using this module (e.g., using the <i>%(SH_ELLIPSE)s</i> option) and saved it using the <b>SaveImages</b> module.<br> In any case, the image must be exactly the same starting size as your image and should contain a contiguous block of white pixels, because the cropping module may remove rows and columns that are completely blank.</li> <li><i>%(SH_OBJECTS)s:</i> Crop based on labeled objects identified by a previous <b>Identify</b> module.</li> <li><i>%(SH_CROPPING)s:</i> The cropping generated by a previous cropping module. You will be able to select images that were generated by previous <b>Crop</b> modules. This <b>Crop</b> module will use the same cropping that was used to generate whichever image you choose.</li> </ul>""" % globals()) self.crop_method = cps.Choice("Select the cropping method", [CM_COORDINATES, CM_MOUSE], CM_COORDINATES, doc=""" Choose whether you would like to crop by typing in pixel coordinates or clicking with the mouse. <ul> <li><i>%(CM_COORDINATES)s:</i> For <i>%(SH_ELLIPSE)s</i>, you will be asked to enter the geometric parameters of the ellipse. For <i>%(SH_RECTANGLE)s</i>, you will be asked to specify the coordinates of the corners.</li> <li><i>%(CM_MOUSE)s:</i> For <i>%(SH_ELLIPSE)s</i>, you will be asked to click five or more points to define an ellipse around the part of the image you want to analyze. Keep in mind that the more points you click, the longer it will take to calculate the ellipse shape. For <i>%(SH_RECTANGLE)s</i>, you can click as many points as you like that are in the interior of the region you wish to retain.</li> </ul>""" % globals()) self.individual_or_once = cps.Choice( "Apply which cycle's cropping pattern?", [IO_INDIVIDUALLY, IO_FIRST], IO_INDIVIDUALLY, doc=""" Specify how a given cropping pattern should be applied to other image cycles: <ul> <li><i>%(IO_FIRST)s:</i> The cropping pattern from the first image cycle is applied to all subsequent cyles. This is useful if the first image is intended to function as a template in some fashion.</li> <li><i>%(IO_INDIVIDUALLY)s:</i> Every image cycle is cropped individually.</li> </ul>""" % globals()) self.horizontal_limits = cps.IntegerOrUnboundedRange( "Left and right rectangle positions", minval=0, doc=""" <i>(Used only if %(SH_RECTANGLE)s selected as cropping shape, or if using Plate Fix)</i><br> Specify the left and right positions for the bounding rectangle by selecting one of the following:<br> <ul> <li><i>%(ABSOLUTE)s:</i> Specify these values as absolute pixel coordinates in the original image. For instance, you might enter "25", "225", and "Absolute" to create a 200×200 pixel image that is 25 pixels from the top-left corner.</li> <li><i>%(FROM_EDGE)s:</i> Specify the position relative to the image edge. For instance, you might enter "25", "25", and "Edge" to crop 25 pixels from both the left and right edges of the image, irrespective of the image's original size.</li> </ul>""" % globals()) self.vertical_limits = cps.IntegerOrUnboundedRange( "Top and bottom rectangle positions", minval=0, doc=""" <i>(Used only if %(SH_RECTANGLE)s selected as cropping shape, or if using Plate Fix)</i><br> Specify the top and bottom positions for the bounding rectangle by selecting one of the following:<br> <ul> <li><i>%(ABSOLUTE)s:</i> Specify these values as absolute pixel coordinates. For instance, you might enter "25", "225", and "Absolute" to create a 200×200 pixel image that's 25 pixels from the top-left corner.</li> <li><i>%(FROM_EDGE)s:</i> Specify position relative to the image edge. For instance, you might enter "25", "25", and "Edge" to crop 25 pixels from the edges of your images irrespective of their size.</li> </ul>""" % globals()) self.ellipse_center = cps.Coordinates("Coordinates of ellipse center", (500, 500), doc=""" <i>(Used only if %(SH_ELLIPSE)s selected as cropping shape)</i><br> Specify the center pixel position of the ellipse.""" % globals()) self.ellipse_x_radius = cps.Integer("Ellipse radius, X direction", 400, doc=""" <i>(Used only if %(SH_ELLIPSE)s selected as cropping shape)</i><br> Specify the radius of the ellipse in the X direction.""" % globals()) self.ellipse_y_radius = cps.Integer("Ellipse radius, Y direction", 200, doc=""" <i>(Used only if %(SH_ELLIPSE)s selected as cropping shape)</i><br> Specify the radius of the ellipse in the Y direction.""" % globals()) self.image_mask_source = cps.ImageNameSubscriber( "Select the masking image", cps.NONE, doc=""" <i>(Used only if %(SH_IMAGE)s selected as cropping shape)</i><br> Select the image to be use as a cropping mask.""" % globals()) self.cropping_mask_source = cps.CroppingNameSubscriber( "Select the image with a cropping mask", cps.NONE, doc=""" <i>(Used only if %(SH_CROPPING)s selected as cropping shape)</i><br> Select the image associated with the cropping mask that you want to use.""" % globals()) self.objects_source = cps.ObjectNameSubscriber("Select the objects", cps.NONE, doc=""" <i>(Used only if %(SH_OBJECTS)s selected as cropping shape)</i><br> Select the objects that are to be used as a cropping mask.""" % globals()) self.use_plate_fix = cps.Binary("Use Plate Fix?", False, doc=""" <i>(Used only if %(SH_IMAGE)s selected as cropping shape)</i><br> Select <i>%(YES)s</i> to attempt to regularize the edges around a previously-identified plate object. <p>When attempting to crop based on a previously identified object such as a rectangular plate, the plate may not have precisely straight edges: there might be a tiny, almost unnoticeable "appendage" sticking out. Without Plate Fix, the <b>Crop</b> module would not crop the image tightly enough: it would retain the tiny appendage, leaving a lot of blank space around the plate and potentially causing problems with later modules (especially ones involving illumination correction). </p> <p>Plate Fix takes the identified object and crops to exclude any minor appendages (technically, any horizontal or vertical line where the object covers less than 50%% of the image). It also sets pixels around the edge of the object (for regions greater than 50%% but less than 100%%) that otherwise would be 0 to the background pixel value of your image, thus avoiding problems with other modules. </p> <p><i>Important note:</i> Plate Fix uses the coordinates entered in the boxes normally used for rectangle cropping (Top, Left and Bottom, Right) to tighten the edges around your identified plate. This is done because in the majority of plate identifications you do not want to include the sides of the plate. If you would like the entire plate to be shown, you should enter "1:end" for both coordinates. If, for example, you would like to crop 80 pixels from each edge of the plate, you could enter Top, Left and Bottom, Right values of 80 and select <i>%(FROM_EDGE)s</i>.</p>""" % globals()) self.remove_rows_and_columns = cps.Choice( "Remove empty rows and columns?", [RM_NO, RM_EDGES, RM_ALL], RM_ALL, doc=""" Use this option to choose whether to remove rows and columns that lack objects: <ul> <li><i>%(RM_NO)s:</i> Leave the image the same size. The cropped areas will be set to zeroes, and will appear as black.</li> <li><i>%(RM_EDGES)s:</i> Crop the image so that its top, bottom, left and right are at the first non-blank pixel for that edge.</li> <li><i>%(RM_ALL)s:</i> Remove any row or column of all-blank pixels, even from the internal portion of the image.</li> </ul>""" % globals())
def create_settings(self): '''Create the UI settings for the module''' self.seed_objects_name = cps.ObjectNameSubscriber( "Select the seed objects", cps.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 = cps.ImageNameSubscriber( "Select the skeletonized image", cps.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 = cps.Binary( "Retain the branchpoint image?", False, doc="""\ Select "*%(YES)s*" 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 = cps.ImageNameProvider( "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 = cps.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)s*" to fill in these small holes prior to skeletonizing.""" % globals()) self.maximum_hole_size = cps.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 = cps.Binary( "Export the skeleton graph relationships?", False, doc="""\ Select "*%(YES)s*" to produce an edge file and a vertex file that gives the relationships between vertices (trunks, branchpoints and endpoints).""" % globals()) self.intensity_image_name = cps.ImageNameSubscriber("Intensity image", cps.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 = cps.DirectoryPath( "File output directory", doc= 'Select the directory you want to save the graph relationships to.', dir_choices=[ cps.DEFAULT_OUTPUT_FOLDER_NAME, cps.DEFAULT_INPUT_FOLDER_NAME, cps.ABSOLUTE_FOLDER_NAME, cps.DEFAULT_OUTPUT_SUBFOLDER_NAME, cps.DEFAULT_INPUT_SUBFOLDER_NAME ]) self.directory.dir_choice = cps.DEFAULT_OUTPUT_FOLDER_NAME self.vertex_file_name = cps.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 = cps.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. """)
def create_settings(self): self.image_name = cps.ImageNameSubscriber("Select the input image", cps.NONE, doc=''' Select the image to be resized.''') self.resized_image_name = cps.ImageNameProvider( "Name the output image", "ResizedBlue", doc=''' Enter the name of the resized image.''') self.size_method = cps.Choice("Resizing method", R_ALL, doc=""" The following options are available: <ul> <li><i>Resize by a fraction or multiple of the original size:</i> Enter a single value which specifies the scaling. </li> <li><i>Resize by specifying desired final dimensions:</i></li> Enter the new height and width of the resized image.</ul>""") self.resizing_factor = cps.Float("Resizing factor", 0.25, minval=0, doc=''' <i>(Used only if resizing by a fraction or multiple of the original size)</i><br> 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 = cps.Choice( "Method to specify the dimensions", C_ALL, doc=""" <i>(Used only if resizing by specifying the dimensions)</i><br> You have two options on how to resize your image: <ul> <li><i>%(C_MANUAL)s:</i> Specify the height and width of the output image.</li> <li><i>>%(C_IMAGE)s::</i> Specify an image and the input image will be resized to the same dimensions.</li> </ul>""" % globals()) self.specific_width = cps.Integer("Width of the final image", 100, minval=1, doc=''' <i>(Used only if resizing by specifying desired final dimensions)</i><br> Enter the desired width of the final image, in pixels.''') self.specific_height = cps.Integer("Height of the final image", 100, minval=1, doc=''' <i>(Used only if resizing by specifying desired final dimensions)</i><br> Enter the desired height of the final image, in pixels.''') self.specific_image = cps.ImageNameSubscriber( "Select the image with the desired dimensions", cps.NONE, doc="""" <i>(Used only if resizing by specifying desired final dimensions using an image)</i><br> The input image will be resized to the dimensions of the specified image.""" ) self.interpolation = cps.Choice("Interpolation method", I_ALL, doc=''' <ul><li><i>Nearest Neighbor:</i> Each output pixel is given the intensity of the nearest corresponding pixel in the input image.</li> <li><i>Bilinear:</i> Each output pixel is given the intensity of the weighted average of the 2x2 neighborhood at the corresponding position in the input image.</li> <li><i>Bicubic:</i> Each output pixel is given the intensity of the weighted average of the 4x4 neighborhood at the corresponding position in the input image.</li> </ul>''') self.separator = cps.Divider(line=False) self.additional_images = [] self.additional_image_count = cps.HiddenCount( self.additional_images, "Additional image count") self.add_button = cps.DoSomething("", "Add another image", self.add_image)
def create_settings(self): self.object_name = cps.ObjectNameSubscriber( 'Select objects to measure', cps.NONE, doc=""" Select the objects whose neighbors you want to measure.""") self.neighbors_name = cps.ObjectNameSubscriber( 'Select neighboring objects to measure', cps.NONE, doc=""" This is the name of the objects that are potential neighbors of the above objects. You can find the neighbors within the same set of objects by selecting the same objects as above.""") self.distance_method = cps.Choice('Method to determine neighbors', D_ALL, D_EXPAND, doc=""" There are several methods by which to determine whether objects are neighbors: <ul> <li><i>%(D_ADJACENT)s:</i> In this mode, two objects must have adjacent boundary pixels to be neighbors. </li> <li><i>%(D_EXPAND)s:</i> The objects are expanded until all pixels on the object boundaries are touching another. Two objects are neighbors if any of their boundary pixels are adjacent after expansion.</li> <li><i>%(D_WITHIN)s:</i> Each object is expanded by the number of pixels you specify. Two objects are neighbors if they have adjacent pixels after expansion. </li> </ul> <p>For <i>%(D_ADJACENT)s</i> and <i>%(D_EXPAND)s</i>, the <i>%(M_PERCENT_TOUCHING)s</i> measurement is the percentage of pixels on the boundary of an object that touch adjacent objects. For <i>%(D_WITHIN)s</i>, two objects are touching if any of their boundary pixels are adjacent after expansion and <i>%(M_PERCENT_TOUCHING)s</i> measures the percentage of boundary pixels of an <i>expanded</i> object that touch adjacent objects.</p>""" % globals()) self.distance = cps.Integer('Neighbor distance', 5, 1, doc=""" <i>(Used only when "%(D_WITHIN)s" is selected)</i> <br> The Neighbor distance is the number of pixels that each object is expanded for the neighbor calculation. Expanded objects that touch are considered neighbors.""" % globals()) self.wants_count_image = cps.Binary( 'Retain the image of objects colored by numbers of neighbors?', False, doc=""" An output image showing the input objects colored by numbers of neighbors may be retained. A colormap of your choice shows how many neighbors each object has. The background is set to -1. Objects are colored with an increasing color value corresponding to the number of neighbors, such that objects with no neighbors are given a color corresponding to 0. Use the <b>SaveImages</b> module to save this image to a file.""") self.count_image_name = cps.ImageNameProvider('Name the output image', 'ObjectNeighborCount', doc=""" <i>(Used only if the image of objects colored by numbers of neighbors is to be retained for later use in the pipeline)</i> <br> Specify a name that will allow the image of objects colored by numbers of neighbors to be selected later in the pipeline.""") self.count_colormap = cps.Colormap('Select colormap', doc=""" <i>(Used only if the image of objects colored by numbers of neighbors is to be retained for later use in the pipeline)</i> <br> Select the colormap to use to color the neighbor number image. All available colormaps can be seen <a href="http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps">here</a>.""" ) self.wants_percent_touching_image = cps.Binary( 'Retain the image of objects colored by percent of touching pixels?', False, doc=""" Select <i>%(YES)s</i> to keep an image of the input objects colored by the percentage of the boundary touching their neighbors. A colormap of your choice is used to show the touching percentage of each object. Use the <b>SaveImages</b> module to save this image to a file.""" % globals()) self.touching_image_name = cps.ImageNameProvider( 'Name the output image', 'PercentTouching', doc=""" <i>(Used only if the image of objects colored by percent touching is to be retained for later use in the pipeline)</i> <br> Specify a name that will allow the image of objects colored by percent of touching pixels to be selected later in the pipeline.""") self.touching_colormap = cps.Colormap('Select a colormap', doc=""" <i>(Used only if the image of objects colored by percent touching is to be retained for later use in the pipeline)</i> <br> Select the colormap to use to color the percent touching image. All available colormaps can be seen <a href="http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps">here</a>.""" )
def test_02_01_neg_assign_number(self): x = cps.Integer("text", 5) x.set_value("foo") self.assertRaises(ValueError, x.test_valid, None)
def create_settings(self): self.x_object = cps.ObjectNameSubscriber( 'Select the object to display on the X-axis', cps.NONE, doc='''\ Choose the name of objects identified by some previous module (such as **IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose measurements are to be displayed on the X-axis. ''') self.x_axis = cps.Measurement( 'Select the object measurement to plot on the X-axis', self.get_x_object, cps.NONE, doc= '''Choose the object measurement made by a previous module to display on the X-axis.''' ) self.y_object = cps.ObjectNameSubscriber( 'Select the object to display on the Y-axis', cps.NONE, doc='''\ Choose the name of objects identified by some previous module (such as **IdentifyPrimaryObjects** or **IdentifySecondaryObjects**) whose measurements are to be displayed on the Y-axis. ''') self.y_axis = cps.Measurement( 'Select the object measurement to plot on the Y-axis', self.get_y_object, cps.NONE, doc= '''Choose the object measurement made by a previous module to display on the Y-axis.''' ) self.gridsize = cps.Integer('Select the grid size', 100, 1, 1000, doc='''\ Enter the number of grid regions you want used on each axis. Increasing the number of grid regions increases the resolution of the plot.''') self.xscale = cps.Choice('How should the X-axis be scaled?', ['linear', 'log'], None, doc='''\ The X-axis can be scaled either with a *linear* scale or with a *log* (base 10) scaling. Using a log scaling is useful when one of the measurements being plotted covers a large range of values; a log scale can bring out features in the measurements that would not easily be seen if the measurement is plotted linearly. ''') self.yscale = cps.Choice('How should the Y-axis be scaled?', ['linear', 'log'], None, doc='''\ The Y-axis can be scaled either with a *linear* scale or with a *log* (base 10) scaling. Using a log scaling is useful when one of the measurements being plotted covers a large range of values; a log scale can bring out features in the measurements that would not easily be seen if the measurement is plotted linearly. ''') self.bins = cps.Choice('How should the colorbar be scaled?', ['linear', 'log'], None, doc='''\ The colorbar can be scaled either with a *linear* scale or with a *log* (base 10) scaling. Using a log scaling is useful when one of the measurements being plotted covers a large range of values; a log scale can bring out features in the measurements that would not easily be seen if the measurement is plotted linearly. ''') maps = [m for m in matplotlib.cm.datad.keys() if not m.endswith('_r')] maps.sort() self.colormap = cps.Choice('Select the color map', maps, 'jet', doc='''\ Select the color map for the density plot. See `this page`_ for pictures of the available colormaps. .. _this page: http://matplotlib.org/users/colormaps.html ''') self.title = cps.Text('Enter a title for the plot, if desired', '', doc='''\ Enter a title for the plot. If you leave this blank, the title will default to *(cycle N)* where *N* is the current image cycle being executed. ''')
def test_01_02_equality(self): x = cps.Integer("text", 5) self.assertTrue(x == 5) self.assertTrue(x.value == 5) self.assertFalse(x == 6) self.assertTrue(x != 6)
def create_settings(self): self.objects_name = cps.ObjectNameSubscriber( "Select the input objects", cps.NONE, doc="""\ Select the objects you would like to split or merge (that is, whose object numbers you want to reassign). You can use any objects that were created in previous modules, such as **IdentifyPrimaryObjects** or **IdentifySecondaryObjects**.""") self.output_objects_name = cps.ObjectNameProvider( "Name the new objects", "RelabeledNuclei", doc="""\ Enter a name for the objects that have been split or merged (that is, whose numbers have been reassigned). You can use this name in subsequent modules that take objects as inputs.""") self.relabel_option = cps.Choice("Operation", [OPTION_MERGE, OPTION_SPLIT], doc="""\ You can choose one of the following options: - *%(OPTION_MERGE)s:* Assign adjacent or nearby objects the same label based on certain criteria. It can be useful, for example, to merge together touching objects that were incorrectly split into two pieces by an **Identify** module. - *%(OPTION_SPLIT)s:* Assign a unique number to separate objects that currently share the same label. This can occur if you applied certain operations in the **Morph** module to objects.""" % globals()) self.merge_option = cps.Choice("Merging method", [UNIFY_DISTANCE, UNIFY_PARENT], doc="""\ *(Used only with the "%(OPTION_MERGE)s" option)* You can merge objects in one of two ways: - *%(UNIFY_DISTANCE)s:* All objects within a certain pixel radius from each other will be merged. - *%(UNIFY_PARENT)s:* All objects which share the same parent relationship to another object will be merged. This is not to be confused with using the **RelateObjects** module, in which the related objects remain as individual objects. See **RelateObjects** for more details.""" % globals()) self.merging_method = cps.Choice("Output object type", [UM_DISCONNECTED, UM_CONVEX_HULL], doc="""\ *(Used only with the "%(UNIFY_PARENT)s" merging method)* **SplitOrMergeObjects** can either merge the child objects and keep them disconnected or it can find the smallest convex polygon (the convex hull) that encloses all of a parent’s child objects. The convex hull will be truncated to include only those pixels in the parent - in that case it may not truly be convex. Choose *%(UM_DISCONNECTED)s* to leave the children as disconnected pieces. Choose *%(UM_CONVEX_HULL)s* to create an output object that is the convex hull around them all.""" % globals()) self.parent_object = cps.Choice("Select the parent object", [cps.NONE], choices_fn=self.get_parent_choices, doc="""\ Select the parent object that will be used to merge the child objects. Please note the following: - You must have established a parent-child relationship between the objects using a prior **RelateObjects** module. - Primary objects and their associated secondary objects are already in a one-to-one parent-child relationship, so it makes no sense to merge them here.""") self.distance_threshold = cps.Integer( "Maximum distance within which to merge objects", 0, minval=0, doc="""\ *(Used only with the "%(OPTION_MERGE)s" option and the "%(UNIFY_DISTANCE)s" method)* Objects that are less than or equal to the distance you enter here, in pixels, will be merged. If you choose zero (the default), only objects that are touching will be merged. Note that *%(OPTION_MERGE)s* will not actually connect or bridge the two objects by adding any new pixels; it simply assigns the same object number to the portions of the object. The new, merged object may therefore consist of two or more unconnected components. If you want to add pixels around objects, see **ExpandOrShrink** or **Morph**.""" % globals()) self.wants_image = cps.Binary("Merge using a grayscale image?", False, doc="""\ *(Used only with the "%(OPTION_MERGE)s" option)* Select *%(YES)s* to use the objects’ intensity features to determine whether two objects should be merged. If you choose to use a grayscale image, *%(OPTION_MERGE)s* will merge two objects only if they are within the distance you have specified *and* certain criteria about the objects within the grayscale image are met.""" % globals()) self.image_name = cps.ImageNameSubscriber( "Select the grayscale image to guide merging", cps.NONE, doc="""\ *(Used only if a grayscale image is to be used as a guide for merging)* Select the name of an image loaded or created by a previous module.""") self.minimum_intensity_fraction = cps.Float( "Minimum intensity fraction", .9, minval=0, maxval=1, doc="""\ *(Used only if a grayscale image is to be used as a guide for merging)* Select the minimum acceptable intensity fraction. This will be used as described for the method you choose in the next setting.""") self.where_algorithm = cps.Choice("Method to find object intensity", [CA_CLOSEST_POINT, CA_CENTROIDS], doc="""\ *(Used only if a grayscale image is to be used as a guide for merging)* You can use one of two methods to determine whether two objects should merged, assuming they meet the distance criteria (as specified above): - *%(CA_CENTROIDS)s:* When the module considers merging two objects, this method identifies the centroid of each object, records the intensity value of the dimmer of the two centroids, multiplies this value by the *minimum intensity fraction* to generate a threshold, and draws a line between the centroids. The method will merge the two objects only if the intensity of every point along the line is above the threshold. For instance, if the intensity of one centroid is 0.75 and the other is 0.50 and the *minimum intensity fraction* has been chosen to be 0.9, all points along the line would need to have an intensity of min(0.75, 0.50) \* 0.9 = 0.50 \* 0.9 = 0.45. This method works well for round cells whose maximum intensity is in the center of the cell: a single cell that was incorrectly segmented into two objects will typically not have a dim line between the centroids of the two halves and will be correctly merged. - *%(CA_CLOSEST_POINT)s:* This method is useful for unifying irregularly shaped cells that are connected. It starts by assigning background pixels in the vicinity of the objects to the nearest object. Objects are then merged if each object has background pixels that are: - Within a distance threshold from each object; - Above the minimum intensity fraction of the nearest object pixel; - Adjacent to background pixels assigned to a neighboring object. An example of a feature that satisfies the above constraints is a line of pixels that connects two neighboring objects and is roughly the same intensity as the boundary pixels of both (such as an axon connecting two neurons' soma).""" % globals())
def test_01_03_assign_str(self): x = cps.Integer("text", 5) x.value = 6 self.assertTrue(x == 6)