RobustEstimateZapper.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2020 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // psrchive/Util/genutil/RobustEstimateZapper.h
10 
11 #ifndef __RobustEstimateZapper_h
12 #define __RobustEstimateZapper_h
13 
14 // #define _DEBUG 1
15 
16 #include "TextInterface.h"
17 #include "Estimate.h"
18 
19 #include <algorithm>
20 
23 {
24 private:
25  bool error;
26  bool logarithmic;
27  bool scale;
28  float threshold_min;
29  float threshold_max;
30 
31 public:
32 
34 
36  bool get_error_bar () const { return error; }
37  void set_error_bar (bool flag) { error = flag; }
38 
40  bool get_log () const { return logarithmic; }
41  void set_log (bool flag) { logarithmic = flag; }
42 
44  bool get_scale () const { return scale; }
45  void set_scale (bool flag) { scale = flag; }
46 
48  float get_cutoff_threshold () const { return threshold_max; }
49  void set_cutoff_threshold (float val) { threshold_max = threshold_min = val; }
50 
52  float get_cutoff_threshold_min () const { return threshold_min; }
53  void set_cutoff_threshold_min (float val) { threshold_min = val; }
54 
56  float get_cutoff_threshold_max () const { return threshold_max; }
57  void set_cutoff_threshold_max (float val) { threshold_max = val; }
58 
61 
62  class Interface;
63 
64  float get_value (const Estimate<float>& datum)
65  {
66  float val;
67 
68  if (error)
69  val = sqrt(datum.var);
70  else
71  val = datum.val;
72 
73  if (logarithmic)
74  val = log10 (val);
75 
76  return val;
77  }
78 
79  template<class Container, class Size, class Get, class Valid>
80  void excise (unsigned iparam, Container* container, Size size, Get get, Valid valid)
81  {
82  unsigned npt = (container->*size)();
83 
84 #if _DEBUG
85  std::cerr << "RobustEstimateZapper::excise iparam=" << iparam << " npt=" << npt << std::endl;
86 #endif
87 
88  std::vector<float> work (npt);
89  unsigned iwork = 0;
90 
91  for (unsigned ipt=0; ipt<npt; ipt++)
92  {
93  Estimate<float> val = (container->*get)(iparam, ipt);
94  if (val.var == 0.0)
95  continue;
96 
97  work[iwork] = get_value (val);
98 
99 #if _DEBUG
100  std::cout << iparam << " " << ipt << " " << work[iwork] << std::endl;
101 #endif
102 
103  iwork ++;
104  }
105 
106  // find the median value
107  std::nth_element (work.begin(), work.begin()+iwork/2, work.begin()+iwork);
108  float median = work[ iwork/2 ];
109 
110  float madm = 1.0;
111 
112  if (scale)
113  {
114  // compute the absolute deviation from the median
115  for (unsigned ipt=0; ipt < iwork; ipt++)
116  work[ipt] = fabs(work[ipt] - median);
117 
118  // find the median absolute deviation from the median
119  std::nth_element (work.begin(), work.begin()+iwork/2, work.begin()+iwork);
120  madm = work[ iwork/2 ];
121  }
122 
123 #if _DEBUG
124  std::cerr << "RobustEstimateZapper::excise iwork=" << iwork
125  << " iparam=" << iparam << " median=" << median
126  << " madm=" << madm << std::endl;
127 #endif
128 
129  unsigned excised = 0;
130 
131  double max_extreme = median + threshold_max * madm;
132  double min_extreme = median - threshold_min * madm;
133 
134  for (unsigned ipt=0; ipt<npt; ipt++)
135  {
136  Estimate<float> val = (container->*get)(iparam, ipt);
137  if (val.var == 0.0)
138  continue;
139 
140  double test = get_value(val);
141 
142  if (threshold_max && test > max_extreme)
143  {
144 #if _DEBUG
145  std::cerr << "RobustEstimateZapper::excise zapping >max iparam=" << iparam
146  << " ipt=" << ipt << std::endl;
147 #endif
148 
149  excised ++;
150  (container->*valid)(ipt, false);
151  }
152 
153  if (threshold_min && test < min_extreme)
154  {
155 #if _DEBUG
156  std::cerr << "RobustEstimateZapper::excise zapping <min iparam=" << iparam
157  << " ipt=" << ipt << std::endl;
158 #endif
159 
160  excised ++;
161  (container->*valid)(ipt, false);
162  }
163 
164  }
165 
166 #if _DEBUG
167  std::cerr << "RobustEstimateZapper::excise excised=" << excised << std::endl;
168 #endif
169 
170  }
171 };
172 
173 #endif
bool get_log() const
Flag outliers based on the logarithm of either the value or the error bar.
Definition: RobustEstimateZapper.h:45
float get_cutoff_threshold_max() const
Set threshold used to identify outliers (multiple of madm)
Definition: RobustEstimateZapper.h:61
float get_cutoff_threshold_min() const
Set threshold used to identify outliers (multiple of madm)
Definition: RobustEstimateZapper.h:57
An array of Value interfaces.
Definition: TextInterfaceParser.h:35
T val
The value, .
Definition: Estimate.h:42
U var
The variance of the value, .
Definition: Estimate.h:44
bool get_scale() const
Do not multiply threshold by MADM.
Definition: RobustEstimateZapper.h:49
Manages Reference::To references to the instance.
Definition: ReferenceAble.h:40
float get_cutoff_threshold() const
Set threshold used to identify outliers (multiple of madm)
Definition: RobustEstimateZapper.h:53
Excises outliers from a container using robust statistics.
Definition: RobustEstimateZapper.h:22
bool get_error_bar() const
Flag outliers based on their error bar.
Definition: RobustEstimateZapper.h:41
TextInterface::Parser * get_interface()
Return a text interface that can be used to access this instance.
Definition: RobustEstimateZapper.C:38
Class text interface: an instance of C and a vector of Attribute<C>
Definition: TextInterfaceTo.h:30

Generated using doxygen 1.8.17