Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
pmtana::PedAlgoRmsSlider Class Reference

#include <PedAlgoRmsSlider.h>

Inheritance diagram for pmtana::PedAlgoRmsSlider:
pmtana::PMTPedestalBase

Public Member Functions

 PedAlgoRmsSlider (const std::string name="PedRmsSlider")
 Default constructor. More...
 
 PedAlgoRmsSlider (const fhicl::ParameterSet &pset, const std::string name="PedRmsSlider")
 Alternative ctor. More...
 
void PrintInfo ()
 Print settings. More...
 
- Public Member Functions inherited from pmtana::PMTPedestalBase
 PMTPedestalBase (std::string name="noname")
 Default constructor. More...
 
virtual ~PMTPedestalBase ()
 Default destructor. More...
 
const std::stringName () const
 Name getter. More...
 
bool Evaluate (const pmtana::Waveform_t &wf)
 Method to compute a pedestal. More...
 
double Mean (size_t i) const
 Getter of the pedestal mean value. More...
 
double Sigma (size_t i) const
 Getter of the pedestal standard deviation. More...
 
const pmtana::PedestalMean_tMean () const
 Getter of the pedestal mean value. More...
 
const pmtana::PedestalSigma_tSigma () const
 Getter of the pedestal standard deviation. More...
 

Protected Member Functions

bool ComputePedestal (const pmtana::Waveform_t &wf, pmtana::PedestalMean_t &mean_v, pmtana::PedestalSigma_t &sigma_v)
 Method to compute a pedestal of the input waveform using "nsample" ADC samples from "start" index. More...
 
- Protected Member Functions inherited from pmtana::PMTPedestalBase
virtual bool ComputePedestal (const ::pmtana::Waveform_t &wf, pmtana::PedestalMean_t &mean_v, pmtana::PedestalSigma_t &sigma_v)=0
 

Private Member Functions

double CalcMean (const std::vector< double > &wf, size_t start, size_t nsample)
 Returns the mean of the elements of the vector from start to start+nsample. More...
 
double CalcStd (const std::vector< double > &wf, const double ped_mean, size_t start, size_t nsample)
 Returns the std of the elements of the vector from start to start+nsample. More...
 
bool CheckSanity (pmtana::PedestalMean_t &mean_v, pmtana::PedestalSigma_t &sigma_v)
 Checks the sanity of the estimated pedestal, returns false if not sane. More...
 

Private Attributes

size_t _sample_size
 How many samples are used to calculate local rms and mean. More...
 
double _threshold
 Threshold applied to local rms to claim a pulse. More...
 
float _max_sigma
 Max sigma to consider adc as 'sane'. More...
 
float _ped_range_max
 Max value of adc to consider adc as 'sane'. More...
 
float _ped_range_min
 Min value of adc to consider adc as 'sane'. More...
 
bool _verbose
 For debugging. More...
 
int _n_wf_to_csvfile
 If greater than zero saves firsts waveforms with pedestal to csv file. More...
 
int _wf_saved = 0
 
int _num_presample
 number of ADCs to sample before the gap More...
 
int _num_postsample
 number of ADCs to sample after the gap More...
 
std::ofstream _csvfile
 

Detailed Description

A class that calculates pedestal mean & standard deviation (here and elsewhere called as "RMS").

Definition at line 32 of file PedAlgoRmsSlider.h.

Constructor & Destructor Documentation

pmtana::PedAlgoRmsSlider::PedAlgoRmsSlider ( const std::string  name = "PedRmsSlider")

Default constructor.

Definition at line 19 of file PedAlgoRmsSlider.cxx.

21  //*****************************************************************
22  {
23  srand(static_cast<unsigned int>(time(0)));
24  }
static QCString name
Definition: declinfo.cpp:673
PMTPedestalBase(std::string name="noname")
Default constructor.
pmtana::PedAlgoRmsSlider::PedAlgoRmsSlider ( const fhicl::ParameterSet pset,
const std::string  name = "PedRmsSlider" 
)

Alternative ctor.

