AdcCodeMitigator_tool.cc
Go to the documentation of this file.
1 // AdcCodeMitigator_tool.cc
2 
3 #include "AdcCodeMitigator.h"
4 #include <iostream>
5 #include <sstream>
6 
7 using std::string;
8 using std::cout;
9 using std::endl;
10 using std::istringstream;
14 using NameVector = std::vector<Name>;
15 
16 //**********************************************************************
17 // Class methods.
18 //**********************************************************************
19 
21 : m_LogLevel(ps.get<int>("LogLevel")),
22  m_FixFlags(ps.get<IndexVector>("FixFlags")),
23  m_InterpolateFlags(ps.get<IndexVector>("InterpolateFlags")),
24  m_SkipFlags(ps.get<IndexVector>("SkipFlags")),
25  m_FixedCurvThresh(ps.get<double>("FixedCurvThresh")) {
26  const string myname = "AdcCodeMitigator::ctor: ";
27  // Display configuration.
28  if ( m_LogLevel ) {
29  cout << myname << "Configuration: " << endl;
30  cout << myname << " LogLevel: " << m_LogLevel << endl;
31  cout << myname << " FixFlags: [";
32  bool first = true;
33  for ( Index iflg : m_FixFlags ) {
34  if ( ! first ) cout << ", ";
35  cout << iflg;
36  }
37  cout << "]" << endl;
38  cout << myname << " InterpolateFlags: [";
39  first = true;
40  for ( Index iflg : m_InterpolateFlags ) {
41  if ( ! first ) cout << ", ";
42  else first = false;
43  cout << iflg;
44  }
45  cout << "]" << endl;
46  cout << myname << " SkipFlags: [";
47  first = true;
48  for ( Index iflg : m_SkipFlags ) {
49  if ( ! first ) cout << ", ";
50  else first = false;
51  cout << iflg;
52  }
53  cout << "]" << endl;
54  cout << myname << " FixedCurvThresh: " << m_FixedCurvThresh << endl;
55  }
56  for ( Index iflg : m_FixFlags ) m_fixSet.insert(iflg);
57  for ( Index iflg : m_InterpolateFlags ) {
58  m_interpolateSet.insert(iflg);
59  m_skipSet.insert(iflg);
60  }
61  for ( Index iflg : m_SkipFlags ) m_skipSet.insert(iflg);
62 }
63 
64 //**********************************************************************
65 
67  const string myname = "AdcCodeMitigator::view: ";
68  DataMap ret;
69  Index nsam = acd.samples.size();
70  if ( acd.flags.size() != acd.samples.size() ) {
71  cout << myname << "ERROR: Flag and sample sizes disagree: "
72  << acd.flags.size() << " != " << nsam << endl;
73  return ret.setStatus(1);
74  }
75  Index mitCount = 0;
76  // Fixed mitigation.
77  for ( Index isam=0; isam<nsam; ++isam ) {
78  AdcFlag iflg = acd.flags[isam];
79  if ( m_fixSet.find(iflg) == m_fixSet.end() ) continue;
80  ++mitCount;
81  acd.samples[isam] = 0.0;
82  acd.flags[isam] = AdcSetFixed;
83  }
84  // Interpolation mitigation.
85  // Ordering of samples: isamLo2 isamLo1 isam isamHi1 isamHi2
86  Index isamLo2 = 0; // Second sample used for low-side interpolation.
87  Index isamLo1 = 0; // Firstample used for low-side interpolation.
88  bool haveLo1 = false;
89  bool haveLo2 = false;
90  Index isamHi1 = 0; // Sample used for high-side interpolation.
91  Index isamHi2 = 0; // 2nd Sample used for high-side interpolation.
92  for ( Index isam=0; isam<nsam; ++isam ) {
93  AdcFlag iflg = acd.flags[isam];
94  // Record if this sample can be used for low-side interpolation.
95  if ( m_skipSet.find(iflg) == m_skipSet.end() ) {
96  isamLo2 = isamLo1;
97  isamLo1 = isam;
98  haveLo1 = true;
99  haveLo2 = isamLo1 != isamLo2;
100  continue;
101  }
102  // Skip sample if it is not to be interpolated.
103  if ( m_interpolateSet.find(iflg) == m_interpolateSet.end() ) continue;
104  // Check if we have a valid high-side sample.
105  bool haveHi1 = isamHi1 > isam && isamHi1 < nsam;
106  if ( ! haveHi1 && isamHi1 < nsam ) {
107  isamHi1 = isam;
108  while ( !haveHi1 && ++isamHi1 < nsam ) haveHi1 = m_skipSet.find(acd.flags[isamHi1]) == m_skipSet.end();
109  }
110  bool haveHi2 = false;
111  if ( haveHi1 ) {
112  haveHi2 = isamHi2 > isamHi1 && isamHi2 < nsam;
113  if ( ! haveHi2 ) {
114  isamHi2 = isamHi1;
115  while ( !haveHi2 && ++isamHi2 < nsam ) haveHi2 = m_skipSet.find(acd.flags[isamHi2]) == m_skipSet.end();
116  if ( ! haveHi2 ) isamHi2 = isamHi1;
117  }
118  }
119  if ( m_LogLevel >= 5 ) {
120  cout << myname << "Samples: " << isamLo2 << " " << isamLo1 << " | " << isam
121  << " | " << isamHi1 << " " << isamHi2 << endl;
122  }
123  double y = 0.0;
124  // If threshold is set and samples are available, consider doing interpolation with
125  // a varying slope but constant curvature.
126  bool done = false;
127  if ( m_FixedCurvThresh > 0.0 && haveLo1 && haveHi1 && ( haveLo2 || haveHi2 ) ) {
128  double ylo1 = acd.samples[isamLo1];
129  double ylo2 = acd.samples[isamLo2];
130  double yhi1 = acd.samples[isamHi1];
131  double yhi2 = acd.samples[isamHi2];
132  //int nBigJump = 0;
133  //if ( fabs(ylo2 - ylo1) > m_FixedCurvThresh ) ++nBigJump;
134  //if ( fabs(yhi2 - yhi1) > m_FixedCurvThresh ) ++nBigJump;
135  //if ( fabs(yhi1 - ylo1) > m_FixedCurvThresh ) ++nBigJump;
136  //bool doFixedCurvature = nBigJump > 1;
137  double adiflo = fabs(ylo2 - ylo1);
138  double adifhi = fabs(yhi2 - yhi1);
139  bool doFixedCurvature = adiflo > m_FixedCurvThresh ||
140  adifhi > m_FixedCurvThresh;
141  if ( m_LogLevel >= 5 ) {
142  cout << myname << "Lo, hi jumps for sample " << isam << ": " << adiflo << ", " << adifhi << endl;
143  }
144  if ( doFixedCurvature ) {
145  // j = isam - isamLo1
146  // k = isam - isamHi1
147  // y = a*(i-isamLo1) + b*(i-isamHi1) + c*(i-isamLo1)*(i-isamHi1)
148  // = a*j + b*k + c*j*k
149  // There are three parameters: a, b, c, and four measurements: ylo1, yhi1, ylo2, yhi2
150  // Require the curve pass through the interpolation endpoints ylo1 and yhi1:
151  // a = yhi1/(isamHi1 - isamLo1)
152  // b = ylo1/(isamLo1 - isamHi1)
153  // Fix the remaining param c so that
154  // wlo*[y(isamlo2) - ylo2] + whi*[y(isamhi2) - yhi2] = 0
155  // E.g. if w1 == w2, the curve is equally close to ylo2 and yhi2
156  int jlo2 = int(isamLo2) - int(isamLo1);
157  int jhi2 = int(isamHi2) - int(isamLo1);
158  int klo2 = int(isamLo2) - int(isamHi1);
159  int khi2 = int(isamHi2) - int(isamHi1);
160  double a = yhi1/(isamHi1 - isamLo1);
161  double b = -ylo1/(isamHi1 - isamLo1);
162  //int iden = jlo2*klo2 + jhi2*khi2;
163  //double wlo = 1.0;
164  //double whi = 1.0;
165  double w0 = acd.pedestalRms;
166  if ( w0 < 1.0 ) w0 = 1.0;
167  double wlo = adifhi + w0;
168  double whi = adiflo + w0;
169  double den = wlo*jlo2*klo2 + whi*jhi2*khi2;
170  if ( den != 0.0 ) {
171  //double num = ylo2 + yhi2 - a*(jlo2+jhi2) - b*(klo2+khi2);
172  //double c = num/double(iden);
173  double num = wlo*ylo2 + whi*yhi2 - a*(wlo*jlo2+whi*jhi2) - b*(wlo*klo2+whi*khi2);
174  double c = num/den;
175  if ( m_LogLevel >= 4 ) {
176  cout << myname << "Quadratic interpolation for sample " << isam << endl;
177  cout << myname << " isamLo2: " << isamLo2 << endl;
178  cout << myname << " isamLo1: " << isamLo1 << endl;
179  cout << myname << " isamHi1: " << isamHi1 << endl;
180  cout << myname << " isamHi2: " << isamHi2 << endl;
181  cout << myname << " ylo2: " << ylo2 << endl;
182  cout << myname << " ylo1: " << ylo1 << endl;
183  cout << myname << " yhi1: " << yhi1 << endl;
184  cout << myname << " yhi2: " << yhi2 << endl;
185  cout << myname << " a: " << a << endl;
186  cout << myname << " b: " << b << endl;
187  cout << myname << " c: " << c << endl;
188  }
189  int jsam = isam - isamLo1;
190  int ksam = isam - isamHi1;
191  y = a*jsam + b*ksam + c*jsam*ksam;
192  done = true;
193  } else {
194  if ( m_LogLevel >= 4 ) {
195  cout << myname << "Skipping quadratic interpolation for den=0 for sample " << isam << endl;
196  }
197  }
198  }
199  }
200  // Two point linear interpolation.
201  if ( done ) {
202  if ( m_LogLevel >= 3 ) cout << myname << "Quadratic interpolation: isam=" << isam
203  << ": [" << isamLo1 << "], [" << isamHi1 << "] ==> " << y << endl;
204  } else if ( haveLo1 && haveHi1 ) {
205  double ylo = acd.samples[isamLo1];
206  double yhi = acd.samples[isamHi1];
207  double x01 = isam - isamLo1;
208  double x12 = isamHi1 - isamLo1;
209  y = ylo + (yhi - ylo)*x01/x12;
210  iflg = AdcInterpolated;
211  if ( m_LogLevel >= 3 ) cout << myname << "Linear interpolating isam=" << isam
212  << ": [" << isamLo1 << "], [" << isamHi1 << "] ==> " << y << endl;
213  // One point lo extrapolation.
214  } else if ( haveLo1 ) {
215  y = acd.samples[isamLo1];
216  iflg = AdcExtrapolated;
217  if ( m_LogLevel >= 3 ) cout << myname << "Setting low extrapolation for isam=" << isam
218  << ": [" << isamLo1 << "] = " << y << endl;
219  // One point lo extrapolation.
220  } else if ( haveHi1 ) {
221  y = acd.samples[isamHi1];
222  iflg = AdcExtrapolated;
223  if ( m_LogLevel >= 3 ) cout << myname << "Setting high extrapolation for isam=" << isam
224  << ": [" << isamHi1 << "] = " << y << endl;
225  // Use fixed value.
226  } else {
227  iflg = AdcSetFixed;
228  }
229  acd.samples[isam] = y;
230  acd.flags[isam] = iflg;
231  ++mitCount;
232  }
233  ret.setInt("mitCount", mitCount);
234  return ret;
235 }
236 
237 //**********************************************************************
238 
std::vector< Index > IndexVector
std::vector< Index > IndexVector
IndexVector m_SkipFlags
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
short AdcFlag
Definition: AdcTypes.h:29
unsigned int Index
unsigned int Index
DataMap & setStatus(int stat)
Definition: DataMap.h:130
std::string string
Definition: nybbler.cc:12
ChannelGroupService::Name Name
unsigned int Index
const AdcFlag AdcSetFixed
Definition: AdcTypes.h:41
AdcSignal pedestalRms
AdcCodeMitigator(fhicl::ParameterSet const &ps)
const double a
IndexVector m_InterpolateFlags
void setInt(Name name, int val)
Definition: DataMap.h:131
const AdcFlag AdcExtrapolated
Definition: AdcTypes.h:43
IndexSet m_interpolateSet
static constexpr double ps
Definition: Units.h:99
IndexVector m_FixFlags
const AdcFlag AdcInterpolated
Definition: AdcTypes.h:42
std::vector< string > NameVector
static bool * b
Definition: config.cpp:1043
DataMap update(AdcChannelData &acds) const override
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
AdcSignalVector samples
QTextStream & endl(QTextStream &s)
AdcFlagVector flags