diff --git a/active_plugins/filterobjects_stringmatch.py b/active_plugins/filterobjects_stringmatch.py index 8714e77..9634380 100644 --- a/active_plugins/filterobjects_stringmatch.py +++ b/active_plugins/filterobjects_stringmatch.py @@ -3,6 +3,7 @@ Divider, ) from cellprofiler_core.setting.text import Alphanumeric +from cellprofiler_core.setting.choice import Choice __doc__ = "" @@ -19,6 +20,8 @@ LOGGER = logging.getLogger(__name__) +METHOD_EXACT = "Exact match" +METHOD_CONTAINS = "String contains" class FilterObjects_StringMatch(ObjectProcessing): module_name = "FilterObjects_StringMatch" @@ -46,20 +49,32 @@ 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 = + self.rules.create_settings() def settings(self): settings = super(FilterObjects_StringMatch, self).settings() - settings += [self.filter_out] + settings += [self.filter_out,self.filter_method] 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 ] return visible_settings @@ -165,12 +180,15 @@ 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 + 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