Definition at line 27 of file PedAlgoRmsSlider.cxx.

30  //############################################################
31  {
32 
33  _sample_size = pset.get<size_t>("SampleSize", 7 );
34  _threshold = pset.get<double>("Threshold", 0.6 );
35  _max_sigma = pset.get<float> ("MaxSigma", 0.5 );
36  _ped_range_max = pset.get<float> ("PedRangeMax", 2150 );
37  _ped_range_min = pset.get<float> ("PedRangeMin", 100 );
38  _num_presample = pset.get<int> ("NumPreSample", 0 );
39  _num_postsample = pset.get<int> ("NumPostSample", 0 );
40  _verbose = pset.get<bool> ("Verbose", true );
41  _n_wf_to_csvfile = pset.get<int> ("NWaveformsToFile", 12 );
42 
43  if (_n_wf_to_csvfile > 0) {
44  _csvfile.open ("wf_pedalgormsslider.csv", std::ofstream::out | std::ofstream::trunc);
45  _csvfile << "n,time,wf,wf_ped_mean,wf_ped_rms" << std::endl;
46  }
47 
48  }
static QCString name
Definition: declinfo.cpp:673
float _ped_range_min
Min value of adc to consider adc as &#39;sane&#39;.
PMTPedestalBase(std::string name="noname")
Default constructor.
int _num_postsample
number of ADCs to sample after the gap
float _max_sigma
Max sigma to consider adc as &#39;sane&#39;.
int _num_presample
number of ADCs to sample before the gap
double _threshold
Threshold applied to local rms to claim a pulse.
float _ped_range_max
Max value of adc to consider adc as &#39;sane&#39;.
T get(std::string const &key) const
Definition: ParameterSet.h:271
int _n_wf_to_csvfile
If greater than zero saves firsts waveforms with pedestal to csv file.
size_t _sample_size
How many samples are used to calculate local rms and mean.
bool _verbose
For debugging.
QTextStream & endl(QTextStream &s)

Member Function Documentation

double pmtana::PedAlgoRmsSlider::CalcMean ( const std::vector< double > &  wf,
size_t  start,
size_t  nsample 
)
private

Returns the mean of the elements of the vector from start to start+nsample.

Definition at line 62 of file PedAlgoRmsSlider.cxx.

64  {
65  if(!nsample) nsample = wf.size();
66  if(start > wf.size() || (start+nsample) > wf.size())
67  throw OpticalRecoException("Invalid start/end index!");
68 
69  double sum = std::accumulate(wf.begin()+start,wf.begin()+start+nsample,0.0);
70 
71  sum /= ((double)nsample);
72 
73  return sum;
74  }
double pmtana::PedAlgoRmsSlider::CalcStd ( const std::vector< double > &  wf,
const double  ped_mean,
size_t  start,
size_t  nsample 
)
private

Returns the std of the elements of the vector from start to start+nsample.

Definition at line 77 of file PedAlgoRmsSlider.cxx.

79  {
80  if(!nsample) nsample = wf.size();
81  if(start > wf.size() || (start+nsample) > wf.size())
82  throw OpticalRecoException("Invalid start/end index!");
83 
84  double sigma = 0;
85 
86  for(size_t index=start; index < (start+nsample); ++index){
87  sigma += pow( (wf[index] - ped_mean), 2 );
88  }
89 
90  sigma = sqrt(sigma/((double)(nsample)));
91 
92  return sigma;
93  }
constexpr T pow(T x)
Definition: pow.h:72
bool pmtana::PedAlgoRmsSlider::CheckSanity ( pmtana::PedestalMean_t mean_v,
pmtana::PedestalSigma_t sigma_v 
)
private

Checks the sanity of the estimated pedestal, returns false if not sane.

Definition at line 411 of file PedAlgoRmsSlider.cxx.

