|
3 | 3 | Divider, |
4 | 4 | ) |
5 | 5 | from cellprofiler_core.setting.text import Alphanumeric |
| 6 | +from cellprofiler_core.setting.choice import Choice |
| 7 | +from cellprofiler_core.setting import Measurement |
6 | 8 |
|
7 | 9 | __doc__ = "" |
8 | 10 |
|
|
19 | 21 |
|
20 | 22 | LOGGER = logging.getLogger(__name__) |
21 | 23 |
|
| 24 | +METHOD_EXACT = "Exact match" |
| 25 | +METHOD_CONTAINS = "String contains" |
22 | 26 |
|
23 | 27 | class FilterObjects_StringMatch(ObjectProcessing): |
24 | 28 | module_name = "FilterObjects_StringMatch" |
@@ -46,20 +50,37 @@ def create_settings(self): |
46 | 50 | self.filter_out = Alphanumeric( |
47 | 51 | "What string to filter out", |
48 | 52 | "AAAA", |
49 | | - doc="""Enter a name for the measurement calculated by this module.""", |
| 53 | + doc="""Enter the string that should be used to filter objects.""", |
50 | 54 | ) |
51 | 55 |
|
| 56 | + self.filter_method = Choice( |
| 57 | + "Filter method", |
| 58 | + [METHOD_EXACT, METHOD_CONTAINS], |
| 59 | + doc="""Select whether to only filter objects that are an exact match for the string entered |
| 60 | + (e.g. Object 'AAAAB' will NOT be filtered by string 'AAAA') |
| 61 | + or to filter any object that contains the string entered |
| 62 | + (e.g. Object 'AAAAB' will be filtered by string 'AAAA').""", |
| 63 | + ) |
| 64 | + |
| 65 | + self.filter_column = Measurement("Measurement", |
| 66 | + self.x_name.get_value, |
| 67 | + "Barcode_BarcodeCalled", |
| 68 | + doc="""Select the measurement column that will be used for filtering.""", |
| 69 | + ) |
| 70 | + |
52 | 71 | self.rules.create_settings() |
53 | 72 |
|
54 | 73 | def settings(self): |
55 | 74 | settings = super(FilterObjects_StringMatch, self).settings() |
56 | | - settings += [self.filter_out] |
| 75 | + settings += [self.filter_out,self.filter_method, self.filter_column] |
57 | 76 | return settings |
58 | 77 |
|
59 | 78 | def visible_settings(self): |
60 | 79 | visible_settings = super(FilterObjects_StringMatch, self).visible_settings() |
61 | 80 | visible_settings += [ |
62 | | - self.filter_out |
| 81 | + self.filter_out, |
| 82 | + self.filter_method, |
| 83 | + self.filter_column |
63 | 84 | ] |
64 | 85 | return visible_settings |
65 | 86 |
|
@@ -164,13 +185,16 @@ def keep_by_string(self, workspace, src_objects): |
164 | 185 | """ |
165 | 186 | src_name = self.x_name.value |
166 | 187 | m = workspace.measurements |
167 | | - values = m.get_current_measurement(src_name, "Barcode_BarcodeCalled") |
168 | | - # Is this structure still necessary or is it an artifact? |
169 | | - # Could be just values == self.filter_out.value |
170 | | - # Make an array of True |
171 | | - hits = numpy.ones(len(values), bool) |
172 | | - # Fill with False for those where we want to filter out |
173 | | - hits[values == self.filter_out.value] = False |
| 188 | + values = m.get_current_measurement(src_name, self.filter_column.value) |
| 189 | + if self.filter_method == METHOD_EXACT: |
| 190 | + # Is this structure still necessary or is it an artifact? |
| 191 | + # Could be just values == self.filter_out.value |
| 192 | + # Make an array of True |
| 193 | + hits = numpy.ones(len(values), bool) |
| 194 | + # Fill with False for those where we want to filter out |
| 195 | + hits[values == self.filter_out.value] = False |
| 196 | + elif self.filter_method == METHOD_CONTAINS: |
| 197 | + hits = [self.filter_out.value in x for x in values] |
174 | 198 | # Get object numbers for things that are True |
175 | 199 | indexes = numpy.argwhere(hits)[:, 0] |
176 | 200 | # Objects are 1 counted, Python is 0 counted |
|
0 commit comments