AlgoSlidingWindow.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // AlgoSlidingWindow source
4 //
5 ////////////////////////////////////////////////////////////////////////
6 
8 
9 #include "AlgoSlidingWindow.h"
10 
11 namespace pmtana {
12 
13  //*********************************************************************
15  //*********************************************************************
16  {}
17 
18  //*********************************************************************
20  const fhicl::ParameterSet& pset,
21  //AlgoSlidingWindow::AlgoSlidingWindow(const ::fcllite::PSet &pset,
22  const std::string name)
23  : PMTPulseRecoBase(name)
24  //*********************************************************************
25  {
26  _positive = pset.get<bool>("PositivePolarity", true);
27 
28  _adc_thres = pset.get<float>("ADCThreshold");
29 
30  _tail_adc_thres = pset.get<float>("TailADCThreshold", _adc_thres);
31 
32  _end_adc_thres = pset.get<float>("EndADCThreshold");
33 
34  _nsigma = pset.get<float>("NSigmaThreshold");
35 
36  _tail_nsigma = pset.get<float>("TailNSigma", _nsigma);
37 
38  _end_nsigma = pset.get<float>("EndNSigmaThreshold");
39 
40  _verbose = pset.get<bool>("Verbosity");
41 
42  _num_presample = pset.get<size_t>("NumPreSample");
43 
44  _num_postsample = pset.get<size_t>("NumPostSample", 0);
45 
46  _min_width = pset.get<size_t>("MinPulseWidth", 0);
47 
48  Reset();
49  }
50 
51  //***************************************************************
52  void
54  //***************************************************************
55  {
57  }
58 
59  //***************************************************************
60  bool
62  const pmtana::PedestalMean_t& mean_v,
63  const pmtana::PedestalSigma_t& sigma_v)
64  //***************************************************************
65  {
66 
67  bool fire = false;
68 
69  bool in_tail = false;
70 
71  bool in_post = false;
72 
73  double pulse_tail_threshold = 0;
74 
75  double pulse_end_threshold = 0;
76 
77  double pulse_start_baseline = 0;
78 
79  int post_integration = 0;
80 
81  assert(wf.size() == mean_v.size() && wf.size() == sigma_v.size());
82 
83  //double threshold = ( _adc_thres > (_nsigma * _ped_rms) ? _adc_thres : (_nsigma * _ped_rms) );
84 
85  //threshold += _ped_mean;
86 
87  Reset();
88 
89  for (size_t i = 0; i < wf.size(); ++i) {
90 
91  double value = 0.;
92  if (_positive)
93  value = ((double)(wf[i])) - mean_v[i];
94  else
95  value = mean_v[i] - ((double)(wf[i]));
96 
97  float start_threshold = 0.;
98  float tail_threshold = 0.;
99  if (sigma_v[i] * _nsigma < _adc_thres)
100  start_threshold = _adc_thres;
101  else
102  start_threshold = sigma_v[i] * _nsigma;
103 
104  if (sigma_v[i] * _tail_nsigma < _tail_adc_thres)
105  tail_threshold = _tail_adc_thres;
106  else
107  tail_threshold = sigma_v[i] * _tail_nsigma;
108 
109  // End pulse if significantly high peak found (new pulse)
110  if ((!fire || in_tail || in_post) && ((double)value > start_threshold)) {
111 
112  // If there's a pulse, end it
113  if (in_tail) {
114  _pulse.t_end = i - 1;
115 
116  // Register if width is acceptable
117  if ((_pulse.t_end - _pulse.t_start) >= _min_width) _pulse_v.push_back(_pulse);
118 
120 
121  if (_verbose)
122  std::cout << "\033[93mPulse End\033[00m: "
123  << "baseline: " << mean_v[i] << " ... "
124  << " ... adc above: " << value << " T=" << i << std::endl;
125  }
126 
127  //
128  // Found a new pulse ... try to get a few samples prior to this
129  //
130 
131  pulse_tail_threshold = tail_threshold;
132  pulse_start_baseline = mean_v[i];
133 
134  pulse_end_threshold = 0.;
135  if (sigma_v[i] * _end_nsigma < _end_adc_thres)
136  pulse_end_threshold = _end_adc_thres;
137  else
138  pulse_end_threshold = sigma_v[i] * _end_nsigma;
139 
140  int buffer_num_index = 0;
141  if (_pulse_v.size())
142  buffer_num_index = (int)i - _pulse_v.back().t_end - 1;
143  else
144  buffer_num_index = std::min(_num_presample, i);
145 
146  if (buffer_num_index > (int)_num_presample) buffer_num_index = _num_presample;
147 
148  if (buffer_num_index < 0) {
149  std::cerr << "\033[95m[ERROR]\033[00m Logic error! Negative buffer_num_index..."
150  << std::endl;
151  throw std::exception();
152  }
153 
154  // If there's a pulse, end we where in in_post, end the previous pulse first
155  if (in_post) {
156  // Find were
157  _pulse.t_end = static_cast<int>(i) - buffer_num_index;
158  if (_pulse.t_end > 0) --_pulse.t_end; // leave a gap, if we can
159 
160  // Register if width is acceptable
161  if ((_pulse.t_end - _pulse.t_start) >= _min_width) _pulse_v.push_back(_pulse);
162 
164 
165  if (_verbose)
166  std::cout << "\033[93mPulse End\033[00m: new pulse starts during in_post: "
167  << "baseline: " << mean_v[i] << " ... "
168  << " ... adc above: " << value << " T=" << i << std::endl;
169  }
170 
171  _pulse.t_start = i - buffer_num_index;
172  _pulse.ped_mean = pulse_start_baseline;
173  _pulse.ped_sigma = sigma_v[i];
174 
175  for (size_t pre_index = _pulse.t_start; pre_index < i; ++pre_index) {
176 
177  double pre_adc = wf[pre_index];
178  if (_positive)
179  pre_adc -= pulse_start_baseline;
180  else
181  pre_adc = pulse_start_baseline - pre_adc;
182 
183  if (pre_adc > 0.) _pulse.area += pre_adc;
184  }
185 
186  if (_verbose)
187  std::cout << "\033[93mPulse Start\033[00m: "
188  << "baseline: " << mean_v[i] << " ... threshold: " << start_threshold
189  << " ... adc above baseline: " << value << " ... pre-adc sum: " << _pulse.area
190  << " T=" << i << std::endl;
191 
192  fire = true;
193  in_tail = false;
194  in_post = false;
195  }
196 
197  if (fire && value < pulse_tail_threshold) {
198  fire = false;
199  in_tail = true;
200  in_post = false;
201  }
202 
203  if ((fire || in_tail || in_post) && _verbose) {
204  std::cout << (fire ? "\033[93mPulsing\033[00m: " : "\033[93mIn-tail\033[00m: ")
205  << "baseline: " << mean_v[i] << " std: " << sigma_v[i]
206  << " ... adc above baseline " << value << " T=" << i << std::endl;
207  }
208 
209  if ((fire || in_tail) && value < pulse_end_threshold) {
210  in_post = true;
211  fire = in_tail = false;
212  post_integration = _num_postsample;
213  }
214 
215  if (in_post && post_integration < 1) {
216  // Found the end of a pulse
217  _pulse.t_end = i - 1;
218 
219  // Register if width is acceptable
220  if ((_pulse.t_end - _pulse.t_start) >= _min_width) _pulse_v.push_back(_pulse);
221 
222  if (_verbose)
223  std::cout << "\033[93mPulse End\033[00m: "
224  << "baseline: " << mean_v[i] << " ... adc: " << value << " T=" << i
225  << " ... area sum " << _pulse.area << std::endl;
226 
228 
229  fire = false;
230  in_tail = false;
231  in_post = false;
232  }
233 
234  if (fire || in_tail || in_post) {
235 
236  //_pulse.area += ((double)value - (double)mean_v[i]);
237  _pulse.area += value;
238 
239  if (_pulse.peak < value) {
240 
241  // Found a new maximum
242  _pulse.peak = value;
243 
244  _pulse.t_max = i;
245  }
246 
247  if (in_post) --post_integration;
248  }
249  }
250 
251  if (fire || in_tail || in_post) {
252 
253  // Take care of a pulse that did not finish within the readout window.
254 
255  fire = false;
256  in_tail = false;
257 
258  _pulse.t_end = wf.size() - 1;
259 
260  // Register if width is acceptable
261  if ((_pulse.t_end - _pulse.t_start) >= _min_width) _pulse_v.push_back(_pulse);
262 
264  }
265 
266  return true;
267  }
268 
269 }
static QCString name
Definition: declinfo.cpp:673
std::vector< double > PedestalSigma_t
virtual void Reset()
A method to be called event-wise to reset parameters.
float _nsigma
A variable holder for a multiplicative factor for the pedestal standard deviation to define the thres...
std::string string
Definition: nybbler.cc:12
AlgoSlidingWindow(const std::string name="SlidingWindow")
Default constructor.
bool RecoPulse(const pmtana::Waveform_t &, const pmtana::PedestalMean_t &, const pmtana::PedestalSigma_t &)
Implementation of AlgoSlidingWindow::reco() method.
pulse_param _pulse
A subject pulse_param object to be filled with the last reconstructed pulse parameters.
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::vector< short > Waveform_t
bool _positive
A boolean to set waveform positive/negative polarity.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Class definition file of AlgoSlidingWindow.
void Reset()
Implementation of AlgoSlidingWindow::reset() method.
float _adc_thres
A variable holder for a user-defined absolute ADC threshold value.
std::vector< double > PedestalMean_t
size_t _min_width
A variable holder to ensure the minimum pulse width.
pulse_param_array _pulse_v
A container array of pulse_param struct objects to store (possibly multiple) reconstructed pulse(s)...
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)