413  {
414 
415  float best_sigma = 1.1e9;
416  size_t best_sigma_index = 0;
417  size_t num_good_adc = 0;
418 
419  for(size_t i=0; i<sigma_v.size(); ++i) {
420  // Only consider adcs which mean is in the allowed range
421  auto const& mean = mean_v[i];
422 
423  if( mean < _ped_range_min || mean > _ped_range_max ) continue;
424 
425  auto const& sigma = sigma_v[i];
426  if(sigma < best_sigma) {
427  best_sigma = sigma;
428  best_sigma_index = i;
429  }
430 
431  if(sigma < _max_sigma) num_good_adc += 1;
432  }
433 
434 
435  if( num_good_adc < 1 ) {
436  std::cerr << "\033[93m<<" << __FUNCTION__ << ">>\033[00m Could not find good pedestal at all..." << std::endl;
437  return false;
438  }
439 
440  // If not enough # of good mean indices, use the best guess within this waveform
441  if(best_sigma > _max_sigma || num_good_adc < 3) {
442 
443  if(_verbose) {
444  std::cout << "\033[93mPedAlgoRmsSlider\033[00m: Not enough number of good mean indices."
445  << "Using the best guess within this waveform."
446  << std::endl;
447  }
448 
449  for(size_t i=0; i<mean_v.size(); ++i) {
450  mean_v[i] = mean_v [ best_sigma_index ];
451  sigma_v[i] = sigma_v [ best_sigma_index ];
452  }
453  }
454 
455  return true;
456 
457  }
float _max_sigma
Max sigma to consider adc as &#39;sane&#39;.
float _ped_range_max
Max value of adc to consider adc as &#39;sane&#39;.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:13
bool _verbose
For debugging.
QTextStream & endl(QTextStream &s)
bool pmtana::PedAlgoRmsSlider::ComputePedestal ( const pmtana::Waveform_t wf,
pmtana::PedestalMean_t mean_v,
pmtana::PedestalSigma_t sigma_v 
)
protected

Method to compute a pedestal of the input waveform using "nsample" ADC samples from "start" index.

Definition at line 96 of file PedAlgoRmsSlider.cxx.

