Microboone.cxx
Go to the documentation of this file.
1 /** FIXME: this file is full of magic numbers and likely totally not
2  * usable for detectors other than MicroBooNE.
3  */
4 
7 
9 
10 #include <cmath>
11 #include <complex>
12 #include <iostream>
13 #include <set>
14 
15 // Register the components defined here
16 WIRECELL_FACTORY(mbCoherentNoiseSub,
19 WIRECELL_FACTORY(mbOneChannelNoise,
20  WireCell::SigProc::Microboone::OneChannelNoise,
21  WireCell::IChannelFilter, WireCell::IConfigurable)
22 WIRECELL_FACTORY(mbOneChannelStatus,
23  WireCell::SigProc::Microboone::OneChannelStatus,
24  WireCell::IChannelFilter, WireCell::IConfigurable)
25 WIRECELL_FACTORY(mbADCBitShift,
26  WireCell::SigProc::Microboone::ADCBitShift,
27  WireCell::IChannelFilter, WireCell::IConfigurable)
28 
29 
30 
31 using namespace WireCell::SigProc;
32 
33 double filter_low(double freq, double cut_off = 0.08);
34 
35 double filter_time(double freq){
36  double a = 0.143555;
37  double b = 4.95096;
38  return (freq>0)*exp(-0.5*pow(freq/a,b));
39 }
40 
41 double filter_low(double freq, double cut_off){
42  if ( (freq>0.177 && freq<0.18) || (freq > 0.2143 && freq < 0.215) ||
43  (freq >=0.106 && freq<=0.109) || (freq >0.25 && freq<0.251)){
44  return 0;
45  }else{
46  return 1-exp(-pow(freq/cut_off,8));
47  }
48 }
49 
50 double filter_low_loose(double freq){
51  return 1-exp(-pow(freq/0.005,2));
52 }
53 
54 
56  const WireCell::Waveform::realseq_t& medians,
57  const WireCell::Waveform::compseq_t& respec,
58  int res_offset,
59  std::vector< std::vector<int> >& rois,
60  float decon_limit1,
61  float roi_min_max_ratio)
62 {
63  double ave_coef = 0;
64  double_t ave_coef1 = 0;
65  std::map<int,double> coef_all;
66 
67  const int nbin = medians.size();
68 
69  for (auto it: chansig) {
70  int ch = it.first;
71  WireCell::IChannelFilter::signal_t& signal = it.second;
72 
73 
74  double sum2 = 0;
75  double sum3 = 0;
76  double coef = 0;
77 
78  std::pair<double,double> temp = Derivations::CalcRMS(signal);
79  //std::pair<double,double> temp = WireCell::Waveform::mean_rms(signal);
80 
81  // if ( abs(ch-6117)<5)
82  // std::cout << ch << " " << temp.first << " " << temp.second << " " << std::endl;
83 
84  for (int j=0;j!=nbin;j++){
85  if (fabs(signal.at(j)) < 4 * temp.second){
86  sum2 += signal.at(j) * medians.at(j);
87  sum3 += medians.at(j) * medians.at(j);
88  }
89  }
90  if (sum3 >0) {
91  coef = sum2/sum3;
92  }
93  // protect against the extreme cases
94  // if (coef < 0.6) coef = 0.6;
95  // if (coef > 1.5) coef = 1.5;
96 
97  coef_all[ch] = coef;
98  if (coef != 0){ // FIXME: expect some fluctuation?
99  ave_coef += coef;
100  ave_coef1 ++;
101  }
102  }
103  if (ave_coef1 > 0) {
104  ave_coef = ave_coef / ave_coef1;
105  }
106 
107  for (auto it: chansig) {
108  int ch = it.first;
109  WireCell::IChannelFilter::signal_t& signal = it.second;
110  float scaling;
111  if (ave_coef != 0 ){
112  scaling = coef_all[ch]/ave_coef;
113  // add some protections ...
114  if (scaling < 0) scaling = 0;
115  // if (scaling < 0.5 && scaling > 0.3) scaling = 0.5;
116  if (scaling > 1.5) scaling = 1.5;
117  }else{
118  scaling = 0;
119  }
120  // if ( abs(ch-6117)<5)
121  // std::cout << ch << " " << scaling << " " << std::endl;
122  //scaling = 1.0;
123 
124 
125  if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
126  int nbin = signal.size();
127  WireCell::Waveform::realseq_t signal_roi(nbin,0);
128  for (auto roi: rois){
129  const int bin0 = std::max(roi.front()-1, 0);
130  const int binf = std::min(roi.back()+1, nbin-1);
131  const double m0 = signal[bin0];
132  const double mf = signal[binf];
133  const double roi_run = binf - bin0;
134  const double roi_rise = mf - m0;
135  for (auto bin : roi) {
136  const double m = m0 + (bin - bin0)/roi_run*roi_rise;
137  signal_roi.at(bin) = signal.at(bin) - m;
138  }
139  }
140 
141  // do the deconvolution with a very loose low-frequency filter
142  WireCell::Waveform::compseq_t signal_roi_freq = WireCell::Waveform::dft(signal_roi);
143  WireCell::Waveform::shrink(signal_roi_freq,respec);
144  for (size_t i=0;i!=signal_roi_freq.size();i++){
145  double freq;
146  // assuming 2 MHz digitization
147  if (i <signal_roi_freq.size()/2.){
148  freq = i/(1.*signal_roi_freq.size())*2.;
149  }else{
150  freq = (signal_roi_freq.size() - i)/(1.*signal_roi_freq.size())*2.;
151  }
152  std::complex<float> factor = filter_time(freq)*filter_low_loose(freq);
153  signal_roi_freq.at(i) = signal_roi_freq.at(i) * factor;
154  }
155  WireCell::Waveform::realseq_t signal_roi_decon = WireCell::Waveform::idft(signal_roi_freq);
156 
157  std::map<int, bool> flag_replace;
158  for (auto roi: rois){
159  flag_replace[roi.front()] = false;
160  }
161 
162  // judge if any ROI is good ...
163  for (auto roi: rois){
164  const int bin0 = std::max(roi.front()-1, 0);
165  const int binf = std::min(roi.back()+1, nbin-1);
166  double max_val = 0;
167  double min_val = 0;
168  for (int i=bin0; i<=binf; i++){
169  int time_bin = i-res_offset;
170  if (time_bin <0) time_bin += nbin;
171  if (time_bin >=nbin) time_bin -= nbin;
172  if (i==bin0){
173  max_val = signal_roi_decon.at(time_bin);
174  min_val = signal_roi_decon.at(time_bin);
175  }else{
176  if (signal_roi_decon.at(time_bin) > max_val) max_val = signal_roi_decon.at(time_bin);
177  if (signal_roi_decon.at(time_bin) < min_val) min_val = signal_roi_decon.at(time_bin);
178  }
179  }
180 
181  // if (signal.ch==1027)
182  //std::cout << roi.front() << " Xin " << max_val << " " << decon_limit1 << std::endl;
183 
184  if ( max_val > decon_limit1 && fabs(min_val) < max_val * roi_min_max_ratio)
185  flag_replace[roi.front()] = true;
186  }
187 
188  WireCell::Waveform::realseq_t temp_medians = medians;
189 
190  for (auto roi : rois) {
191  // original code used the bins just outside the ROI
192  const int bin0 = std::max(roi.front()-1, 0);
193  const int binf = std::min(roi.back()+1, nbin-1);
194  if (flag_replace[roi.front()]){
195  const double m0 = temp_medians[bin0];
196  const double mf = temp_medians[binf];
197  const double roi_run = binf - bin0;
198  const double roi_rise = mf - m0;
199  for (auto bin : roi) {
200  const double m = m0 + (bin - bin0)/roi_run*roi_rise;
201  temp_medians.at(bin) = m;
202  }
203  }
204  }
205 
206  // collection plane, directly subtracti ...
207  for (int i=0;i!=nbin;i++){
208  if (fabs(signal.at(i)) > 0.001) {
209  signal.at(i) = signal.at(i) - temp_medians.at(i) * scaling;
210  }
211  }
212 
213 
214  }else{
215  // collection plane, directly subtracti ...
216  for (int i=0;i!=nbin;i++){
217  if (fabs(signal.at(i)) > 0.001) {
218  signal.at(i) = signal.at(i) - medians.at(i) * scaling;
219  }
220  }
221  }
222  chansig[ch] = signal;
223  }
224 
225  // for (auto it: chansig){
226  // std::cout << "Xin2 " << it.second.at(0) << std::endl;
227  // }
228 
229  return true;
230 }
231 
232 std::vector< std::vector<int> > Microboone::SignalProtection(WireCell::Waveform::realseq_t& medians, const WireCell::Waveform::compseq_t& respec, int res_offset, int pad_f, int pad_b, float upper_decon_limit, float decon_lf_cutoff, float upper_adc_limit, float protection_factor, float min_adc_limit)
233 {
234 
235 
236  // WireCell::Waveform::realseq_t temp1;
237  // for (int i=0;i!=medians.size();i++){
238  // if (fabs(medians.at(i) - mean) < 4.5*rms)
239  // temp1.push_back(medians.at(i));
240  // }
241  // temp = WireCell::Waveform::mean_rms(temp1);
242  // mean = temp.first;
243  // rms = temp.second;
244 
245  //std::cout << temp.first << " " << temp.second << std::endl;
246  const int nbin = medians.size();
247 
248  // const int protection_factor = 5.0;
249  // move to input ...
250  // const float upper_decon_limit = 0.05;
251  // const float upper_adc_limit = 15;
252  //const float min_adc_limit = 50;
253 
254 
255  std::vector<bool> signalsBool;
256  signalsBool.resize(nbin, false);
257 
258 
259 
260 
261  // calculate the RMS
262  std::pair<double,double> temp = Derivations::CalcRMS(medians);
263  double mean = temp.first;
264  double rms = temp.second;
265 
266  // std::cout << mean << " " << rms << " " << respec.size() << " " << res_offset << " " << pad_f << " " << pad_b << " " << respec.at(0) << std::endl;
267 
268  float limit;
269  if (protection_factor*rms > upper_adc_limit){
270  limit = protection_factor*rms;
271  }else{
272  limit = upper_adc_limit;
273  }
274  if (min_adc_limit < limit){
275  limit = min_adc_limit;
276  }
277 
278  // std::cout << "Xin " << protection_factor << " " << mean << " " << rms *protection_factor << " " << upper_adc_limit << " " << decon_lf_cutoff << " " << upper_decon_limit << std::endl;
279 
280  for (int j=0;j!=nbin;j++) {
281  float content = medians.at(j);
282  if (fabs(content-mean)>limit){
283  //protection_factor*rms) {
284  // medians.at(j) = 0;
285  signalsBool.at(j) = true;
286  // add the front and back padding
287  for (int k=0;k!=pad_b;k++){
288  int bin = j+k+1;
289  if (bin > nbin-1) bin = nbin-1;
290  signalsBool.at(bin) = true;
291  }
292  for (int k=0;k!=pad_f;k++){
293  int bin = j-k-1;
294  if (bin <0) { bin = 0; }
295  signalsBool.at(bin) = true;
296  }
297  }
298  }
299 
300 
301  //std::cout << "Xin: " << respec.size() << " " << res_offset << std::endl;
302  // the deconvolution protection code ...
303  if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
304  //std::cout << nbin << std::endl;
305 
307  WireCell::Waveform::shrink(medians_freq,respec);
308 
309  for (size_t i=0;i!=medians_freq.size();i++){
310  double freq;
311  // assuming 2 MHz digitization
312  if (i <medians_freq.size()/2.){
313  freq = i/(1.*medians_freq.size())*2.;
314  }else{
315  freq = (medians_freq.size() - i)/(1.*medians_freq.size())*2.;
316  }
317  std::complex<float> factor = filter_time(freq)*filter_low(freq, decon_lf_cutoff);
318  medians_freq.at(i) = medians_freq.at(i) * factor;
319  }
320  WireCell::Waveform::realseq_t medians_decon = WireCell::Waveform::idft(medians_freq);
321 
322  temp = Derivations::CalcRMS(medians_decon);
323  mean = temp.first;
324  rms = temp.second;
325 
326  if (protection_factor*rms > upper_decon_limit){
327  limit = protection_factor*rms;
328  }else{
329  limit = upper_decon_limit;
330  }
331 
332 
333  // std::cout << "Xin: " << protection_factor << " " << rms << " " << upper_decon_limit << std::endl;
334 
335 
336 
337  for (int j=0;j!=nbin;j++) {
338  float content = medians_decon.at(j);
339  if ((content-mean)>limit){
340  int time_bin = j + res_offset;
341  if (time_bin >= nbin) time_bin -= nbin;
342  // medians.at(time_bin) = 0;
343  signalsBool.at(time_bin) = true;
344  // add the front and back padding
345  for (int k=0;k!=pad_b;k++){
346  int bin = time_bin+k+1;
347  if (bin > nbin-1) bin = nbin-1;
348  signalsBool.at(bin) = true;
349  }
350  for (int k=0;k!=pad_f;k++){
351  int bin = time_bin-k-1;
352  if (bin <0) { bin = 0; }
353  signalsBool.at(bin) = true;
354  }
355  }
356  }
357 
358 
359  // // second-level decon ...
360  // medians_freq = WireCell::Waveform::dft(medians);
361  // WireCell::Waveform::realseq_t respec_time = WireCell::Waveform::idft(respec);
362  // for (size_t i=0;i!=respec_time.size();i++){
363  // if (respec_time.at(i)<0) respec_time.at(i) = 0;
364  // }
365  // WireCell::Waveform::compseq_t respec_freq = WireCell::Waveform::dft(respec_time);
366  // WireCell::Waveform::shrink(medians_freq,respec_freq);
367  // for (size_t i=0;i!=medians_freq.size();i++){
368  // double freq;
369  // // assuming 2 MHz digitization
370  // if (i <medians_freq.size()/2.){
371  // freq = i/(1.*medians_freq.size())*2.;
372  // }else{
373  // freq = (medians_freq.size() - i)/(1.*medians_freq.size())*2.;
374  // }
375  // std::complex<float> factor = filter_time(freq)*filter_low(freq, decon_lf_cutoff);
376  // medians_freq.at(i) = medians_freq.at(i) * factor;
377  // }
378  // medians_decon = WireCell::Waveform::idft(medians_freq);
379 
380  // temp = Derivations::CalcRMS(medians_decon);
381  // mean = temp.first;
382  // rms = temp.second;
383 
384  // // if (protection_factor*rms > upper_decon_limit){
385  // limit = protection_factor*rms;
386  // // }else{
387  // // limit = upper_decon_limit;
388  // // }
389 
390  // for (int j=0;j!=nbin;j++) {
391  // float content = medians_decon.at(j);
392  // if ((content-mean)>limit){
393  // int time_bin = j + res_offset;
394  // if (time_bin >= nbin) time_bin -= nbin;
395  // // medians.at(time_bin) = 0;
396  // signalsBool.at(time_bin) = true;
397  // // add the front and back padding
398  // for (int k=0;k!=pad_b;k++){
399  // int bin = time_bin+k+1;
400  // if (bin > nbin-1) bin = nbin-1;
401  // signalsBool.at(bin) = true;
402  // }
403  // for (int k=0;k!=pad_f;k++){
404  // int bin = time_bin-k-1;
405  // if (bin <0) { bin = 0; }
406  // signalsBool.at(bin) = true;
407  // }
408  // }
409  // }
410 
411 
412  }
413 
414  // {
415  // partition waveform indices into consecutive regions with
416  // signalsBool true.
417  std::vector< std::vector<int> > rois;
418  bool inside = false;
419  for (int ind=0; ind<nbin; ++ind) {
420  if (inside) {
421  if (signalsBool[ind]) { // still inside
422  rois.back().push_back(ind);
423  }else{
424  inside = false;
425  }
426  }
427  else { // outside the Rio
428  if (signalsBool[ind]) { // just entered ROI
429  std::vector<int> roi;
430  roi.push_back(ind);
431  rois.push_back(roi);
432  inside = true;
433  }
434  }
435  }
436 
437 
438 
439  std::map<int, bool> flag_replace;
440  for (auto roi: rois){
441  flag_replace[roi.front()] = true;
442  }
443 
444  if (respec.size() > 0 && (respec.at(0).real()!=1 || respec.at(0).imag()!=0) && res_offset!=0){
445  for (auto roi: rois){
446  flag_replace[roi.front()] = false;
447  }
448  }
449 
450 
451  // // use ROI to get a new waveform
452  // WireCell::Waveform::realseq_t medians_roi(nbin,0);
453  // for (auto roi: rois){
454  // const int bin0 = std::max(roi.front()-1, 0);
455  // const int binf = std::min(roi.back()+1, nbin-1);
456  // const double m0 = medians[bin0];
457  // const double mf = medians[binf];
458  // const double roi_run = binf - bin0;
459  // const double roi_rise = mf - m0;
460  // for (auto bin : roi) {
461  // const double m = m0 + (bin - bin0)/roi_run*roi_rise;
462  // medians_roi.at(bin) = medians.at(bin) - m;
463  // }
464  // }
465  // // do the deconvolution with a very loose low-frequency filter
466  // WireCell::Waveform::compseq_t medians_roi_freq = WireCell::Waveform::dft(medians_roi);
467  // WireCell::Waveform::shrink(medians_roi_freq,respec);
468  // for (size_t i=0;i!=medians_roi_freq.size();i++){
469  // double freq;
470  // // assuming 2 MHz digitization
471  // if (i <medians_roi_freq.size()/2.){
472  // freq = i/(1.*medians_roi_freq.size())*2.;
473  // }else{
474  // freq = (medians_roi_freq.size() - i)/(1.*medians_roi_freq.size())*2.;
475  // }
476  // std::complex<float> factor = filter_time(freq)*filter_low_loose(freq);
477  // medians_roi_freq.at(i) = medians_roi_freq.at(i) * factor;
478  // }
479  // WireCell::Waveform::realseq_t medians_roi_decon = WireCell::Waveform::idft(medians_roi_freq);
480 
481  // // judge if a roi is good or not ...
482  // //shift things back properly
483  // for (auto roi: rois){
484  // const int bin0 = std::max(roi.front()-1, 0);
485  // const int binf = std::min(roi.back()+1, nbin-1);
486  // flag_replace[roi.front()] = false;
487 
488  // double max_val = 0;
489  // double min_val = 0;
490  // // double max_adc_val=0;
491  // // double min_adc_val=0;
492 
493  // for (int i=bin0; i<=binf; i++){
494  // int time_bin = i-res_offset;
495  // if (time_bin <0) time_bin += nbin;
496  // if (time_bin >=nbin) time_bin -= nbin;
497 
498  // if (i==bin0){
499  // max_val = medians_roi_decon.at(time_bin);
500  // min_val = medians_roi_decon.at(time_bin);
501  // // max_adc_val = medians.at(i);
502  // // min_adc_val = medians.at(i);
503  // }else{
504  // if (medians_roi_decon.at(time_bin) > max_val) max_val = medians_roi_decon.at(time_bin);
505  // if (medians_roi_decon.at(time_bin) < min_val) min_val = medians_roi_decon.at(time_bin);
506  // // if (medians.at(i) > max_adc_val) max_adc_val = medians.at(i);
507  // // if (medians.at(i) < min_adc_val) min_adc_val = medians.at(i);
508  // }
509  // }
510 
511  // //std::cout << "Xin: " << upper_decon_limit1 << std::endl;
512  // // if ( max_val > upper_decon_limit1)
513  // // if ( max_val > 0.04 && fabs(min_val) < 0.6*max_val)
514  // //if (max_val > 0.06 && fabs(min_val) < 0.6*max_val)
515  // if (max_val > 0.06)
516  // flag_replace[roi.front()] = true;
517  // }
518  // }
519 
520  // Replace medians for above regions with interpolation on values
521  // just outside each region.
522  for (auto roi : rois) {
523  // original code used the bins just outside the ROI
524  const int bin0 = std::max(roi.front()-1, 0);
525  const int binf = std::min(roi.back()+1, nbin-1);
526  if (flag_replace[roi.front()]){
527  const double m0 = medians[bin0];
528  const double mf = medians[binf];
529  const double roi_run = binf - bin0;
530  const double roi_rise = mf - m0;
531  for (auto bin : roi) {
532  const double m = m0 + (bin - bin0)/roi_run*roi_rise;
533  medians.at(bin) = m;
534  }
535  }
536  }
537 
538 
539  return rois;
540 }
541 
542 bool Microboone::NoisyFilterAlg(WireCell::Waveform::realseq_t& sig, float min_rms, float max_rms)
543 {
544  const double rmsVal = Microboone::CalcRMSWithFlags(sig);
545 
546  //std::cout << rmsVal << std::endl;
547 
548  // int planeNum,channel_no;
549  // if (ch < 2400) {
550  // planeNum = 0;
551  // channel_no = ch;
552  // }
553  // else if (ch < 4800) {
554  // planeNum = 1;
555  // channel_no = ch - 2400;
556  // }
557  // else {
558  // planeNum = 2;
559  // channel_no = ch - 4800;
560  // }
561 
562  // //std::cout << rmsVal << " " << ch << std::endl;
563 
564  // double maxRMSCut[3] = {10.0,10.0,5.0};
565  // double minRMSCut[3] = {2,2,2};
566 
567  // if (planeNum == 0) {
568  // if (channel_no < 100) {
569  // maxRMSCut[0] = 5;
570  // minRMSCut[0] = 1;
571  // }
572  // else if (channel_no >= 100 && channel_no<2000) {
573  // maxRMSCut[0] = 11; // increase the threshold slightly ...
574  // minRMSCut[0] = 1.9;
575  // }
576  // else if (channel_no >= 2000 && channel_no < 2400) {
577  // maxRMSCut[0] = 5;
578  // minRMSCut[0] = 0.9; // take into account FT-1 channel ...
579  // }
580  // }
581  // else if (planeNum == 1) {
582  // if (channel_no <290){
583  // maxRMSCut[1] = 5;
584  // minRMSCut[1] = 1;
585  // }
586  // else if (channel_no>=290 && channel_no < 2200) {
587  // maxRMSCut[1] = 11;
588  // minRMSCut[1] = 1.9;
589  // }
590  // else if (channel_no >=2200) {
591  // maxRMSCut[1] = 5;
592  // minRMSCut[1] = 1;
593  // }
594  // }
595  // else if (planeNum == 2) {
596  // maxRMSCut[2] = 8;
597  // minRMSCut[2] = 1.3; // reduce threshold to take into account the adaptive baseline ...
598  // }
599 
600  //if(rmsVal > maxRMSCut[planeNum] || rmsVal < minRMSCut[planeNum]) {
601  if(rmsVal > max_rms || rmsVal < min_rms) {
602  int numBins = sig.size();
603  for(int i = 0; i < numBins; i++) {
604  sig.at(i) = 10000.0;
605  }
606 
607  return true;
608  }
609 
610  return false;
611 }
612 
613 
614 
616 {
617  if (bin1 < 0 ) bin1 = 0;
618  if (bin2 > (int)sig.size()) bin2 = sig.size();
619  for (int i=bin1; i<bin2;i++) {
620  sig.at(i) = 10000.0;
621  }
622  return true;
623 }
624 
626 {
627  float theRMS = 0.0;
628  //int waveformSize = sig.size();
629 
631  for (size_t i=0;i!=sig.size();i++){
632  if (sig.at(i) < 4096) temp.push_back(sig.at(i));
633  }
634  float par[3];
635  if (temp.size()>0) {
636  par[0] = WireCell::Waveform::percentile_binned(temp,0.5 - 0.34);
637  par[1] = WireCell::Waveform::percentile_binned(temp,0.5);
638  par[2] = WireCell::Waveform::percentile_binned(temp,0.5 + 0.34);
639 
640  // std::cout << par[0] << " " << par[1] << " " << par[2] << std::endl;
641 
642  theRMS = sqrt((pow(par[2]-par[1],2)+pow(par[1]-par[0],2))/2.);
643  }
644 
645  return theRMS;
646 }
647 
649 {
650  const double sigFactor = 4.0;
651  const int padBins = 8;
652 
653  float rmsVal = Microboone::CalcRMSWithFlags(sig);
654  float sigThreshold = sigFactor*rmsVal;
655 
656  float ADCval;
657  std::vector<bool> signalRegions;
658  int numBins = sig.size();
659 
660  for (int i = 0; i < numBins; i++) {
661  ADCval = sig.at(i);
662  if (((ADCval > sigThreshold) || (ADCval < -1.0*sigThreshold)) && (ADCval < 4096.0)) {
663  signalRegions.push_back(true);
664  }
665  else {
666  signalRegions.push_back(false);
667  }
668  }
669 
670  for(int i = 0; i < numBins; i++) {
671  if(signalRegions[i] == true) {
672  int bin1 = i - padBins;
673  if (bin1 < 0 ) {
674  bin1 = 0;
675  }
676  int bin2 = i + padBins;
677  if (bin2 > numBins) {
678  bin2 = numBins;
679  }
680 
681  for(int j = bin1; j < bin2; j++) {
682  ADCval = sig.at(j);
683  if(ADCval < 4096.0) {
684  sig.at(j) = sig.at(j)+20000.0;
685  }
686  }
687  }
688  }
689  return true;
690 }
691 
692 
694 {
695  const int windowSize = 20;
696  const int numBins = sig.size();
697  int minWindowBins = windowSize/2;
698 
699  std::vector<double> baselineVec(numBins, 0.0);
700  std::vector<bool> isFilledVec(numBins, false);
701 
702  int numFlaggedBins = 0;
703 
704  for(int j = 0; j < numBins; j++) {
705  if(sig.at(j) == 10000.0) {
706  numFlaggedBins++;
707  }
708  }
709  if(numFlaggedBins == numBins) {
710  return true; // Eventually replace this with flag check
711  }
712 
713  double baselineVal = 0.0;
714  int windowBins = 0;
715  //int index;
716  double ADCval = 0.0;
717  for(int j = 0; j <= windowSize/2; j++) {
718  ADCval = sig.at(j);
719  if(ADCval < 4096.0) {
720  baselineVal += ADCval;
721  windowBins++;
722  }
723  }
724 
725  if(windowBins == 0) {
726  baselineVec[0] = 0.0;
727  }
728  else {
729  baselineVec[0] = baselineVal/((double) windowBins);
730  }
731 
732  if(windowBins < minWindowBins) {
733  isFilledVec[0] = false;
734  }
735  else {
736  isFilledVec[0] = true;
737  }
738 
739  for(int j = 1; j < numBins; j++) {
740  int oldIndex = j-windowSize/2-1;
741  int newIndex = j+windowSize/2;
742 
743  if(oldIndex >= 0) {
744  ADCval = sig.at(oldIndex);
745  if(ADCval < 4096.0) {
746  baselineVal -= sig.at(oldIndex);
747  windowBins--;
748  }
749  }
750  if(newIndex < numBins) {
751  ADCval = sig.at(newIndex);
752  if(ADCval < 4096) {
753  baselineVal += sig.at(newIndex);
754  windowBins++;
755  }
756  }
757 
758  if(windowBins == 0) {
759  baselineVec[j] = 0.0;
760  }
761  else {
762  baselineVec[j] = baselineVal/windowBins;
763  }
764 
765  if(windowBins < minWindowBins) {
766  isFilledVec[j] = false;
767  }
768  else {
769  isFilledVec[j] = true;
770  }
771  }
772 
773  for(int j = 0; j < numBins; j++) {
774  bool downFlag = false;
775  bool upFlag = false;
776 
777  ADCval = sig.at(j);
778  if(ADCval != 10000.0) {
779  if(isFilledVec[j] == false) {
780  int downIndex = j;
781  while((isFilledVec[downIndex] == false) && (downIndex > 0) && (sig.at(downIndex) != 10000.0)) {
782  downIndex--;
783  }
784 
785  if(isFilledVec[downIndex] == false) {
786  downFlag = true;
787  }
788 
789  int upIndex = j;
790  while((isFilledVec[upIndex] == false) && (upIndex < numBins-1) && (sig.at(upIndex) != 10000.0)) {
791  upIndex++;
792  }
793 
794  if(isFilledVec[upIndex] == false) {
795  upFlag = true;
796  }
797 
798  if((downFlag == false) && (upFlag == false)) {
799  baselineVec[j] = ((j-downIndex)*baselineVec[downIndex]+(upIndex-j)*baselineVec[upIndex])/((double) upIndex-downIndex);
800  }
801  else if((downFlag == true) && (upFlag == false)) {
802  baselineVec[j] = baselineVec[upIndex];
803  }
804  else if((downFlag == false) && (upFlag == true)) {
805  baselineVec[j] = baselineVec[downIndex];
806  }
807  else {
808  baselineVec[j] = 0.0;
809  }
810  }
811 
812  sig.at(j) = ADCval -baselineVec[j];
813  }
814  }
815 
816  return true;
817 
818 }
819 
820 
822 {
823  int numBins = sig.size();
824  for(int i = 0; i < numBins; i++) {
825  double ADCval = sig.at(i);
826  if (ADCval > 4096.0) {
827  if(ADCval > 10000.0) {
828  sig.at(i) = ADCval-20000.0;
829  }
830  else {
831  sig.at(i) = 0.0;
832  }
833 
834  }
835  }
836 
837  return true;
838 }
839 
840 
841 /*
842  * Classes
843  */
844 
845 
846 /*
847  * Configuration base class used for a couple filters
848  */
849 Microboone::ConfigFilterBase::ConfigFilterBase(const std::string& anode, const std::string& noisedb)
850  : m_anode_tn(anode)
851  , m_noisedb_tn(noisedb) {}
854 {
855  m_anode_tn = get(cfg, "anode", m_anode_tn);
856  m_anode = Factory::find_tn<IAnodePlane>(m_anode_tn);
857  m_noisedb_tn = get(cfg, "noisedb", m_noisedb_tn);
858  m_noisedb = Factory::find_tn<IChannelNoiseDatabase>(m_noisedb_tn);
859  //std::cerr << "ConfigFilterBase: \n" << cfg << "\n";
860 }
862 {
864  cfg["anode"] = m_anode_tn;
865  cfg["noisedb"] = m_noisedb_tn;
866  return cfg;
867 }
868 
869 
870 
872  : ConfigFilterBase(anode, noisedb) {}
874 
877 {
878  //std::cout << "Xin2: " << " " << chansig.size() << std::endl;
879  // find the median among all
881 
882  // std::cout << medians.size() << " " << medians.at(100) << " " << medians.at(101) << std::endl;
883 
884 
885  // For Xin: here is how you can get the response spectrum for this group.
886  const int achannel = chansig.begin()->first;
887 
888  //std::cerr << "CoherentNoiseSub: ch=" << achannel << " response offset:" << m_noisedb->response_offset(achannel) << std::endl;
889 
890  const Waveform::compseq_t& respec = m_noisedb->response(achannel);
891  const int res_offset = m_noisedb->response_offset(achannel);
892  const int pad_f = m_noisedb->pad_window_front(achannel);
893  const int pad_b = m_noisedb->pad_window_back(achannel);
894 
895  // need to move these to data base, consult with Brett ...
896  // also need to be time dependent ...
897  const float decon_limit = m_noisedb->coherent_nf_decon_limit(achannel);// 0.02;
898  const float decon_lf_cutoff = m_noisedb->coherent_nf_decon_lf_cutoff(achannel);
899  const float adc_limit = m_noisedb->coherent_nf_adc_limit(achannel);//15;
900  const float decon_limit1 = m_noisedb->coherent_nf_decon_limit1(achannel);// 0.08; // loose filter
901  const float roi_min_max_ratio = m_noisedb->coherent_nf_roi_min_max_ratio(achannel);// 0.8 default
902 
903  const float protection_factor = m_noisedb->coherent_nf_protection_factor(achannel);
904  const float min_adc_limit = m_noisedb->coherent_nf_min_adc_limit(achannel);
905 
906  // std::cout << decon_limit << " " << adc_limit << " " << protection_factor << " " << min_adc_limit << std::endl;
907 
908  // if (respec.size()) {
909  // now, apply the response spectrum to deconvolve the median
910  // and apply the special protection or pass respec into
911  // SignalProtection().
912  //}
913 
914  //std::cout << achannel << std::endl;
915 
916  // do the signal protection and adaptive baseline
917  std::vector< std::vector<int> > rois = Microboone::SignalProtection(medians,respec,res_offset,pad_f,pad_b,decon_limit, decon_lf_cutoff, adc_limit, protection_factor, min_adc_limit);
918 
919  // if (achannel == 3840){
920  // std::cout << "Xin1: " << rois.size() << std::endl;
921  // for (size_t i=0;i!=rois.size();i++){
922  // std::cout << "Xin1: " << rois.at(i).front() << " " << rois.at(i).back() << std::endl;
923  // }
924  // }
925 
926  //std::cerr <<"\tSigprotection done: " << chansig.size() << " " << medians.size() << " " << medians.at(100) << " " << medians.at(101) << std::endl;
927 
928  // calculate the scaling coefficient and subtract
929  Microboone::Subtract_WScaling(chansig, medians, respec, res_offset, rois, decon_limit1, roi_min_max_ratio);
930 
931 
932  // WireCell::IChannelFilter::signal_t& signal = chansig.begin()->second;
933  // for (size_t i=0;i!=signal.size();i++){
934  // signal.at(i) = medians.at(i);
935  // }
936 
937  //std::cerr <<"\tSubtrace_WScaling done" << std::endl;
938 
939  // for (auto it: chansig){
940  // std::cout << "Xin3 " << it.first << std::endl;
941  // break;
942  // }
943 
944  return WireCell::Waveform::ChannelMaskMap(); // not implemented
945 }
948 {
949  return WireCell::Waveform::ChannelMaskMap(); // not implemented
950 }
951 
952 
953 
954 
955 
957  : ConfigFilterBase(anode, noisedb)
958  , m_check_chirp() // fixme, there are magic numbers hidden here
959  , m_check_partial() // fixme, here too.
960 {
961 }
963 {
964 }
965 
967 {
969 
970  // sanity check data/config match.
971  const size_t nsiglen = signal.size();
972  int nmismatchlen = 0;
973 
974  // fixme: some channels are just bad can should be skipped.
975 
976  // get signal with nominal baseline correction
977  float baseline = m_noisedb->nominal_baseline(ch);
978 
979  // get signal with nominal gain correction
980  float gc = m_noisedb->gain_correction(ch);
981  WireCell::Waveform::increase(signal, baseline *(-1));
982 
983  auto signal_gc = signal; // copy, need to keep original signal
984 
985  WireCell::Waveform::scale(signal_gc, gc);
986 
987  // std::cerr << "OneChannelNoise: ch="<<ch<<" gain scaled sum=" << Waveform::sum(signal_gc)
988  // << std::endl;;
989 
990 
991  // determine if chirping
992  WireCell::Waveform::BinRange chirped_bins;
993  bool is_chirp = m_check_chirp(signal_gc, chirped_bins.first, chirped_bins.second);
994  if (is_chirp) {
995  ret["chirp"][ch].push_back(chirped_bins);
996 
997  auto wpid = m_anode->resolve(ch);
998  const int iplane = wpid.index();
999 
1000  if (iplane!=2){ // not collection
1001  if (chirped_bins.first>0 || chirped_bins.second<int(signal.size())){
1002  ret["lf_noisy"][ch].push_back(chirped_bins);
1003  //std::cout << "Chirp " << ch << std::endl;
1004  }
1005  }
1006  }
1007 
1008  auto spectrum = WireCell::Waveform::dft(signal);
1009  //std::cerr << "OneChannelNoise: "<<ch<<" dft spectral sum="<<Waveform::sum(spectrum)<<"\n";
1010 
1011  bool is_partial = m_check_partial(spectrum); // Xin's "IS_RC()"
1012 
1013  int nspec=0; // just catch any non-zero
1014  if (!is_partial) {
1015  auto const& spec = m_noisedb->rcrc(ch);
1016  WireCell::Waveform::shrink(spectrum, spec);
1017 
1018  if (nsiglen != spec.size()) {
1019  ++nmismatchlen;
1020  nspec=spec.size();
1021  }
1022  }
1023 
1024  {
1025  auto const& spec = m_noisedb->config(ch);
1026  WireCell::Waveform::scale(spectrum, spec);
1027 
1028  if (nsiglen != spec.size()) {
1029  ++nmismatchlen;
1030  nspec=spec.size();
1031  }
1032  }
1033 
1034  {
1035  auto const& spec = m_noisedb->noise(ch);
1036  WireCell::Waveform::scale(spectrum, spec);
1037 
1038  if (nsiglen != spec.size()) {
1039  ++nmismatchlen;
1040  nspec=spec.size();
1041  }
1042  }
1043 
1044  if (nmismatchlen) {
1045  std::cerr << "OneChannelNoise: WARNING: "<<nmismatchlen << " config/data mismatches. "
1046  << "#spec="<<nspec <<", #wave=" << nsiglen << ".\n"
1047  << "\tResults may be suspect."
1048  << std::endl;
1049  }
1050 
1051  // remove the DC component
1052  spectrum.front() = 0;
1053  signal = WireCell::Waveform::idft(spectrum);
1054 
1055  //std::cerr << "OneChannelNoise: "<<ch<<" after dft: sigsum="<<Waveform::sum(signal)<<"\n";
1056 
1057  //Now calculate the baseline ...
1058  std::pair<double,double> temp = WireCell::Waveform::mean_rms(signal);
1059  auto temp_signal = signal;
1060  for (size_t i=0;i!=temp_signal.size();i++){
1061  if (fabs(temp_signal.at(i)-temp.first)>6*temp.second){
1062  temp_signal.at(i) = temp.first;
1063  }
1064  }
1065  baseline = WireCell::Waveform::median_binned(temp_signal);
1066  //correct baseline
1067  WireCell::Waveform::increase(signal, baseline *(-1));
1068 
1069 
1070  //*** from here down is where things become way too microboone
1071  //*** specific and are basically copy-pasted from the prototype
1072 
1073 
1074  // Now do adaptive baseline for the chirping channels
1075  if (is_chirp) {
1076  Microboone::Chirp_raise_baseline(signal,chirped_bins.first, chirped_bins.second);
1077  Microboone::SignalFilter(signal);
1079  }
1080  // Now do the adaptive baseline for the bad RC channels
1081  if (is_partial) {
1082  // add something
1083  WireCell::Waveform::BinRange temp_chirped_bins;
1084  temp_chirped_bins.first = 0;
1085  temp_chirped_bins.second = signal.size();
1086 
1087  auto wpid = m_anode->resolve(ch);
1088  const int iplane = wpid.index();
1089  if (iplane!=2) { // not collection
1090  ret["lf_noisy"][ch].push_back(temp_chirped_bins);
1091  //std::cout << "Partial " << ch << std::endl;
1092  }
1093  Microboone::SignalFilter(signal);
1095  }
1096 
1097  // std::cerr << "OneChannelNoise: "<<ch<<" before SignalFilter: sigsum="<<Waveform::sum(signal)<<"\n";
1098 
1099  // Identify the Noisy channels ...
1100  Microboone::SignalFilter(signal);
1101 
1102  //
1103  const float min_rms = m_noisedb->min_rms_cut(ch);
1104  const float max_rms = m_noisedb->max_rms_cut(ch);
1105 
1106  //std::cerr << "OneChannelNoise: "<<ch<< " RMS:["<<min_rms<<","<<max_rms<<"] sigsum="<<Waveform::sum(signal)<<"\n";
1107 
1108  bool is_noisy = Microboone::NoisyFilterAlg(signal,min_rms,max_rms);
1110 
1111  if (is_noisy) {
1112  // std::cerr << "OneChannelNoise: "<<ch
1113  // <<" is_noisy="<<is_noisy
1114  // <<", is_chirp="<<is_chirp
1115  // <<", is_partial="<<is_partial
1116  // <<", baseline="<<baseline<<std::endl;
1117 
1118  chirped_bins.first = 0;
1119  chirped_bins.second = signal.size();
1120  ret["noisy"][ch].push_back(chirped_bins);
1121 
1122  if (ret.find("lf_noisy") != ret.end()) {
1123  if(ret["lf_noisy"].find(ch)!=ret["lf_noisy"].end())
1124  ret["lf_noisy"].erase(ch);
1125  }
1126 
1127  }
1128 
1129  return ret;
1130 }
1131 
1132 
1133 
1135 {
1137 }
1138 
1139 
1140 
1141 
1142 
1143 
1144 Microboone::ADCBitShift::ADCBitShift(int nbits, int exam_nticks, double threshold_sigma, double threshold_fix)
1145  : m_nbits(nbits)
1146  , m_exam_nticks(exam_nticks)
1147  , m_threshold_sigma(threshold_sigma)
1148  , m_threshold_fix(threshold_fix)
1149 {
1150 }
1152 {
1153 }
1154 
1156 {
1157  m_nbits = get<int>(cfg, "Number_of_ADC_bits", m_nbits);
1158  m_exam_nticks = get<int>(cfg, "Exam_number_of_ticks_test", m_exam_nticks);
1159  m_threshold_sigma = get<double>(cfg, "Threshold_sigma_test", m_threshold_sigma);
1160  m_threshold_fix = get<double>(cfg, "Threshold_fix", m_threshold_fix);
1161  //std::cerr << "ADCBitShift: \n" << cfg << "\n";
1162 }
1164 {
1166  cfg["Number_of_ADC_bits"] = m_nbits;
1167  cfg["Exam_number_of_ticks_test"] = m_exam_nticks;
1168  cfg["Threshold_sigma_test"] = m_threshold_sigma;
1169  cfg["Threshold_fix"] = m_threshold_fix;
1170 
1171  return cfg;
1172 }
1173 
1174 
1175 
1177 {
1178  // No CMM's are produced.
1180 }
1181 
1182 // ADC Bit Shift problem ...
1184 {
1185  std::vector<int> counter(m_nbits,0);
1186  std::vector<int> s,s1(m_nbits,0);
1187  int nbin = m_exam_nticks;
1188 
1189  for (int i=0;i!=nbin;i++){
1190  int x = signal.at(i);
1191  s.clear();
1192  do
1193  {
1194  s.push_back( (x & 1));
1195  } while (x >>= 1);
1196  s.resize(m_nbits);
1197 
1198  for (int j=0;j!=m_nbits;j++){
1199  counter.at(j) += abs(s.at(j) - s1.at(j));
1200  }
1201  s1=s;
1202  }
1203 
1204  int nshift = 0;
1205  for (int i=0;i!=m_nbits;i++){
1206  if (counter.at(i) < nbin/2. - nbin/2. *sqrt(1./nbin) * m_threshold_sigma){
1207  nshift ++;
1208  }else{
1209  break;
1210  }
1211  }
1212 
1214  if (nshift!=0 && nshift < 11){
1215  WireCell::Waveform::BinRange ADC_bit_shifts;
1216  ADC_bit_shifts.first = nshift;
1217  ADC_bit_shifts.second = nshift;
1218 
1219  ret["ADCBitShift"][ch].push_back(ADC_bit_shifts);
1220 
1221  // do the correction ...
1222  const int nl = signal.size();
1223  std::vector<int> x(nl,0), x_orig(nl,0);
1224  for (int i=0;i!=nl;i++){
1225  x_orig[i] = signal.at(i);
1226  x[i] = signal.at(i);
1227  }
1228 
1229  std::set<int> fillings;
1230  int filling;
1231  int mean = 0;
1232  for (int i=0;i!=nl;i++){
1233  filling = WireCell::Bits::lowest_bits(x_orig[i], nshift);
1234  int y = WireCell::Bits::shift_right(x_orig[i], nshift, filling, 12);
1235  fillings.insert(filling);
1236  // cout << y << " ";
1237  // filling = lowest_bits(x[i], nshift);
1238  // filling = x[i] & int(pow(2, nshift)-1);
1239  x[i] = y;
1240  mean += x[i];
1241  }
1242  mean = mean/nl;
1243 
1244  int exp_diff = pow(2,m_nbits-nshift)*m_threshold_fix;
1245 
1246  // examine the results ...
1247  int prev1_bin_content = mean;
1248  int prev_bin_content = mean;
1249  int next_bin_content = mean;
1250  int next1_bin_content = mean;
1251  int curr_bin_content;
1252 
1253  for (int i=0;i<nl;i=i+1){
1254  curr_bin_content = x[i];
1255  // when to judge if one is likely bad ...
1256  if (abs(curr_bin_content-mean)>exp_diff &&
1257  (abs(curr_bin_content - prev_bin_content) > exp_diff ||
1258  abs(curr_bin_content - next_bin_content) > exp_diff)
1259  ){
1260  int exp_value = ( (2*prev_bin_content - prev1_bin_content) +
1261  (prev_bin_content + next_bin_content)/2. +
1262  (prev_bin_content * 2./3. + next1_bin_content/3.))/3.;
1263  for (auto it = fillings.begin(); it!=fillings.end(); it++){
1264  int y = WireCell::Bits::shift_right(x_orig[i], nshift, (*it), 12);
1265  // when to switch ...
1266  if (fabs(y-exp_value) < fabs(x[i] - exp_value)){
1267  x[i] = y;//hs->SetBinContent(i+1,y);
1268  }
1269  }
1270  }
1271 
1272  prev1_bin_content = prev_bin_content;
1273  prev_bin_content = x[i];
1274  if (i+2 < nl){
1275  next_bin_content = x[i+2];
1276  }else{
1277  next_bin_content = mean;
1278  }
1279  if (i+3 < nl){
1280  next1_bin_content = x[i+3];
1281  }else{
1282  next1_bin_content = mean;
1283  }
1284  }
1285 
1286  // change the histogram ...
1287  for (int i=0;i!=nl;i++){
1288  signal.at(i) = x[i];
1289  }
1290  }
1291  return ret;
1292 }
1293 
1294 
1295 
1296 
1297 Microboone::OneChannelStatus::OneChannelStatus(const std::string anode_tn, double threshold, int window, int nbins, double cut)
1298  : m_anode_tn(anode_tn)
1299  , m_threshold(threshold)
1300  , m_window(window)
1301  , m_nbins(nbins)
1302  , m_cut(cut)
1303 {
1304 }
1306 {
1307 }
1308 
1310 {
1311  m_threshold = get<double>(cfg, "Threshold", m_threshold);
1312  m_window = get<int>(cfg, "Window", m_window);
1313  m_nbins = get<double>(cfg, "Nbins", m_nbins);
1314  m_cut = get<double>(cfg, "Cut", m_cut);
1315 
1316  m_anode_tn = get(cfg, "anode", m_anode_tn);
1317  m_anode = Factory::find_tn<IAnodePlane>(m_anode_tn);
1318  if (!m_anode) {
1319  THROW(KeyError() << errmsg{"failed to get IAnodePlane: " + m_anode_tn});
1320  }
1321  //std::cerr << "OneChannelStatus: \n" << cfg << "\n";
1322 }
1324 {
1326  cfg["Threshold"] = m_threshold;
1327  cfg["Window"] = m_window;
1328  cfg["Nbins"] = m_nbins;
1329  cfg["Cut"] = m_cut;
1330  cfg["anode"] = m_anode_tn;
1331  return cfg;
1332 }
1333 
1335 {
1336 
1337 
1339 }
1340 
1341 // ADC Bit Shift problem ...
1343 {
1345  auto wpid = m_anode->resolve(ch);
1346  const int iplane = wpid.index();
1347  if (iplane!=2){ // not collection
1348  //std::cout << ch << std::endl;
1349  if (ID_lf_noisy(signal)){
1350  WireCell::Waveform::BinRange temp_chirped_bins;
1351  temp_chirped_bins.first = 0;
1352  temp_chirped_bins.second = signal.size();
1353  ret["lf_noisy"][ch].push_back(temp_chirped_bins);
1354  // std::cout << "lf noisy " << ch << std::endl;
1355  }
1356  }
1357  return ret;
1358 }
1359 
1360 
1362  // do something ...
1363  //std::pair<double,double> results = Derivations::CalcRMS(sig);
1364 
1365  //Waveform::mean_rms(sig);
1366  //double mean = results.first;
1367  //double rms = results.second;
1368 
1369  double mean = Waveform::percentile_binned(sig,0.5);
1370  double val1 = Waveform::percentile_binned(sig,0.5-0.34);
1371  double val2 = Waveform::percentile_binned(sig,0.5+0.34);
1372  double rms = sqrt((pow(val1-mean,2)+pow(val2-mean,2))/2.);
1373 
1374  double valid = 0 ;
1375  for (int i=0;i<int(sig.size());i++){
1376  if (sig.at(i)!=0){
1377  valid ++;
1378  }
1379  }
1380  if (!valid) {
1381  return false;
1382  }
1383 
1384 
1385 
1386  signal_t temp_sig = sig;
1387  for (int i=0;i<int(sig.size());i++){
1388  if (fabs(sig.at(i)-mean) > m_threshold * rms){
1389  for (int k=-m_window;k!=m_window;k++){
1390  if (k+i>=0&& k+i < int(sig.size()))
1391  temp_sig.at(k+i) = mean;
1392  }
1393  }
1394  }
1395 
1396  double content = 0;
1397  // for (int i=0;i!=temp_sig.size();i++){
1398  // temp_sig.at(i)=i;
1399  // }
1400  // do FFT
1401  Waveform::compseq_t sig_freq = Waveform::dft(temp_sig);
1402  for (int i=0;i!=m_nbins;i++){
1403  content += abs(sig_freq.at(i+1));
1404  }
1405 
1406  //std::cout << mean << " " << rms << " " << content << " " << valid << std::endl;
1407  // std::cout << m_threshold << " " << m_window << " " << m_nbins << " " << m_cut << std::endl;
1408 
1409  if (content/valid>m_cut) {
1410  // std::cerr << "OneChannelStatus::ID_lf_noisy: content=" << content << " valid=" << valid << " m_cut="<<m_cut<< std::endl;
1411  return true;
1412  }
1413 
1414  return false;
1415 
1416 
1417 }
1418 
1419 
1420 
1421 // Local Variables:
1422 // mode: c++
1423 // c-basic-offset: 4
1424 // End:
CoherentNoiseSub(const std::string &anode="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB")
Definition: Microboone.cxx:871
std::vector< std::vector< int > > SignalProtection(WireCell::Waveform::realseq_t &sig, const WireCell::Waveform::compseq_t &respec, int res_offset, int pad_f, int pad_b, float upper_decon_limit=0.02, float decon_lf_cutoff=0.08, float upper_adc_limit=15, float protection_factor=5.0, float min_adc_limit=50)
Definition: Microboone.cxx:232
static const double m
Definition: Units.h:79
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
Definition: Microboone.cxx:947
bool SignalFilter(WireCell::Waveform::realseq_t &sig)
Definition: Microboone.cxx:648
std::pair< int, int > BinRange
A half-open range of bins (from first bin to one past last bin)
Definition: Waveform.h:38
Sequence< real_t > realseq_t
Definition: Waveform.h:31
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:39
Waveform::realseq_t signal_t
double filter_low_loose(double freq)
Definition: Microboone.cxx:50
bool Subtract_WScaling(WireCell::IChannelFilter::channel_signals_t &chansig, const WireCell::Waveform::realseq_t &medians, const WireCell::Waveform::compseq_t &respec, int res_offset, std::vector< std::vector< int > > &rois, float upper_decon_limit1=0.08, float roi_min_max_ratio=0.8)
Definition: Microboone.cxx:55
std::string string
Definition: nybbler.cc:12
boost::error_info< struct tag_errmsg, std::string > errmsg
Definition: Exceptions.h:54
Val sum2(const Sequence< Val > &seq)
Return sum of square of all entries in sequence.
Definition: Waveform.h:184
constexpr T pow(T x)
Definition: pow.h:72
struct vector vector
std::pair< double, double > CalcRMS(const WireCell::Waveform::realseq_t &signal)
Definition: Derivations.cxx:7
cfg
Definition: dbjson.py:29
bool Chirp_raise_baseline(WireCell::Waveform::realseq_t &sig, int bin1, int bin2)
Definition: Microboone.cxx:615
double y
T abs(T value)
compseq_t dft(realseq_t seq)
Definition: Waveform.cxx:141
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
void shrink(Sequence< Val > &seq, const Sequence< Val > &other)
Shrink (divide) seq values by values from the other sequence.
Definition: Waveform.h:162
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
std::map< std::string, ChannelMasks > ChannelMaskMap
Collect channel masks by some label.
Definition: Waveform.h:59
void increase(Sequence< Val > &seq, Val scalar)
Increase (shift) sequence values by scalar.
Definition: Waveform.h:129
OneChannelStatus(const std::string anode_tn="AnodePlane", double threshold=3.5, int window=5, int nbins=250, double cut=14)
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
#define THROW(e)
Definition: Exceptions.h:25
virtual void configure(const WireCell::Configuration &config)
IConfigurable configuration interface.
Definition: Microboone.cxx:853
static int max(int a, int b)
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
Definition: Microboone.cxx:861
virtual void configure(const WireCell::Configuration &config)
Accept a configuration.
WireCell::Waveform::realseq_t CalcMedian(const WireCell::IChannelFilter::channel_signals_t &chansig)
Definition: Derivations.cxx:22
bool NoisyFilterAlg(WireCell::Waveform::realseq_t &spec, float min_rms, float max_rms)
Definition: Microboone.cxx:542
real_t median_binned(realseq_t &wave)
Definition: Waveform.cxx:81
bool RawAdapativeBaselineAlg(WireCell::Waveform::realseq_t &sig)
Definition: Microboone.cxx:693
bool RemoveFilterFlags(WireCell::Waveform::realseq_t &sig)
Definition: Microboone.cxx:821
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
Definition: Main.h:22
OneChannelNoise(const std::string &anode_tn="AnodePlane", const std::string &noisedb="OmniChannelNoiseDB")
Definition: Microboone.cxx:956
void scale(Sequence< Val > &seq, Val scalar)
Scale (multiply) sequence values by scalar.
Definition: Waveform.h:146
realseq_t idft(compseq_t spec)
Definition: Waveform.cxx:149
std::map< int, signal_t > channel_signals_t
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
Definition: Microboone.cxx:966
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
std::pair< double, double > mean_rms(const realseq_t &wave)
Definition: Waveform.cxx:24
Json::Value Configuration
Definition: Configuration.h:50
QTextStream & bin(QTextStream &s)
IChannelNoiseDatabase::pointer m_noisedb
Definition: Microboone.h:55
static bool * b
Definition: config.cpp:1043
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
virtual WireCell::Waveform::ChannelMaskMap apply(int channel, signal_t &sig) const
list x
Definition: train.py:276
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
double filter_low(double freq, double cut_off=0.08)
Definition: Microboone.cxx:41
int lowest_bits(int value, int n)
Definition: Bits.cxx:9
Sequence< complex_t > compseq_t
A complex-valued sequence, eg for discrete spectrum powers.
Definition: Waveform.h:34
float CalcRMSWithFlags(const WireCell::Waveform::realseq_t &sig)
Definition: Microboone.cxx:625
WIRECELL_FACTORY(mbCoherentNoiseSub, WireCell::SigProc::Microboone::CoherentNoiseSub, WireCell::IChannelFilter) WIRECELL_FACTORY(mbOneChannelNoise
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:15
std::string nl(std::size_t i=1)
static QCString * s
Definition: config.cpp:1042
Thrown when a wrong key or has been encountered.
Definition: Exceptions.h:43
int shift_right(int value, int n, int filling, int totalBit)
Definition: Bits.cxx:4
QTextStream & endl(QTextStream &s)
real_t percentile_binned(realseq_t &wave, real_t percentage)
Definition: Waveform.cxx:93
ADCBitShift(int nbits=12, int exam_nticks=500, double threshold_sigma=7.5, double threshold_fix=0.8)
double filter_time(double freq)
Definition: Microboone.cxx:35