Diagnostics.cxx
Go to the documentation of this file.
2 
3 #include <cmath>
4 #include <complex>
5 //#include <iostream>
6 
7 using namespace WireCell::SigProc;
8 
9 
10 
11 Diagnostics::Partial::Partial(int nfreqs, double maxpower)
12  : nfreqs(nfreqs)
13  , maxpower(maxpower)
14 {
15 }
16 
18 {
19  const double mag0 = std::abs(spec[0+1]);
20  double sum = mag0;
21  for (int ind=1; ind<= nfreqs && ind < (int)spec.size(); ++ind) {
22  const double magi = std::abs(spec[ind+1]);
23  if (mag0 <= magi) {
24  return false;
25  }
26  sum += magi;
27  }
28  // if (sum/(nfreqs+1) > maxpower){
29  // std::cout << mag0 << " " << std::abs(spec[2]) << " " << std::abs(spec[3]) << " " << std::abs(spec[4]) << " " << std::abs(spec[5]) << std::endl;
30  // }
31 
32  return sum/(nfreqs+1) > maxpower;
33 }
34 
35 
36 Diagnostics::Chirp::Chirp(int windowSize, double chirpMinRMS, double maxNormalNeighborFrac)
37  : windowSize(windowSize)
38  , chirpMinRMS(chirpMinRMS)
39  , maxNormalNeighborFrac(maxNormalNeighborFrac)
40 {
41 }
42 
44 {
45  beg = end = -1;
46 
47  // this alg is from Mike Mooney
48 
49  // magic numbers moved into constructor
50  //const int windowSize = 20;
51  //const double chirpMinRMS = 0.9;
52  //const double maxNormalNeighborFrac = 0.20;
53 
54  int counter = 0;
55  double runningAmpMean = 0.0;
56  double runningAmpRMS = 0.0;
57  int numLowRMS = 0;
58  int firstLowRMSBin = -1; // computed below assuming
59  int lastLowRMSBin = -1; // 1-based arrays
60  bool lowRMSFlag = false;
61  double RMSfirst = 0.0;
62  double RMSsecond = 0.0;
63  double RMSthird = 0.0;
64  int numNormalNeighbors = 0;
65 
66  const int numBins = sig.size();
67 
68  for (int ibin = 0; ibin < numBins; ibin++) {
69 
70  double ADCval = sig[ibin];
71 
72  runningAmpMean += ADCval;
73  runningAmpRMS += ADCval*ADCval;
74 
75  counter++;
76  if(counter == windowSize) {
77 
78  runningAmpMean /= (double)windowSize;
79  runningAmpRMS /= (double)windowSize;
80  runningAmpRMS = std::sqrt(runningAmpRMS - runningAmpMean*runningAmpMean);
81 
82  RMSfirst = RMSsecond;
83  RMSsecond = RMSthird;
84  RMSthird = runningAmpRMS;
85 
86  if(runningAmpRMS < chirpMinRMS) {
87  numLowRMS++;
88  }
89 
90  if(ibin >= 3*windowSize-1) {
91  if((RMSsecond < chirpMinRMS) && ((RMSfirst > chirpMinRMS) || (RMSthird > chirpMinRMS))) {
92  numNormalNeighbors++;
93  }
94 
95  if(lowRMSFlag == false) {
96  if((RMSsecond < chirpMinRMS) && (RMSthird < chirpMinRMS)) {
97  lowRMSFlag = true;
98  firstLowRMSBin = ibin - 2*windowSize + 1;
99  lastLowRMSBin = ibin - windowSize + 1;
100  }
101 
102  if((ibin == 3*windowSize-1) && (RMSfirst < chirpMinRMS) && (RMSsecond < chirpMinRMS)) {
103  lowRMSFlag = true;
104  firstLowRMSBin = ibin - 3*windowSize + 1;
105  lastLowRMSBin = ibin - 2*windowSize + 1;
106  }
107  }
108  else {
109  if((RMSsecond < chirpMinRMS) && (RMSthird < chirpMinRMS)) {
110  lastLowRMSBin = ibin - windowSize + 1;
111  }
112  }
113  }
114 
115  counter = 0;
116  runningAmpMean = 0.0;
117  runningAmpRMS = 0.0;
118  }
119  }
120 
121  double chirpFrac = ((double) numLowRMS)/(((double) numBins)/((double) windowSize));
122  double normalNeighborFrac = ((double) numNormalNeighbors)/((double) numLowRMS);
123  if ( (numLowRMS > 4) &&
124  ((normalNeighborFrac < maxNormalNeighborFrac)
125  || ((numLowRMS < 2.0/maxNormalNeighborFrac)
126  && (lastLowRMSBin-firstLowRMSBin == numLowRMS*windowSize)))
127  ) {
128 
129  firstLowRMSBin = std::max(1, firstLowRMSBin - windowSize);
130  lastLowRMSBin = std::min(numBins, lastLowRMSBin + 2*windowSize);
131 
132  if((numBins-lastLowRMSBin) < windowSize) {
133  lastLowRMSBin = numBins;
134  }
135 
136  if(chirpFrac > 0.99) {
137  firstLowRMSBin = 1;
138  lastLowRMSBin = numBins;
139  }
140 
141  beg = firstLowRMSBin - 1;
142  end = lastLowRMSBin;
143  return true;
144  }
145  return false;
146 }
147 
148 // Local Variables:
149 // mode: c++
150 // c-basic-offset: 4
151 // End:
bool operator()(const WireCell::Waveform::compseq_t &spec) const
Return true if given frequency spectrum consistent with a partial waveform.
Definition: Diagnostics.cxx:17
Sequence< real_t > realseq_t
Definition: Waveform.h:31
bool operator()(const WireCell::Waveform::realseq_t &sig, int &beg, int &end) const
Definition: Diagnostics.cxx:43
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:72
T abs(T value)
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
static int max(int a, int b)
IFrame::pointer sum(std::vector< IFrame::pointer > frames, int ident)
Definition: FrameUtil.cxx:15
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Sequence< complex_t > compseq_t
A complex-valued sequence, eg for discrete spectrum powers.
Definition: Waveform.h:34
Partial(int nfreqs=4, double maxpower=6000.0)
Create a partial waveform detector using magic numbers.
Definition: Diagnostics.cxx:11
Chirp(int windowSize=20, double chirpMinRMS=0.9, double maxNormalNeighborFrac=0.20)
Create a chirp detector using magic numbers.
Definition: Diagnostics.cxx:36