100  {
101 
102  if (_verbose)
103  this->PrintInfo();
104 
105  if (wf.size() <= (_sample_size * 2))
106  return false;
107 
108  // Prepare output
109  mean_v.resize (wf.size(), 0);
110  sigma_v.resize(wf.size(), 0);
111 
112 
113 
114 
115  // **********
116  // To start, set the pedestal equal to
117  // the wf itself
118  // **********
119 
120  pmtana::PedestalMean_t mean_temp_v;
121  mean_temp_v.resize( wf.size(), 0);
122 
123  for(size_t i=0; i< wf.size(); ++i) {
124  mean_temp_v[i] = wf[i];
125  sigma_v[i] = 0;
126  }
127 
128 
129 
130 
131 
132  // **********
133  // Now look for rms variations
134  // and change the mean and rms accordingly
135  // **********
136  int last_good_index = -1;
137  double local_mean, local_rms;
138  std::vector<double> local_mean_v(wf.size(),-1.);
139  std::vector<double> local_sigma_v(wf.size(),-1.);
140 
141  for (size_t i = 0; i < wf.size() - _sample_size; i++) {
142 
143  local_mean = mean(wf, i, _sample_size);
144  local_rms = std(wf, local_mean, i, _sample_size);
145 
146  if(_verbose) std::cout << "\033[93mPedAlgoRmsSlider\033[00m: i " << i
147  << " local_mean: " << local_mean
148  << " local_rms: " << local_rms << std::endl;
149 
150  if (local_rms < _threshold) {
151 
152  local_mean_v[i] = local_mean;
153  local_sigma_v[i] = local_rms;
154 
155  if(_verbose)
156  std::cout << "\033[93mBelow threshold\033[00m: "
157  << "at i " << i
158  << " last good index was: " << last_good_index
159  << std::endl;
160 
161  }
162  }
163 
164  // find the gaps (regions to be interpolated
165  last_good_index = -1;
166  std::vector<bool> ped_interapolated(wf.size(),false);
167  for(size_t i=0; i < wf.size() - _sample_size; i++) {
168 
169  if(local_mean_v[i] > -0.1) {
170  // good pedestal!
171 
172  if( ( last_good_index + 1 ) < (int)i ) {
173  // finished the gap. try interpolation
174  // 0) find where to start/end interpolation
175  int start_tick = last_good_index;
176  int end_tick = i;
177  int start_bound = std::max(last_good_index - _num_presample, 0);
178  int end_bound = std::min(i + _num_postsample, (int)(wf.size()) - _sample_size);
179  for(int j=start_tick; j>=start_bound; --j) {
180  if(local_mean_v[j] < 0) continue;
181  start_tick = j;
182  }
183  for(int j=end_tick; j<=end_bound; ++j) {
184  if(local_mean_v[j] < 0) continue;
185  end_tick = j;
186  }
187 
188  //this should become generic interpolation function, for now lets leave.
189  float slope = (local_mean_v[end_tick] - local_mean_v[start_tick]) / (float(end_tick - start_tick));
190 
191  for(int j = start_tick + 1; j < end_tick; ++j) {
192  mean_temp_v[j] = slope * ( float(j - start_tick) ) + local_mean_v[start_tick];
193  // for sigma, put either the sigma in the region before the pulse or
194  // after the pulse, depending on which one if != 0. If both are !=0 put the one after
195  // the pulse (just default), if both are zero then put zero
196  sigma_v[j] = (local_sigma_v[end_tick] != 0 ? local_sigma_v[end_tick] : local_sigma_v[start_tick]); // todo: fluctuate baseline
197  ped_interapolated[j] = true;
198  }
199  }
200 
201  last_good_index = i;
202  }
203  }
204 
205  /*
206 
207  for (size_t i = 0; i < wf.size() - _sample_size; i++) {
208 
209  local_mean = mean(wf, i, _sample_size);
210  local_rms = std(wf, local_mean, i, _sample_size);
211 
212  if(_verbose) std::cout << "\033[93mPedAlgoRmsSlider\033[00m: i " << i << " local_mean: " << local_mean << " local_rms: " << local_rms << std::endl;
213 
214  if (local_rms < _threshold) {
215 
216  local_mean_v[i] = local_mean;
217  local_sigma_v[i] = local_sigma;
218 
219  if(_verbose)
220  std::cout << "\033[93mBelow threshold\033[00m: "
221  << "at i " << i
222  << " last good index was: " << last_good_index
223  << std::endl;
224 
225  if(last_good_index<0) {
226  last_good_index = (int)i;
227  last_local_mean = local_mean;
228  last_local_rms = local_rms;
229  continue;
230  }
231 
232 
233  if( ( last_good_index + 1 ) < (int)i ) {
234 
235  //this should become generic interpolation function, for now lets leave.
236  float slope = (local_mean - last_local_mean) / (float(i - last_good_index));
237 
238  for(size_t j = last_good_index + 1; j < i && j < wf.size(); ++j) {
239  mean_temp_v.at(j) = slope * ( float(j - last_good_index) ) + mean_temp_v.at(last_good_index);
240  // for sigma, put either the sigma in the region before the pulse or
241  // after the pulse, depending on which one if != 0. If both are !=0 put the one after
242  // the pulse (just default), if both are zero then put zero
243  sigma_v.at(j) = (local_rms != 0 ? local_rms : last_local_rms); // todo: fluctuate baseline
244  ped_interapolated.at(j) = true;
245  }
246  }
247 
248  // record this mean & rms as good mean value
249  last_good_index = i;
250  last_local_mean = local_mean;
251  last_local_rms = local_rms;
252  // if _num_postsample is specified, go back in time to look for it
253  if(_num_postsample >0 && (i>_num_postsample)) {
254  int loop_start = std::max(((int)i) - _num_postsample, 0);
255  for(int j=loop_start; j>=0; --j) {
256  if(local_mean_v[j] <0) continue;
257  last_good_index = j;
258  last_local_mean = local_mean_v[j];
259  last_local_rms = local_sigma_v[j];
260  break;
261  }
262  }
263  }
264 
265 
266  }
267  */
268 
269 
270 
271  // **********
272  // Now look at special cases, if wf starts or
273  // ends with a pulse
274  // **********
275 
276  // At start
277 
278  bool end_found = false;
279 
280  local_mean = mean(wf, 0, _sample_size);
281  local_rms = std(wf, local_mean, 0, _sample_size);
282 
283  if (local_rms >= _threshold) {
284 
285  for (size_t i = 1; i < wf.size() - _sample_size; i++) {
286 
287  local_mean = mean(wf, i, _sample_size);
288  local_rms = std(wf, local_mean, i, _sample_size);
289 
290  if (local_rms < _threshold) {
291 
292  end_found = true;
293 
294  for (size_t j = 0; j < i; j++){
295  mean_temp_v[j] = local_mean;
296  sigma_v[j] = local_rms;
297  ped_interapolated[j] = true;
298  }
299  break;
300  }
301  }
302 
303  if (!end_found) {
304  std::cerr <<"\033[93m<<" << __FUNCTION__ << ">>\033[00m Could not find good pedestal for CDF"
305  << "There is pulse on first sample and baseline never went back down. Returning false here.";
306  return false;
307  }
308 
309  }
310 
311 
312  // At end
313 
314  bool start_found = false;
315 
316  local_mean = mean(wf, wf.size()-1-_sample_size, _sample_size);
317  local_rms = std(wf, local_mean, wf.size()-1-_sample_size, _sample_size);
318 
319  if (local_rms >= _threshold) {
320 
321  size_t i = wf.size() - 1 - _sample_size;
322  while (i-- > 0) {
323  local_mean = mean(wf, i, _sample_size);
324  local_rms = std(wf, local_mean, i, _sample_size);
325 
326  if (local_rms < _threshold) {
327 
328  start_found = true;
329 
330  for (size_t j = wf.size()-1; j > i; j--){
331  mean_temp_v[j] = local_mean;
332  sigma_v[j] = local_rms;
333  ped_interapolated[j] = true;
334  }
335  break;
336  }
337  }
338 
339  if (!start_found) {
340  std::cerr <<"\033[93m<<" << __FUNCTION__ << ">>\033[00m Could not find good pedestal for CDF"
341  << "There is pulse on last sample and baseline never went back down. Returning false here.";
342  return false;
343  }
344 
345  }
346 
347 
348 
349 
350 
351 
352 
353  // **********
354  // Now smooth it to estimate the final pedestal
355  // **********
356 
357  const size_t window_size = _sample_size*2;
358 
359  // middle mean
360  for(size_t i=0; i< mean_temp_v.size(); ++i) {
361 
362  if( i < _sample_size || i >= (wf.size() - _sample_size) ) continue;
363 
364  mean_v[i] = this->CalcMean (mean_temp_v,i - _sample_size,window_size);
365  if(!ped_interapolated[i]){
366  sigma_v[i] = this->CalcStd (mean_temp_v,mean_v[i],i - _sample_size,window_size);
367  }
368  }
369 
370  // front mean
371  for(size_t i=0; i<_sample_size; ++i) {
372 
373  mean_v[i] = mean_v [_sample_size];
374  if(!ped_interapolated[i]){
375  sigma_v[i] = sigma_v[_sample_size];
376  }
377  }
378 
379  // tail mean
380  for(size_t i=(mean_temp_v.size() - _sample_size); i<mean_temp_v.size(); ++i) {
381 
382  mean_v[i] = mean_v [wf.size() - _sample_size -1];
383  if(!ped_interapolated[i]){
384  sigma_v[i] = sigma_v[wf.size() - _sample_size -1];
385  }
386  }
387 
388 
389 
390 
391  // Save to file
392  if (_wf_saved + 1 <= _n_wf_to_csvfile) {
393  _wf_saved ++;
394  for (size_t i = 0; i < wf.size(); i++) {
395  _csvfile << _wf_saved-1 << "," << i << "," << wf[i] << "," << mean_v[i] << "," << sigma_v[i] << std::endl;
396  }
397  }
398 
399 
400  bool is_sane = this->CheckSanity(mean_v, sigma_v);
401 
402  return is_sane;
403 
404  }
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
void PrintInfo()
Print settings.
bool CheckSanity(pmtana::PedestalMean_t &mean_v, pmtana::PedestalSigma_t &sigma_v)
Checks the sanity of the estimated pedestal, returns false if not sane.
int _num_postsample
number of ADCs to sample after the gap
int _num_presample
number of ADCs to sample before the gap
double CalcStd(const std::vector< double > &wf, const double ped_mean, size_t start, size_t nsample)
Returns the std of the elements of the vector from start to start+nsample.
double _threshold
Threshold applied to local rms to claim a pulse.
int _n_wf_to_csvfile
If greater than zero saves firsts waveforms with pedestal to csv file.
size_t _sample_size
How many samples are used to calculate local rms and mean.
static int max(int a, int b)
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Definition: UtilFunc.cxx:13
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
double CalcMean(const std::vector< double > &wf, size_t start, size_t nsample)
Returns the mean of the elements of the vector from start to start+nsample.
std::vector< double > PedestalMean_t
bool _verbose
For debugging.
QTextStream & endl(QTextStream &s)
void pmtana::PedAlgoRmsSlider::PrintInfo ( )

