DataSelection.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2016 Imperial College London
5  * Copyright 2016 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_DataSelection_H
21 #define MIRTK_DataSelection_H
22 
23 #include "mirtk/Object.h"
24 
25 #include "mirtk/UnorderedSet.h"
26 #include "mirtk/Algorithm.h"
27 
28 
29 namespace mirtk { namespace data {
30 
31 /// Set of selected data point IDs
32 typedef UnorderedSet<int> Selection;
33 
34 // -----------------------------------------------------------------------------
35 /// Base class of data selectors
36 class Selector : public Object
37 {
38  mirtkAbstractMacro(Selector);
39 
40 public:
41 
42  /// Destructor
43  virtual ~Selector() {};
44 
45  /// Run selection query and return IDs of selected data points
46  ///
47  /// \param[in] values Values of the n data points.
48  ///
49  /// \returns Set of IDs of the selected data points.
50  virtual Selection Evaluate(const Array<double> &values) const = 0;
51 };
52 
53 // -----------------------------------------------------------------------------
54 /// Combine one or more data selection criteria using a logical operator
55 class LogicalOp : public Selector
56 {
57  mirtkAbstractMacro(LogicalOp);
58 
59  typedef SharedPtr<const Selector> SelectorPointer;
60  typedef List<SelectorPointer> SelectorList;
61 
62 protected:
63 
64  /// Individual data selectors
65  mirtkAttributeMacro(SelectorList, Criteria);
66 
67 public:
68 
69  /// Number of data selection criteria
70  int NumberOfCriteria() const
71  {
72  return static_cast<int>(_Criteria.size());
73  }
74 
75  /// Get n-th data selection criterium
76  SelectorPointer Criterium(int i) const
77  {
78  auto it = _Criteria.begin();
79  for (int pos = 0; pos < i; ++pos) ++it;
80  return *it;
81  }
82 
83  /// Add data selection criterium
84  void Push(const SelectorPointer &criterium)
85  {
86  _Criteria.push_back(criterium);
87  }
88 };
89 
90 // -----------------------------------------------------------------------------
91 /// Combine one or more data selection criteria using a logical AND
92 class LogicalAnd : public LogicalOp
93 {
94  mirtkObjectMacro(LogicalAnd);
95 
96 public:
97 
98  /// Run selection query and return IDs of selected data points
99  virtual Selection Evaluate(const Array<double> &values) const
100  {
101  if (_Criteria.empty()) return Selection();
102  auto criterium = _Criteria.begin();
103  auto selection = (*criterium)->Evaluate(values);
104  while (++criterium != _Criteria.end()) {
105  selection = Intersection(selection, (*criterium)->Evaluate(values));
106  }
107  return selection;
108  }
109 };
110 
111 // -----------------------------------------------------------------------------
112 /// Combine one or more data selection criteria using a logical OR
113 class LogicalOr : public LogicalOp
114 {
115  mirtkObjectMacro(LogicalOr);
116 
117 public:
118 
119  /// Run selection query and return IDs of selected data points
120  virtual Selection Evaluate(const Array<double> &values) const
121  {
122  Selection selection;
123  for (auto criterium : _Criteria) {
124  auto ids = criterium->Evaluate(values);
125  for (auto id : ids) {
126  selection.insert(id);
127  }
128  }
129  return selection;
130  }
131 };
132 
133 // -----------------------------------------------------------------------------
134 /// Base class of data selection criteria
136 {
137  mirtkAbstractMacro(SelectionCriterium);
138 
139 public:
140 
141  /// Run selection query and return IDs of selected data points
142  virtual Selection Evaluate(const Array<double> &values) const
143  {
144  Selection selection;
145  selection.reserve(values.size());
146  const int n = static_cast<int>(values.size());
147  for (int id = 0; id < n; ++id) {
148  if (this->Select(values[id])) {
149  selection.insert(id);
150  }
151  }
152  return selection;
153  }
154 
155  /// Evaluate criterium for given data value
156  virtual bool Select(double) const = 0;
157 };
158 
159 // =============================================================================
160 // Data selection criteria
161 // =============================================================================
162 
163 namespace select {
164 
165 
166 // -----------------------------------------------------------------------------
167 /// Select data points with a value equal the specified value
168 class Equal : public SelectionCriterium
169 {
170  mirtkObjectMacro(Equal);
171 
172  /// Upper data value threshold
173  mirtkPublicAttributeMacro(double, Value);
174 
175 public:
176 
177  /// Constructor
178  Equal(double value) : _Value(value) {}
179 
180  /// Evaluate criterium for given data value
181  virtual bool Select(double value) const
182  {
183  return fequal(value, _Value);
184  }
185 };
186 
187 // -----------------------------------------------------------------------------
188 /// Select data points a value different from the specified value
190 {
191  mirtkObjectMacro(NotEqual);
192 
193  /// Upper data value threshold
194  mirtkPublicAttributeMacro(double, Value);
195 
196 public:
197 
198  /// Constructor
199  NotEqual(double value) : _Value(value) {}
200 
201  /// Evaluate criterium for given data value
202  virtual bool Select(double value) const
203  {
204  return !fequal(value, _Value);
205  }
206 };
207 
208 // -----------------------------------------------------------------------------
209 /// Select data points with a value less than the specified threshold
211 {
212  mirtkObjectMacro(LessThan);
213 
214  /// Upper data value threshold
215  mirtkPublicAttributeMacro(double, Threshold);
216 
217 public:
218 
219  /// Constructor
220  LessThan(double threshold) : _Threshold(threshold) {}
221 
222  /// Evaluate criterium for given data value
223  virtual bool Select(double value) const
224  {
225  return value < _Threshold;
226  }
227 };
228 
229 // -----------------------------------------------------------------------------
230 /// Select data points with a value less than or equal the specified threshold
232 {
233  mirtkObjectMacro(LessOrEqual);
234 
235  /// Upper data value threshold
236  mirtkPublicAttributeMacro(double, Threshold);
237 
238 public:
239 
240  /// Constructor
241  LessOrEqual(double threshold) : _Threshold(threshold) {}
242 
243  /// Evaluate criterium for given data value
244  virtual bool Select(double value) const
245  {
246  return value <= _Threshold;
247  }
248 };
249 
250 // -----------------------------------------------------------------------------
251 /// Select data points with a value greater than the specified threshold
253 {
254  mirtkObjectMacro(GreaterThan);
255 
256  /// Lower data value threshold
257  mirtkPublicAttributeMacro(double, Threshold);
258 
259 public:
260 
261  /// Constructor
262  GreaterThan(double threshold) : _Threshold(threshold) {}
263 
264  /// Evaluate criterium for given data value
265  virtual bool Select(double value) const
266  {
267  return value > _Threshold;
268  }
269 };
270 
271 // -----------------------------------------------------------------------------
272 /// Select data points with a value greater than or equal the specified threshold
274 {
275  mirtkObjectMacro(GreaterOrEqual);
276 
277  /// Lower data value threshold
278  mirtkPublicAttributeMacro(double, Threshold);
279 
280 public:
281 
282  /// Constructor
283  GreaterOrEqual(double threshold) : _Threshold(threshold) {}
284 
285  /// Evaluate criterium for given data value
286  virtual bool Select(double value) const
287  {
288  return value >= _Threshold;
289  }
290 };
291 
292 
293 } } } // namespace mirtk::data::select
294 
295 #endif // MIRTK_DataSelection_H
virtual ~Selector()
Destructor.
Definition: DataSelection.h:43
Select data points with a value equal the specified value.
GreaterOrEqual(double threshold)
Constructor.
Select data points with a value greater than the specified threshold.
int NumberOfCriteria() const
Number of data selection criteria.
Definition: DataSelection.h:70
virtual bool Select(double value) const
Evaluate criterium for given data value.
UnorderedSet< T > Intersection(const UnorderedSet< T > &a, const UnorderedSet< T > &b)
Definition: Algorithm.h:302
Select data points with a value less than the specified threshold.
GreaterThan(double threshold)
Constructor.
virtual bool Select(double value) const
Evaluate criterium for given data value.
Base class of data selection criteria.
SelectorPointer Criterium(int i) const
Get n-th data selection criterium.
Definition: DataSelection.h:76
MIRTKCU_API bool fequal(double a, double b, double tol=1e-12)
Definition: Math.h:138
virtual bool Select(double value) const
Evaluate criterium for given data value.
virtual Selection Evaluate(const Array< double > &values) const
Run selection query and return IDs of selected data points.
Definition: DataSelection.h:99
Select data points a value different from the specified value.
Definition: IOConfig.h:41
Equal(double value)
Constructor.
virtual Selection Evaluate(const Array< double > &values) const
Run selection query and return IDs of selected data points.
virtual Selection Evaluate(const Array< double > &values) const
Run selection query and return IDs of selected data points.
Combine one or more data selection criteria using a logical AND.
Definition: DataSelection.h:92
virtual bool Select(double value) const
Evaluate criterium for given data value.
virtual bool Select(double value) const
Evaluate criterium for given data value.
virtual Selection Evaluate(const Array< double > &values) const =0
Combine one or more data selection criteria using a logical operator.
Definition: DataSelection.h:55
LessOrEqual(double threshold)
Constructor.
Select data points with a value less than or equal the specified threshold.
Select data points with a value greater than or equal the specified threshold.
Base class of data selectors.
Definition: DataSelection.h:36
NotEqual(double value)
Constructor.
virtual bool Select(double value) const
Evaluate criterium for given data value.
void Push(const SelectorPointer &criterium)
Add data selection criterium.
Definition: DataSelection.h:84
LessThan(double threshold)
Constructor.
Combine one or more data selection criteria using a logical OR.