DataFunctions.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 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_DataFunctions_H
21 #define MIRTK_DataFunctions_H
22 
23 #include "mirtk/DataOp.h"
24 #include "mirtk/DataStatistics.h"
25 #include "mirtk/Parallel.h"
26 
27 
28 namespace mirtk { namespace data { namespace op {
29 
30 
31 // -----------------------------------------------------------------------------
32 /// Reset data mask
33 class ResetMask : public Op
34 {
35 private:
36 
37  bool _Value;
38 
39 public:
40 
41  ResetMask(bool value = true) : _Value(value) {}
42 
43  /// Process given data (not thread-safe!)
44  virtual void Process(int n, double *, bool *mask = nullptr)
45  {
46  if (mask != nullptr) {
47  memset(mask, _Value ? 1 : 0, n * sizeof(bool));
48  }
49  }
50 };
51 
52 // -----------------------------------------------------------------------------
53 /// Invert mask values
54 class InvertMask : public Op
55 {
56 public:
57 
58  /// Process given data (not thread-safe!)
59  virtual void Process(int n, double *, bool *mask = nullptr)
60  {
61  if (mask != nullptr) {
62  for (int i = 0; i < n; ++i) {
63  mask[i] = !mask[i];
64  }
65  }
66  }
67 };
68 
69 // -----------------------------------------------------------------------------
70 /// Set value of unmasked data points
71 class SetInsideValue : public Op
72 {
73 private:
74 
75  double *_Data;
76  bool *_Mask;
77  double _Value;
78 
79 public:
80 
81  SetInsideValue(double value = .0) : _Value(value) {}
82 
83  // Called by TBB's parallel_for, for internal use only!
84  void operator()(const blocked_range<int> &re) const
85  {
86  double *data = _Data + re.begin();
87  if (_Mask) {
88  bool *mask = _Mask + re.begin();
89  for (int i = re.begin(); i != re.end(); ++i, ++data, ++mask) {
90  if (*mask == true) *data = _Value;
91  }
92  } else {
93  for (int i = re.begin(); i != re.end(); ++i, ++data) {
94  *data = _Value;
95  }
96  }
97  }
98 
99  /// Process given data (not thread-safe!)
100  virtual void Process(int n, double *data, bool *mask = NULL)
101  {
102  _Data = data;
103  _Mask = mask;
104  parallel_for(blocked_range<int>(0, n), *this);
105  }
106 };
107 
108 // -----------------------------------------------------------------------------
109 /// Set value of masked data points
110 class SetOutsideValue : public Op
111 {
112 private:
113 
114  double *_Data;
115  bool *_Mask;
116  double _Value;
117 
118 public:
119 
120  SetOutsideValue(double value = .0) : _Value(value) {}
121 
122  // Called by TBB's parallel_for, for internal use only!
123  void operator()(const blocked_range<int> &re) const
124  {
125  double *data = _Data + re.begin();
126  bool *mask = _Mask + re.begin();
127  for (int i = re.begin(); i != re.end(); ++i, ++data, ++mask) {
128  if (*mask == false) *data = _Value;
129  }
130  }
131 
132  /// Process given data (not thread-safe!)
133  virtual void Process(int n, double *data, bool *mask = NULL)
134  {
135  if (mask) {
136  _Data = data;
137  _Mask = mask;
138  parallel_for(blocked_range<int>(0, n), *this);
139  }
140  }
141 };
142 
143 // -----------------------------------------------------------------------------
144 /// Base class of element-wise data transformations
145 class ElementWiseUnaryOp : public Op
146 {
147 private:
148 
149  double *_Data;
150  bool *_Mask;
151 
152 public:
153 
154  // Called by TBB's parallel_for, for internal use only!
155  void operator()(const blocked_range<int> &re) const
156  {
157  double *data = _Data + re.begin();
158  if (_Mask) {
159  bool *mask = _Mask + re.begin();
160  for (int i = re.begin(); i != re.end(); ++i, ++data, ++mask) {
161  if (*mask) *data = this->Op(*data, *mask);
162  }
163  } else {
164  bool mask = true;
165  for (int i = re.begin(); i != re.end(); ++i, ++data) {
166  *data = this->Op(*data, mask);
167  }
168  }
169  }
170 
171  /// Transform data value and/or mask it by setting mask = false
172  virtual double Op(double value, bool &) const = 0;
173 
174  /// Process given data (not thread-safe!)
175  virtual void Process(int n, double *data, bool *mask = NULL)
176  {
177  _Data = data;
178  _Mask = mask;
179  // MUST be called in the base class which defines Op!
180  //parallel_for(blocked_range<int>(0, n), *this);
181  }
182 };
183 
184 // -----------------------------------------------------------------------------
185 /// Base class of element-wise data transformations
186 class ElementWiseBinaryOp : public Op
187 {
188  /// Constant value of right-hand side
189  mirtkPublicAttributeMacro(double, Constant);
190 
191  /// Pointer to memory of constant value
192  mirtkPublicAggregateMacro(const double, ConstantPointer);
193 
194  /// File path of dataset of right-hand side
195  mirtkPublicAttributeMacro(string, FileName);
196 
197  /// Name of input point/cell data array
198  mirtkPublicAttributeMacro(string, ArrayName);
199 
200  /// Whether input array is cell data
201  mirtkPublicAttributeMacro(bool, IsCellData);
202 
203 private:
204 
205  double *_Data;
206  bool *_Mask;
207  SharedPtr<double> _Other;
208 
209 protected:
210 
211  /// Constructor
212  ElementWiseBinaryOp(double value)
213  :
214  _Constant(value), _ConstantPointer(nullptr), _Other(nullptr)
215  {}
216 
217  /// Constructor
218  ElementWiseBinaryOp(const double *value)
219  :
220  _Constant(NaN), _ConstantPointer(value), _Other(nullptr)
221  {}
222 
223  /// Constructor
224  ElementWiseBinaryOp(const char *fname)
225  :
226  _Constant(NaN), _ConstantPointer(nullptr), _FileName(fname), _Other(nullptr)
227  {}
228 
229  /// Constructor
230  ElementWiseBinaryOp(const char *fname, double value)
231  :
232  _Constant(value), _ConstantPointer(nullptr), _FileName(fname), _Other(nullptr)
233  {}
234 
235  /// Constructor
236  ElementWiseBinaryOp(const char *fname, const double *value)
237  :
238  _Constant(NaN), _ConstantPointer(value), _FileName(fname), _Other(nullptr)
239  {}
240 
241  /// Constructor
242  ElementWiseBinaryOp(const char *fname, const char *aname, bool cell_data = false)
243  :
244  _Constant(NaN), _ConstantPointer(nullptr), _FileName(fname), _ArrayName(aname ? aname : ""), _IsCellData(cell_data), _Other(nullptr)
245  {}
246 
247  /// Constructor
248  ElementWiseBinaryOp(const char *fname, const char *aname, double value, bool cell_data = false)
249  :
250  _Constant(value), _ConstantPointer(nullptr), _FileName(fname), _ArrayName(aname ? aname : ""), _IsCellData(cell_data), _Other(nullptr)
251  {}
252 
253  /// Constructor
254  ElementWiseBinaryOp(const char *fname, const char *aname, const double *value, bool cell_data = false)
255  :
256  _Constant(NaN), _ConstantPointer(value), _FileName(fname), _ArrayName(aname ? aname : ""), _IsCellData(cell_data), _Other(nullptr)
257  {}
258 
259 public:
260 
261  // Called by TBB's parallel_for, for internal use only!
262  void operator()(const blocked_range<int> &re) const
263  {
264  double *data = _Data + re.begin();
265  if (_Other) {
266  double *other = _Other.get() + re.begin();
267  if (_Mask) {
268  bool *mask = _Mask + re.begin();
269  for (int i = re.begin(); i != re.end(); ++i) {
270  if (*mask) *data = this->Op(*data, *other, *mask);
271  ++data, ++other, ++mask;
272  }
273  } else {
274  bool mask;
275  for (int i = re.begin(); i != re.end(); ++i) {
276  mask = true;
277  *data = this->Op(*data, *other, mask);
278  ++data, ++other;
279  }
280  }
281  } else {
282  double c = (_ConstantPointer ? *_ConstantPointer : _Constant);
283  if (_Mask) {
284  bool *mask = _Mask + re.begin();
285  for (int i = re.begin(); i != re.end(); ++i) {
286  if (*mask) *data = this->Op(*data, c, *mask);
287  ++data, ++mask;
288  }
289  } else {
290  bool mask;
291  for (int i = re.begin(); i != re.end(); ++i) {
292  mask = true;
293  *data = this->Op(*data, c, mask);
294  ++data;
295  }
296  }
297  }
298  }
299 
300  /// Transform data value and/or mask it by setting mask = false
301  virtual double Op(double value, double, bool &) const = 0;
302 
303 protected:
304 
305  /// Initialize processing and read data from file
306  void Initialize(int n, double *data, bool *mask = nullptr)
307  {
308  _Data = data;
309  _Mask = mask;
310  _Other.reset();
311  if (!_FileName.empty()) {
312  UniquePtr<double[]> other;
313  if (n != Read(_FileName.c_str(), other, nullptr, nullptr, nullptr, _ArrayName.c_str(), _IsCellData)) {
314  cerr << "Input file " << _FileName << " has different number of data points!" << endl;
315  exit(1);
316  }
317  _Other = SharedPtr<double>(other.release(), std::default_delete<double[]>());
318  }
319  }
320 
321  /// Finalize processing and release temporary memory
322  void Finalize()
323  {
324  _Other.reset();
325  }
326 };
327 
328 // -----------------------------------------------------------------------------
329 /// Compute element-wise absolute value
330 class Abs : public ElementWiseUnaryOp
331 {
332 public:
333 
334  /// Transform data value and/or mask data value by setting *mask = false
335  virtual double Op(double value, bool &) const
336  {
337  return abs(value);
338  }
339 
340  /// Process given data (not thread-safe!)
341  virtual void Process(int n, double *data, bool *mask = NULL)
342  {
343  ElementWiseUnaryOp::Process(n, data, mask);
344  parallel_for(blocked_range<int>(0, n), *this);
345  }
346 };
347 
348 // -----------------------------------------------------------------------------
349 /// Compute element-wise power
350 class Pow : public ElementWiseUnaryOp
351 {
352  mirtkPublicAttributeMacro(double, Exponent);
353 
354 public:
355 
356  Pow(double exponent) : _Exponent(exponent) {}
357 
358  /// Transform data value and/or mask data value by setting *mask = false
359  virtual double Op(double value, bool &) const
360  {
361  return pow(value, _Exponent);
362  }
363 
364  /// Process given data (not thread-safe!)
365  virtual void Process(int n, double *data, bool *mask = NULL)
366  {
367  ElementWiseUnaryOp::Process(n, data, mask);
368  parallel_for(blocked_range<int>(0, n), *this);
369  }
370 };
371 
372 // -----------------------------------------------------------------------------
373 /// Compute element-wise exponential map
374 class Exp : public ElementWiseUnaryOp
375 {
376 public:
377 
378  /// Transform data value and/or mask it by setting mask = false
379  virtual double Op(double value, bool &) const
380  {
381  return exp(value);
382  }
383 
384  /// Process given data (not thread-safe!)
385  virtual void Process(int n, double *data, bool *mask = NULL)
386  {
387  ElementWiseUnaryOp::Process(n, data, mask);
388  parallel_for(blocked_range<int>(0, n), *this);
389  }
390 };
391 
392 // -----------------------------------------------------------------------------
393 /// Compute element-wise logarithmic map
394 class Log : public ElementWiseUnaryOp
395 {
396  mirtkPublicAttributeMacro(double, Base);
397  mirtkPublicAttributeMacro(double, Threshold);
398 
399 public:
400 
401  Log(double base, double threshold = .01) : _Base(base), _Threshold(threshold) {}
402 
403  /// Transform data value and/or mask data value by setting *mask = false
404  virtual double Op(double value, bool &) const
405  {
406  if (value < _Threshold) value = _Threshold;
407  return log(value) / log(_Base);
408  }
409 
410  /// Process given data (not thread-safe!)
411  virtual void Process(int n, double *data, bool *mask = NULL)
412  {
413  ElementWiseUnaryOp::Process(n, data, mask);
414  parallel_for(blocked_range<int>(0, n), *this);
415  }
416 };
417 
418 // -----------------------------------------------------------------------------
419 /// Compute element-wise binary logarithm
420 class Lb : public ElementWiseUnaryOp
421 {
422  mirtkPublicAttributeMacro(double, Threshold);
423 
424 public:
425 
426  Lb(double threshold = .01) : _Threshold(threshold) {}
427 
428  /// Transform data value and/or mask data value by setting *mask = false
429  virtual double Op(double value, bool &) const
430  {
431  if (value < _Threshold) value = _Threshold;
432  return log2(value);
433  }
434 
435  /// Process given data (not thread-safe!)
436  virtual void Process(int n, double *data, bool *mask = NULL)
437  {
438  ElementWiseUnaryOp::Process(n, data, mask);
439  parallel_for(blocked_range<int>(0, n), *this);
440  }
441 };
442 
443 // -----------------------------------------------------------------------------
444 /// Compute element-wise natural logarithm
445 class Ln : public ElementWiseUnaryOp
446 {
447  mirtkPublicAttributeMacro(double, Threshold);
448 
449 public:
450 
451  Ln(double threshold = .01) : _Threshold(threshold) {}
452 
453  /// Transform data value and/or mask data value by setting *mask = false
454  virtual double Op(double value, bool &) const
455  {
456  if (value < _Threshold) value = _Threshold;
457  return log(value);
458  }
459 
460  /// Process given data (not thread-safe!)
461  virtual void Process(int n, double *data, bool *mask = NULL)
462  {
463  ElementWiseUnaryOp::Process(n, data, mask);
464  parallel_for(blocked_range<int>(0, n), *this);
465  }
466 };
467 
468 // -----------------------------------------------------------------------------
469 /// Compute element-wise logarithm to base 10
470 class Lg : public ElementWiseUnaryOp
471 {
472  mirtkPublicAttributeMacro(double, Threshold);
473 
474 public:
475 
476  Lg(double threshold = .01) : _Threshold(threshold) {}
477 
478  /// Transform data value and/or mask data value by setting *mask = false
479  virtual double Op(double value, bool &) const
480  {
481  if (value < _Threshold) value = _Threshold;
482  return log10(value);
483  }
484 
485  /// Process given data (not thread-safe!)
486  virtual void Process(int n, double *data, bool *mask = NULL)
487  {
488  ElementWiseUnaryOp::Process(n, data, mask);
489  parallel_for(blocked_range<int>(0, n), *this);
490  }
491 };
492 
493 // -----------------------------------------------------------------------------
494 /// Element-wise addition
495 class Add : public ElementWiseBinaryOp
496 {
497 public:
498 
499  /// Constructor
500  Add(double value) : ElementWiseBinaryOp(value) {}
501 
502  /// Constructor
503  Add(const double *value) : ElementWiseBinaryOp(value) {}
504 
505  /// Constructor
506  Add(const char *fname) : ElementWiseBinaryOp(fname) {}
507 
508  /// Transform data value and/or mask data value by setting *mask = false
509  virtual double Op(double value, double constant, bool &) const
510  {
511  return value + constant;
512  }
513 
514  /// Process given data (not thread-safe!)
515  virtual void Process(int n, double *data, bool *mask = NULL)
516  {
517  Initialize(n, data, mask);
518  parallel_for(blocked_range<int>(0, n), *this);
519  Finalize();
520  }
521 };
522 
523 // -----------------------------------------------------------------------------
524 /// Element-wise subtraction
525 class Sub : public ElementWiseBinaryOp
526 {
527 public:
528 
529  /// Constructor
530  Sub(double value) : ElementWiseBinaryOp(value) {}
531 
532  /// Constructor
533  Sub(const double *value) : ElementWiseBinaryOp(value) {}
534 
535  /// Constructor
536  Sub(const char *fname) : ElementWiseBinaryOp(fname) {}
537 
538  /// Transform data value and/or mask data value by setting *mask = false
539  virtual double Op(double value, double constant, bool &) const
540  {
541  return value - constant;
542  }
543 
544  /// Process given data (not thread-safe!)
545  virtual void Process(int n, double *data, bool *mask = NULL)
546  {
547  Initialize(n, data, mask);
548  parallel_for(blocked_range<int>(0, n), *this);
549  Finalize();
550  }
551 };
552 
553 // -----------------------------------------------------------------------------
554 /// Element-wise multiplication
555 class Mul : public ElementWiseBinaryOp
556 {
557 public:
558 
559  /// Constructor
560  Mul(double value) : ElementWiseBinaryOp(value) {}
561 
562  /// Constructor
563  Mul(const double *value) : ElementWiseBinaryOp(value) {}
564 
565  /// Constructor
566  Mul(const char *fname) : ElementWiseBinaryOp(fname) {}
567 
568  /// Transform data value and/or mask data value by setting *mask = false
569  virtual double Op(double value, double constant, bool &) const
570  {
571  return value * constant;
572  }
573 
574  /// Process given data (not thread-safe!)
575  virtual void Process(int n, double *data, bool *mask = NULL)
576  {
577  Initialize(n, data, mask);
578  parallel_for(blocked_range<int>(0, n), *this);
579  Finalize();
580  }
581 };
582 
583 // -----------------------------------------------------------------------------
584 /// Element-wise division
585 class Div : public ElementWiseBinaryOp
586 {
587 public:
588 
589  /// Constructor
590  Div(double value) : ElementWiseBinaryOp(value) {}
591 
592  /// Constructor
593  Div(const double *value) : ElementWiseBinaryOp(value) {}
594 
595  /// Constructor
596  Div(const char *fname) : ElementWiseBinaryOp(fname) {}
597 
598  /// Transform data value and/or mask data value by setting *mask = false
599  virtual double Op(double value, double constant, bool &) const
600  {
601  return (constant != .0 ? value / constant : numeric_limits<double>::quiet_NaN());
602  }
603 
604  /// Process given data (not thread-safe!)
605  virtual void Process(int n, double *data, bool *mask = NULL)
606  {
607  Initialize(n, data, mask);
608  parallel_for(blocked_range<int>(0, n), *this);
609  Finalize();
610  }
611 };
612 
613 // -----------------------------------------------------------------------------
614 /// Element-wise division
616 {
617 public:
618 
619  /// Constructor
620  DivWithZero(double value) : ElementWiseBinaryOp(value) {}
621 
622  /// Constructor
623  DivWithZero(const double *value) : ElementWiseBinaryOp(value) {}
624 
625  /// Constructor
626  DivWithZero(const char *fname) : ElementWiseBinaryOp(fname) {}
627 
628  /// Transform data value and/or mask data value by setting *mask = false
629  virtual double Op(double value, double constant, bool &) const
630  {
631  return (constant != .0 ? value / constant : .0);
632  }
633 
634  /// Process given data (not thread-safe!)
635  virtual void Process(int n, double *data, bool *mask = NULL)
636  {
637  Initialize(n, data, mask);
638  parallel_for(blocked_range<int>(0, n), *this);
639  Finalize();
640  }
641 };
642 
643 // -----------------------------------------------------------------------------
644 /// Map values (e.g. segmentation labels)
645 class Map : public ElementWiseUnaryOp
646 {
647  typedef UnorderedMap<double, double> ValueMapType;
648 
649  /// Map of values
650  mirtkAttributeMacro(ValueMapType, ValueMap);
651 
652 public:
653 
654  /// Insert map from a to b
655  void Insert(double a, double b)
656  {
657  _ValueMap[a] = b;
658  }
659 
660  /// Transform data value and/or mask data value by setting *mask = false
661  virtual double Op(double value, bool &) const
662  {
663  auto it = _ValueMap.find(value);
664  if (it != _ValueMap.end()) {
665  return it->second;
666  } else {
667  return value;
668  }
669  }
670 
671  /// Process given data (not thread-safe!)
672  virtual void Process(int n, double *data, bool *mask = NULL)
673  {
674  ElementWiseUnaryOp::Process(n, data, mask);
675  parallel_for(blocked_range<int>(0, n), *this);
676  }
677 };
678 
679 // -----------------------------------------------------------------------------
680 /// Mask values
681 class Mask : public ElementWiseBinaryOp
682 {
683 public:
684 
685  /// Constructor
686  Mask(double value) : ElementWiseBinaryOp(value) {}
687 
688  /// Constructor
689  Mask(const double *value) : ElementWiseBinaryOp(value) {}
690 
691  /// Constructor
692  Mask(const char *fname) : ElementWiseBinaryOp(fname) {}
693 
694  /// Constructor
695  Mask(const char *fname, double value) : ElementWiseBinaryOp(fname, value) {}
696 
697  /// Transform data value and/or mask data value by setting *mask = false
698  virtual double Op(double value, double constant, bool &mask) const
699  {
700  const double v = (_FileName.empty() ? value : _Constant);
701  if (fequal(v, constant) || (IsNaN(v) && IsNaN(constant))) {
702  mask = false;
703  }
704  return value;
705  }
706 
707  /// Process given data (not thread-safe!)
708  virtual void Process(int n, double *data, bool *mask = NULL)
709  {
710  Initialize(n, data, mask);
711  parallel_for(blocked_range<int>(0, n), *this);
712  Finalize();
713  }
714 };
715 
716 // -----------------------------------------------------------------------------
717 /// Mask values below or above a specified lower/upper threshold
719 {
720  /// Lower threshold value
721  mirtkPublicAttributeMacro(double, LowerThreshold);
722 
723  /// Address of lower threshold value storage
724  ///
725  /// This pointer can be set to the memory location of a double value that
726  /// will be set by a preceeding data statistic operation such as
727  /// data::statistic::Percentile. The result of this statistic calculation
728  /// thus becomes the input parameter of this data masking operation.
729  mirtkPublicAggregateMacro(const double, LowerThresholdPointer);
730 
731  /// Upper threshold value
732  mirtkPublicAttributeMacro(double, UpperThreshold);
733 
734  /// Address of upper threshold value storage
735  ///
736  /// This pointer can be set to the memory location of a double value that
737  /// will be set by a preceeding data statistic operation such as
738  /// data::statistic::Percentile. The result of this statistic calculation
739  /// thus becomes the input parameter of this data masking operation.
740  mirtkPublicAggregateMacro(const double, UpperThresholdPointer);
741 
742 public:
743 
744  /// Constructor
745  MaskOutsideInterval(double l, double u)
746  :
747  _LowerThreshold(l), _LowerThresholdPointer(nullptr),
748  _UpperThreshold(u), _UpperThresholdPointer(nullptr)
749  {}
750 
751  /// Constructor
752  MaskOutsideInterval(const double *l, const double *u)
753  :
754  _LowerThreshold(.0), _LowerThresholdPointer(l),
755  _UpperThreshold(.0), _UpperThresholdPointer(u)
756  {}
757 
758  /// Constructor
759  MaskOutsideInterval(double l, const double *u)
760  :
761  _LowerThreshold(l ), _LowerThresholdPointer(nullptr),
762  _UpperThreshold(.0), _UpperThresholdPointer(u)
763  {}
764 
765  /// Constructor
766  MaskOutsideInterval(const double *l, double u)
767  :
768  _LowerThreshold(.0), _LowerThresholdPointer(l),
769  _UpperThreshold(u ), _UpperThresholdPointer(nullptr)
770  {}
771 
772  /// Transform data value and/or mask data value by setting *mask = false
773  virtual double Op(double value, bool &mask) const
774  {
775  if (_LowerThreshold > _UpperThreshold) {
776  if (_UpperThreshold < value && value < _LowerThreshold) mask = false;
777  } else {
778  if (value < _LowerThreshold || value > _UpperThreshold) mask = false;
779  }
780  return value;
781  }
782 
783  /// Process given data (not thread-safe!)
784  virtual void Process(int n, double *data, bool *mask = NULL)
785  {
786  if (_LowerThresholdPointer) _LowerThreshold = *_LowerThresholdPointer;
787  if (_UpperThresholdPointer) _UpperThreshold = *_UpperThresholdPointer;
788  ElementWiseUnaryOp::Process(n, data, mask);
789  parallel_for(blocked_range<int>(0, n), *this);
790  }
791 };
792 
793 // -----------------------------------------------------------------------------
794 /// Mask values below, equal, or above a specified lower/upper threshold
796 {
797  /// Lower threshold value
798  mirtkPublicAttributeMacro(double, LowerThreshold);
799 
800  /// Address of lower threshold value storage
801  ///
802  /// This pointer can be set to the memory location of a double value that
803  /// will be set by a preceeding data statistic operation such as
804  /// data::statistic::Percentile. The result of this statistic calculation
805  /// thus becomes the input parameter of this data masking operation.
806  mirtkPublicAggregateMacro(const double, LowerThresholdPointer);
807 
808  /// Upper threshold value
809  mirtkPublicAttributeMacro(double, UpperThreshold);
810 
811  /// Address of upper threshold value storage
812  ///
813  /// This pointer can be set to the memory location of a double value that
814  /// will be set by a preceeding data statistic operation such as
815  /// data::statistic::Percentile. The result of this statistic calculation
816  /// thus becomes the input parameter of this data masking operation.
817  mirtkPublicAggregateMacro(const double, UpperThresholdPointer);
818 
819 public:
820 
821  /// Constructor
822  MaskOutsideOpenInterval(double l, double u)
823  :
824  _LowerThreshold(l), _LowerThresholdPointer(nullptr),
825  _UpperThreshold(u), _UpperThresholdPointer(nullptr)
826  {}
827 
828  /// Constructor
829  MaskOutsideOpenInterval(const double *l, const double *u)
830  :
831  _LowerThreshold(.0), _LowerThresholdPointer(l),
832  _UpperThreshold(.0), _UpperThresholdPointer(u)
833  {}
834 
835  /// Constructor
836  MaskOutsideOpenInterval(double l, const double *u)
837  :
838  _LowerThreshold(l ), _LowerThresholdPointer(nullptr),
839  _UpperThreshold(.0), _UpperThresholdPointer(u)
840  {}
841 
842  /// Constructor
843  MaskOutsideOpenInterval(const double *l, double u)
844  :
845  _LowerThreshold(.0), _LowerThresholdPointer(l),
846  _UpperThreshold(u ), _UpperThresholdPointer(nullptr)
847  {}
848 
849  /// Transform data value and/or mask data value by setting *mask = false
850  virtual double Op(double value, bool &mask) const
851  {
852  if (_LowerThreshold > _UpperThreshold) {
853  if (_UpperThreshold <= value && value <= _LowerThreshold) mask = false;
854  } else {
855  if (value <= _LowerThreshold || value >= _UpperThreshold) mask = false;
856  }
857  return value;
858  }
859 
860  /// Process given data (not thread-safe!)
861  virtual void Process(int n, double *data, bool *mask = NULL)
862  {
863  if (_LowerThresholdPointer) _LowerThreshold = *_LowerThresholdPointer;
864  if (_UpperThresholdPointer) _UpperThreshold = *_UpperThresholdPointer;
865  ElementWiseUnaryOp::Process(n, data, mask);
866  parallel_for(blocked_range<int>(0, n), *this);
867  }
868 };
869 
870 // -----------------------------------------------------------------------------
871 /// Mask values inside closed interval
873 {
874  /// Lower threshold value
875  mirtkPublicAttributeMacro(double, LowerThreshold);
876 
877  /// Address of lower threshold value storage
878  ///
879  /// This pointer can be set to the memory location of a double value that
880  /// will be set by a preceeding data statistic operation such as
881  /// data::statistic::Percentile. The result of this statistic calculation
882  /// thus becomes the input parameter of this data masking operation.
883  mirtkPublicAggregateMacro(const double, LowerThresholdPointer);
884 
885  /// Upper threshold value
886  mirtkPublicAttributeMacro(double, UpperThreshold);
887 
888  /// Address of upper threshold value storage
889  ///
890  /// This pointer can be set to the memory location of a double value that
891  /// will be set by a preceeding data statistic operation such as
892  /// data::statistic::Percentile. The result of this statistic calculation
893  /// thus becomes the input parameter of this data masking operation.
894  mirtkPublicAggregateMacro(const double, UpperThresholdPointer);
895 
896 public:
897 
898  /// Constructor
899  MaskInsideInterval(double l, double u)
900  :
901  _LowerThreshold(l), _LowerThresholdPointer(nullptr),
902  _UpperThreshold(u), _UpperThresholdPointer(nullptr)
903  {}
904 
905  /// Constructor
906  MaskInsideInterval(const double *l, const double *u)
907  :
908  _LowerThreshold(.0), _LowerThresholdPointer(l),
909  _UpperThreshold(.0), _UpperThresholdPointer(u)
910  {}
911 
912  /// Constructor
913  MaskInsideInterval(double l, const double *u)
914  :
915  _LowerThreshold(l ), _LowerThresholdPointer(nullptr),
916  _UpperThreshold(.0), _UpperThresholdPointer(u)
917  {}
918 
919  /// Constructor
920  MaskInsideInterval(const double *l, double u)
921  :
922  _LowerThreshold(.0), _LowerThresholdPointer(l),
923  _UpperThreshold(u ), _UpperThresholdPointer(nullptr)
924  {}
925 
926  /// Transform data value and/or mask data value by setting *mask = false
927  virtual double Op(double value, bool &mask) const
928  {
929  if (_LowerThreshold > _UpperThreshold) {
930  if (value <= _UpperThreshold || value >= _LowerThreshold) mask = false;
931  } else {
932  if (_LowerThreshold <= value && value <= _UpperThreshold) mask = false;
933  }
934  return value;
935  }
936 
937  /// Process given data (not thread-safe!)
938  virtual void Process(int n, double *data, bool *mask = NULL)
939  {
940  if (_LowerThresholdPointer) _LowerThreshold = *_LowerThresholdPointer;
941  if (_UpperThresholdPointer) _UpperThreshold = *_UpperThresholdPointer;
942  ElementWiseUnaryOp::Process(n, data, mask);
943  parallel_for(blocked_range<int>(0, n), *this);
944  }
945 };
946 
947 // -----------------------------------------------------------------------------
948 /// Mask values inside open interval
950 {
951  /// Lower threshold value
952  mirtkPublicAttributeMacro(double, LowerThreshold);
953 
954  /// Address of lower threshold value storage
955  ///
956  /// This pointer can be set to the memory location of a double value that
957  /// will be set by a preceeding data statistic operation such as
958  /// data::statistic::Percentile. The result of this statistic calculation
959  /// thus becomes the input parameter of this data masking operation.
960  mirtkPublicAggregateMacro(const double, LowerThresholdPointer);
961 
962  /// Upper threshold value
963  mirtkPublicAttributeMacro(double, UpperThreshold);
964 
965  /// Address of upper threshold value storage
966  ///
967  /// This pointer can be set to the memory location of a double value that
968  /// will be set by a preceeding data statistic operation such as
969  /// data::statistic::Percentile. The result of this statistic calculation
970  /// thus becomes the input parameter of this data masking operation.
971  mirtkPublicAggregateMacro(const double, UpperThresholdPointer);
972 
973 public:
974 
975  /// Constructor
976  MaskInsideOpenInterval(double l, double u)
977  :
978  _LowerThreshold(l), _LowerThresholdPointer(nullptr),
979  _UpperThreshold(u), _UpperThresholdPointer(nullptr)
980  {}
981 
982  /// Constructor
983  MaskInsideOpenInterval(const double *l, const double *u)
984  :
985  _LowerThreshold(.0), _LowerThresholdPointer(l),
986  _UpperThreshold(.0), _UpperThresholdPointer(u)
987  {}
988 
989  /// Constructor
990  MaskInsideOpenInterval(double l, const double *u)
991  :
992  _LowerThreshold(l ), _LowerThresholdPointer(nullptr),
993  _UpperThreshold(.0), _UpperThresholdPointer(u)
994  {}
995 
996  /// Constructor
997  MaskInsideOpenInterval(const double *l, double u)
998  :
999  _LowerThreshold(.0), _LowerThresholdPointer(l),
1000  _UpperThreshold(u ), _UpperThresholdPointer(nullptr)
1001  {}
1002 
1003  /// Transform data value and/or mask data value by setting *mask = false
1004  virtual double Op(double value, bool &mask) const
1005  {
1006  if (_LowerThreshold > _UpperThreshold) {
1007  if (value < _UpperThreshold || value > _LowerThreshold) mask = false;
1008  } else {
1009  if (_LowerThreshold < value && value < _UpperThreshold) mask = false;
1010  }
1011  return value;
1012  }
1013 
1014  /// Process given data (not thread-safe!)
1015  virtual void Process(int n, double *data, bool *mask = NULL)
1016  {
1017  if (_LowerThresholdPointer) _LowerThreshold = *_LowerThresholdPointer;
1018  if (_UpperThresholdPointer) _UpperThreshold = *_UpperThresholdPointer;
1019  ElementWiseUnaryOp::Process(n, data, mask);
1020  parallel_for(blocked_range<int>(0, n), *this);
1021  }
1022 };
1023 
1024 // -----------------------------------------------------------------------------
1025 /// Mask even values (e.g., segmentation labels of right hemisphere; cf MAL 2012)
1027 {
1028 public:
1029 
1030  /// Transform data value and/or mask data value by setting *mask = false
1031  virtual double Op(double value, bool &mask) const
1032  {
1033  if (static_cast<int>(value) % 2 == 0) mask = false;
1034  return value;
1035  }
1036 
1037  /// Process given data (not thread-safe!)
1038  virtual void Process(int n, double *data, bool *mask = NULL)
1039  {
1040  ElementWiseUnaryOp::Process(n, data, mask);
1041  parallel_for(blocked_range<int>(0, n), *this);
1042  }
1043 };
1044 
1045 // -----------------------------------------------------------------------------
1046 /// Mask odd values (e.g., segmentation labels of left hemisphere; cf MAL 2012)
1048 {
1049 public:
1050 
1051  /// Transform data value and/or mask data value by setting *mask = false
1052  virtual double Op(double value, bool &mask) const
1053  {
1054  if (static_cast<int>(value) % 2 == 1) mask = false;
1055  return value;
1056  }
1057 
1058  /// Process given data (not thread-safe!)
1059  virtual void Process(int n, double *data, bool *mask = NULL)
1060  {
1061  ElementWiseUnaryOp::Process(n, data, mask);
1062  parallel_for(blocked_range<int>(0, n), *this);
1063  }
1064 };
1065 
1066 // -----------------------------------------------------------------------------
1067 /// Clamp values below or equal a given threshold value
1069 {
1070  /// Lower threshold value
1071  mirtkPublicAttributeMacro(double, Threshold);
1072 
1073  /// Address of lower threshold value storage
1074  ///
1075  /// This pointer can be set to the memory location of a double value that
1076  /// will be set by a preceeding data statistic operation such as
1077  /// data::statistic::Percentile. The result of this statistic calculation
1078  /// thus becomes the input parameter of this data masking operation.
1079  mirtkPublicAggregateMacro(const double, ThresholdPointer);
1080 
1081 public:
1082 
1083  /// Constructor
1084  LowerThreshold(double value)
1085  :
1086  _Threshold(value), _ThresholdPointer(nullptr)
1087  {}
1088 
1089  /// Constructor
1090  LowerThreshold(const double *value)
1091  :
1092  _Threshold(.0), _ThresholdPointer(value)
1093  {}
1094 
1095  /// Transform data value and/or mask data value by setting *mask = false
1096  virtual double Op(double value, bool &) const
1097  {
1098  if (value <= _Threshold) value = _Threshold;
1099  return value;
1100  }
1101 
1102  /// Process given data (not thread-safe!)
1103  virtual void Process(int n, double *data, bool *mask = NULL)
1104  {
1105  if (_ThresholdPointer) _Threshold = *_ThresholdPointer;
1106  ElementWiseUnaryOp::Process(n, data, mask);
1107  parallel_for(blocked_range<int>(0, n), *this);
1108  }
1109 };
1110 
1111 // -----------------------------------------------------------------------------
1112 /// Clamp values below or equal a given threshold value
1114 {
1115  /// Upper threshold value
1116  mirtkPublicAttributeMacro(double, Threshold);
1117 
1118  /// Address of upper threshold value storage
1119  ///
1120  /// This pointer can be set to the memory location of a double value that
1121  /// will be set by a preceeding data statistic operation such as
1122  /// data::statistic::Percentile. The result of this statistic calculation
1123  /// thus becomes the input parameter of this data masking operation.
1124  mirtkPublicAggregateMacro(const double, ThresholdPointer);
1125 
1126 public:
1127 
1128  /// Constructor
1129  UpperThreshold(double value)
1130  :
1131  _Threshold(value), _ThresholdPointer(nullptr)
1132  {}
1133 
1134  /// Constructor
1135  UpperThreshold(const double *value)
1136  :
1137  _Threshold(.0), _ThresholdPointer(value)
1138  {}
1139 
1140  /// Transform data value and/or mask data value by setting *mask = false
1141  virtual double Op(double value, bool &) const
1142  {
1143  if (value >= _Threshold) value = _Threshold;
1144  return value;
1145  }
1146 
1147  /// Process given data (not thread-safe!)
1148  virtual void Process(int n, double *data, bool *mask = NULL)
1149  {
1150  if (_ThresholdPointer) _Threshold = *_ThresholdPointer;
1151  ElementWiseUnaryOp::Process(n, data, mask);
1152  parallel_for(blocked_range<int>(0, n), *this);
1153  }
1154 };
1155 
1156 // -----------------------------------------------------------------------------
1157 /// Clamp values below or equal a given threshold value
1159 {
1160  /// Lower threshold value
1161  mirtkPublicAttributeMacro(double, LowerThreshold);
1162 
1163  /// Address of lower threshold value storage
1164  ///
1165  /// This pointer can be set to the memory location of a double value that
1166  /// will be set by a preceeding data statistic operation such as
1167  /// data::statistic::Percentile. The result of this statistic calculation
1168  /// thus becomes the input parameter of this data masking operation.
1169  mirtkPublicAggregateMacro(const double, LowerThresholdPointer);
1170 
1171  /// Upper threshold value
1172  mirtkPublicAttributeMacro(double, UpperThreshold);
1173 
1174  /// Address of upper threshold value storage
1175  ///
1176  /// This pointer can be set to the memory location of a double value that
1177  /// will be set by a preceeding data statistic operation such as
1178  /// data::statistic::Percentile. The result of this statistic calculation
1179  /// thus becomes the input parameter of this data masking operation.
1180  mirtkPublicAggregateMacro(const double, UpperThresholdPointer);
1181 
1182 public:
1183 
1184  /// Constructor
1185  Clamp(double l, double u)
1186  :
1187  _LowerThreshold(l), _LowerThresholdPointer(nullptr),
1188  _UpperThreshold(u), _UpperThresholdPointer(nullptr)
1189  {}
1190 
1191  /// Constructor
1192  Clamp(const double *l, const double *u)
1193  :
1194  _LowerThreshold(.0), _LowerThresholdPointer(l),
1195  _UpperThreshold(.0), _UpperThresholdPointer(u)
1196  {}
1197 
1198  /// Constructor
1199  Clamp(double l, const double *u)
1200  :
1201  _LowerThreshold(l ), _LowerThresholdPointer(nullptr),
1202  _UpperThreshold(.0), _UpperThresholdPointer(u)
1203  {}
1204 
1205  /// Constructor
1206  Clamp(const double *l, double u)
1207  :
1208  _LowerThreshold(.0), _LowerThresholdPointer(l),
1209  _UpperThreshold(u ), _UpperThresholdPointer(nullptr)
1210  {}
1211 
1212  /// Transform data value and/or mask data value by setting *mask = false
1213  virtual double Op(double value, bool &) const
1214  {
1215  if (value <= _LowerThreshold) value = _LowerThreshold;
1216  else if (value >= _UpperThreshold) value = _UpperThreshold;
1217  return value;
1218  }
1219 
1220  /// Process given data (not thread-safe!)
1221  virtual void Process(int n, double *data, bool *mask = NULL)
1222  {
1223  if (_LowerThresholdPointer) _LowerThreshold = *_LowerThresholdPointer;
1224  if (_UpperThresholdPointer) _UpperThreshold = *_UpperThresholdPointer;
1225  ElementWiseUnaryOp::Process(n, data, mask);
1226  parallel_for(blocked_range<int>(0, n), *this);
1227  }
1228 };
1229 
1230 // -----------------------------------------------------------------------------
1231 /// Set values to either one or zero
1233 {
1234  /// Lower threshold value
1235  mirtkPublicAttributeMacro(double, LowerThreshold);
1236 
1237  /// Upper threshold value
1238  mirtkPublicAttributeMacro(double, UpperThreshold);
1239 
1240 public:
1241 
1242  /// Constructor
1243  Binarize(double l, double u = numeric_limits<double>::infinity())
1244  :
1245  _LowerThreshold(l), _UpperThreshold(u)
1246  {}
1247 
1248  /// Transform data value and/or mask data value by setting *mask = false
1249  virtual double Op(double value, bool &) const
1250  {
1251  if (_LowerThreshold > _UpperThreshold) {
1252  if (_UpperThreshold <= value && value <= _LowerThreshold) {
1253  return 0.0;
1254  } else {
1255  return 1.0;
1256  }
1257  } else {
1258  if (_LowerThreshold <= value && value <= _UpperThreshold) {
1259  return 1.0;
1260  } else {
1261  return 0.0;
1262  }
1263  }
1264  }
1265 
1266  /// Process given data (not thread-safe!)
1267  virtual void Process(int n, double *data, bool *mask = NULL)
1268  {
1269  ElementWiseUnaryOp::Process(n, data, mask);
1270  parallel_for(blocked_range<int>(0, n), *this);
1271  }
1272 };
1273 
1274 // -----------------------------------------------------------------------------
1275 /// Rescale values to new range
1276 class Rescale : public Op
1277 {
1278 private:
1279 
1280  double *_Data;
1281  bool *_Mask;
1282  double _Min;
1283  double _Max;
1284  double _Slope;
1285  double _Intercept;
1286 
1287 public:
1288 
1289  Rescale(double min = .0, double max = 1.0) : _Min(min), _Max(max) {}
1290 
1291  // Called by TBB's parallel_for, for internal use only!
1292  void operator()(const blocked_range<int> &re) const
1293  {
1294  double *data = _Data + re.begin();
1295  for (int i = re.begin(); i != re.end(); ++i, ++data) {
1296  *data = (*data * _Slope) + _Intercept;
1297  }
1298  }
1299 
1300  /// Process given data (not thread-safe!)
1301  virtual void Process(int n, double *data, bool *mask = NULL)
1302  {
1303  statistic::Extrema extrema;
1304  extrema.Process(n, data, mask);
1305  _Slope = (_Max - _Min) / (extrema.Max() - extrema.Min());
1306  _Intercept = _Min - (extrema.Min() * _Slope);
1307  _Data = data;
1308  _Mask = mask;
1309  parallel_for(blocked_range<int>(0, n), *this);
1310  }
1311 };
1312 
1313 
1314 } } } // namespace mirtk::data::op
1315 
1316 #endif // MIRTK_DataFunctions_H
int Read(const char *name, UniquePtr< double[]> &data, int *dtype=nullptr, ImageAttributes *attr=nullptr, void *=nullptr, const char *scalars_name=nullptr, bool cell_data=false)
Read data sequence from any supported input file type.
Get minimum and maximum values.
void Finalize()
Finalize processing and release temporary memory.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
LowerThreshold(const double *value)
Constructor.
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
virtual double Op(double value, double constant, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
Set value of masked data points.
Clamp values below or equal a given threshold value.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Mul(const char *fname)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
Compute element-wise power.
Mask(double value)
Constructor.
virtual double Op(double value, double constant, bool &) const
Transform data value and/or mask data value by setting *mask = false.
Element-wise subtraction.
MaskOutsideOpenInterval(const double *l, const double *u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Map values (e.g. segmentation labels)
MaskOutsideInterval(const double *l, double u)
Constructor.
string FileName(const char *, ExtensionMode=EXT_Default)
Get file name of file path excl. file extension.
Base class of all data operations.
Definition: DataOp.h:61
MaskInsideOpenInterval(double l, const double *u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
MaskOutsideOpenInterval(double l, const double *u)
Constructor.
Set value of unmasked data points.
Definition: DataFunctions.h:71
Defines base class and I/O functions for arbitrary 1D data sequences.
Mask odd values (e.g., segmentation labels of left hemisphere; cf MAL 2012)
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Mul(const double *value)
Constructor.
MaskInsideInterval(const double *l, const double *u)
Constructor.
Mask values below, equal, or above a specified lower/upper threshold.
ElementWiseBinaryOp(const char *fname)
Constructor.
Clamp(const double *l, double u)
Constructor.
virtual double Op(double value, double constant, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
DivWithZero(const char *fname)
Constructor.
MIRTKCU_API bool IsNaN(double x)
Check if floating point value is not a number (NaN)
Definition: Math.h:91
void Initialize(int n, double *data, bool *mask=nullptr)
Initialize processing and read data from file.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
MaskOutsideOpenInterval(double l, double u)
Constructor.
ElementWiseBinaryOp(const char *fname, const char *aname, bool cell_data=false)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Sub(const double *value)
Constructor.
Compute element-wise logarithm to base 10.
UpperThreshold(double value)
Constructor.
MaskInsideOpenInterval(const double *l, const double *u)
Constructor.
One-dimensional range.
Definition: Parallel.h:155
Compute element-wise exponential map.
Mul(double value)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
MaskInsideOpenInterval(double l, double u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
ElementWiseBinaryOp(double value)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
ElementWiseBinaryOp(const char *fname, double value)
Constructor.
Invert mask values.
Definition: DataFunctions.h:54
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
Compute element-wise absolute value.
Element-wise division.
MaskOutsideInterval(const double *l, const double *u)
Constructor.
MIRTKCU_API bool fequal(double a, double b, double tol=1e-12)
Definition: Math.h:138
UpperThreshold(const double *value)
Constructor.
Div(double value)
Constructor.
Mask values below or above a specified lower/upper threshold.
Add(double value)
Constructor.
MaskOutsideOpenInterval(const double *l, double u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual void Process(int n, double *data, bool *mask=nullptr)
Process given data.
Definition: IOConfig.h:41
Compute element-wise natural logarithm.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
ElementWiseBinaryOp(const double *value)
Constructor.
Set values to either one or zero.
DivWithZero(const double *value)
Constructor.
Clamp(double l, double u)
Constructor.
Mask(const char *fname)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
Mask even values (e.g., segmentation labels of right hemisphere; cf MAL 2012)
Element-wise addition.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual void Process(int n, double *, bool *mask=nullptr)
Process given data (not thread-safe!)
Definition: DataFunctions.h:59
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
Element-wise division.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Clamp values below or equal a given threshold value.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
Sub(const char *fname)
Constructor.
virtual double Op(double value, bool &mask) const
Transform data value and/or mask data value by setting *mask = false.
MaskOutsideInterval(double l, double u)
Constructor.
Mask(const char *fname, double value)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual double Op(double value, double constant, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
MaskInsideInterval(double l, const double *u)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask it by setting mask = false.
Div(const char *fname)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
Sub(double value)
Constructor.
Binarize(double l, double u=numeric_limits< double >::infinity())
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Compute element-wise logarithmic map.
ElementWiseBinaryOp(const char *fname, const double *value)
Constructor.
ElementWiseBinaryOp(const char *fname, const char *aname, const double *value, bool cell_data=false)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Add(const char *fname)
Constructor.
ElementWiseBinaryOp(const char *fname, const char *aname, double value, bool cell_data=false)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
MaskOutsideInterval(double l, const double *u)
Constructor.
Compute element-wise binary logarithm.
virtual double Op(double value, double constant, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Add(const double *value)
Constructor.
MaskInsideOpenInterval(const double *l, double u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
DivWithZero(double value)
Constructor.
virtual double Op(double value, bool &) const
Transform data value and/or mask data value by setting *mask = false.
void Insert(double a, double b)
Insert map from a to b.
MaskInsideInterval(double l, double u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)
Clamp values below or equal a given threshold value.
Mask values inside open interval.
virtual void Process(int n, double *, bool *mask=nullptr)
Process given data (not thread-safe!)
Definition: DataFunctions.h:44
Mask values inside closed interval.
MaskInsideInterval(const double *l, double u)
Constructor.
Mask(const double *value)
Constructor.
virtual double Op(double value, double constant, bool &) const
Transform data value and/or mask data value by setting *mask = false.
LowerThreshold(double value)
Constructor.
Base class of element-wise data transformations.
Element-wise multiplication.
Base class of element-wise data transformations.
Div(const double *value)
Constructor.
void parallel_for(const Range &range, const Body &body)
parallel_for dummy template function which executes the body serially
Definition: Parallel.h:232
Clamp(double l, const double *u)
Constructor.
Rescale values to new range.
Clamp(const double *l, const double *u)
Constructor.
virtual void Process(int n, double *data, bool *mask=NULL)
Process given data (not thread-safe!)