Print settings.

Definition at line 51 of file PedAlgoRmsSlider.cxx.

53  {
54  std::cout << "PedAlgoRmsSlider setting:"
55  << "\n\t SampleSize: " << _sample_size
56  << "\n\t Threshold: " << _threshold
57  << "\n\t Verbose: " << _verbose
58  << "\n\t NWaveformsToFile: " << _n_wf_to_csvfile << std::endl;
59  }
double _threshold
Threshold applied to local rms to claim a pulse.
int _n_wf_to_csvfile
If greater than zero saves firsts waveforms with pedestal to csv file.
size_t _sample_size
How many samples are used to calculate local rms and mean.
bool _verbose
For debugging.
QTextStream & endl(QTextStream &s)

Member Data Documentation

std::ofstream pmtana::PedAlgoRmsSlider::_csvfile
private

Definition at line 67 of file PedAlgoRmsSlider.h.

float pmtana::PedAlgoRmsSlider::_max_sigma
private

Max sigma to consider adc as 'sane'.

Definition at line 58 of file PedAlgoRmsSlider.h.

int pmtana::PedAlgoRmsSlider::_n_wf_to_csvfile
private

If greater than zero saves firsts waveforms with pedestal to csv file.

Definition at line 63 of file PedAlgoRmsSlider.h.

