From c0f85487234502199fdbbee68089c44ea6c36d95 Mon Sep 17 00:00:00 2001 From: Erin Weisbart <54687786+ErinWeisbart@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:17:47 -0700 Subject: [PATCH] enhance FilterObjects_StringMatch (#257) add string contains option, configurable measurement selection to FilterObjects_StringMatch --- active_plugins/filterobjects_stringmatch.py | 44 ++++++++++++++----- .../supported_plugins.md | 1 + 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/active_plugins/filterobjects_stringmatch.py b/active_plugins/filterobjects_stringmatch.py index 8714e77..92c680a 100644 --- a/active_plugins/filterobjects_stringmatch.py +++ b/active_plugins/filterobjects_stringmatch.py @@ -3,6 +3,8 @@ Divider, ) from cellprofiler_core.setting.text import Alphanumeric +from cellprofiler_core.setting.choice import Choice +from cellprofiler_core.setting import Measurement __doc__ = "" @@ -19,6 +21,8 @@ LOGGER = logging.getLogger(__name__) +METHOD_EXACT = "Exact match" +METHOD_CONTAINS = "String contains" class FilterObjects_StringMatch(ObjectProcessing): module_name = "FilterObjects_StringMatch" @@ -46,20 +50,37 @@ def create_settings(self): self.filter_out = Alphanumeric( "What string to filter out", "AAAA", - doc="""Enter a name for the measurement calculated by this module.""", + doc="""Enter the string that should be used to filter objects.""", ) + self.filter_method = Choice( + "Filter method", + [METHOD_EXACT, METHOD_CONTAINS], + doc="""Select whether to only filter objects that are an exact match for the string entered + (e.g. Object 'AAAAB' will NOT be filtered by string 'AAAA') + or to filter any object that contains the string entered + (e.g. Object 'AAAAB' will be filtered by string 'AAAA').""", + ) + + self.filter_column = Measurement("Measurement", + self.x_name.get_value, + "Barcode_BarcodeCalled", + doc="""Select the measurement column that will be used for filtering.""", + ) + self.rules.create_settings() def settings(self): settings = super(FilterObjects_StringMatch, self).settings() - settings += [self.filter_out] + settings += [self.filter_out,self.filter_method, self.filter_column] return settings def visible_settings(self): visible_settings = super(FilterObjects_StringMatch, self).visible_settings() visible_settings += [ - self.filter_out + self.filter_out, + self.filter_method, + self.filter_column ] return visible_settings @@ -164,13 +185,16 @@ def keep_by_string(self, workspace, src_objects): """ src_name = self.x_name.value m = workspace.measurements - values = m.get_current_measurement(src_name, "Barcode_BarcodeCalled") - # Is this structure still necessary or is it an artifact? - # Could be just values == self.filter_out.value - # Make an array of True - hits = numpy.ones(len(values), bool) - # Fill with False for those where we want to filter out - hits[values == self.filter_out.value] = False + values = m.get_current_measurement(src_name, self.filter_column.value) + if self.filter_method == METHOD_EXACT: + # Is this structure still necessary or is it an artifact? + # Could be just values == self.filter_out.value + # Make an array of True + hits = numpy.ones(len(values), bool) + # Fill with False for those where we want to filter out + hits[values == self.filter_out.value] = False + elif self.filter_method == METHOD_CONTAINS: + hits = [self.filter_out.value in x for x in values] # Get object numbers for things that are True indexes = numpy.argwhere(hits)[:, 0] # Objects are 1 counted, Python is 0 counted diff --git a/documentation/CP-plugins-documentation/supported_plugins.md b/documentation/CP-plugins-documentation/supported_plugins.md index 5d47a4b..72e1f2b 100644 --- a/documentation/CP-plugins-documentation/supported_plugins.md +++ b/documentation/CP-plugins-documentation/supported_plugins.md @@ -17,6 +17,7 @@ Those plugins that do have extra documentation contain links below. | CompensateColors | CompensateColors determines how much signal in any given channel is because of bleed-through from another channel and removes the bleed-through. It can be performed across an image or masked to objects and provides a number of preprocessing and rescaling options to allow for troubleshooting if input image intensities are not well matched. | No | | N/A | | DistanceTransform | DistanceTransform computes the distance transform of a binary image. The distance of each foreground pixel is computed to the nearest background pixel and the resulting image is then scaled so that the largest distance is 1. | No | | N/A | | EnhancedMeasureTexture| EnhancedMeasureTexture measures the degree and nature of textures within an image or objects in a more comprehensive/tuneable manner than the MeasureTexture module native to CellProfiler. | No | | N/A | +| FilterObjects_StringMatch| FilterObjects_StringMatch allows filtering of objects using exact or partial string matching in a manner similar to FilterObjects. | No | | N/A | | HistogramEqualization | HistogramEqualization increases the global contrast of a low-contrast image or volume. Histogram equalization redistributes intensities to utilize the full range of intensities, such that the most common frequencies are more distinct. This module can perform either global or local histogram equalization. | No | | N/A | | HistogramMatching | HistogramMatching manipulates the pixel intensity values an input image and matches them to the histogram of a reference image. It can be used as a way to normalize intensities across different 2D or 3D images or different frames of the same 3D image. It allows you to choose which frame to use as the reference. | No | | N/A | | PixelShuffle | PixelShuffle takes the intensity of each pixel in an image and randomly shuffles its position. | No | | N/A |