int pmtana::PedAlgoRmsSlider::_num_postsample
private

number of ADCs to sample after the gap

Definition at line 66 of file PedAlgoRmsSlider.h.

int pmtana::PedAlgoRmsSlider::_num_presample
private

number of ADCs to sample before the gap

Definition at line 65 of file PedAlgoRmsSlider.h.

float pmtana::PedAlgoRmsSlider::_ped_range_max
private

Max value of adc to consider adc as 'sane'.

Definition at line 59 of file PedAlgoRmsSlider.h.

float pmtana::PedAlgoRmsSlider::_ped_range_min
private

Min value of adc to consider adc as 'sane'.

Definition at line 60 of file PedAlgoRmsSlider.h.

size_t pmtana::PedAlgoRmsSlider::_sample_size
private

How many samples are used to calculate local rms and mean.

Definition at line 55 of file PedAlgoRmsSlider.h.

double pmtana::PedAlgoRmsSlider::_threshold
private

Threshold applied to local rms to claim a pulse.

Definition at line 56 of file PedAlgoRmsSlider.h.

bool pmtana::PedAlgoRmsSlider::_verbose
private

For debugging.

Definition at line 62 of file PedAlgoRmsSlider.h.

int pmtana::PedAlgoRmsSlider::_wf_saved = 0
private

Definition at line 64 of file PedAlgoRmsSlider.h.


The documentation for this class was generated from the following files: