All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Member Functions | Private Attributes | List of all members
pmtana::AlgoCFD Class Reference

#include <AlgoCFD.h>

Inheritance diagram for pmtana::AlgoCFD:
pmtana::PMTPulseRecoBase

Public Member Functions

 AlgoCFD (const std::string name="CFD")
 Default constructor. More...
 
 AlgoCFD (const fhicl::ParameterSet &pset, std::unique_ptr< pmtana::RiseTimeCalculatorBase > risetimecalculator=nullptr, const std::string name="CFD")
 Alternative ctor. More...
 
void Reset ()
 Implementation of AlgoCFD::reset() method. More...
 
- Public Member Functions inherited from pmtana::PMTPulseRecoBase
 PMTPulseRecoBase (const std::string name="noname")
 Default constructor with fhicl parameters. More...
 
virtual ~PMTPulseRecoBase ()=default
 Default destructor. More...
 
const std::string & Name () const
 Name getter. More...
 
bool Status () const
 Status getter. More...
 
bool Reconstruct (const pmtana::Waveform_t &, const pmtana::PedestalMean_t &, const pmtana::PedestalSigma_t &)
 
const pulse_paramGetPulse (size_t index=0) const
 
const pulse_param_arrayGetPulses () const
 A getter for the whole array of pulse_param struct object. More...
 
size_t GetNPulse () const
 A getter for the number of reconstructed pulses from the input waveform. More...
 

Protected Member Functions

bool RecoPulse (const pmtana::Waveform_t &, const pmtana::PedestalMean_t &, const pmtana::PedestalSigma_t &)
 Implementation of AlgoCFD::reco() method. More...
 
const std::map< unsigned, double > LinearZeroPointX (const std::vector< double > &trace)
 
- Protected Member Functions inherited from pmtana::PMTPulseRecoBase
bool Integral (const std::vector< short > &wf, double &result, size_t begin=0, size_t end=0) const
 
bool Derivative (const std::vector< short > &wf, std::vector< int32_t > &diff, size_t begin=0, size_t end=0) const
 
size_t Max (const std::vector< short > &wf, double &result, size_t begin=0, size_t end=0) const
 
size_t Min (const std::vector< short > &wf, double &result, size_t begin=0, size_t end=0) const
 

Private Attributes

float _F
 
int _D
 
double _peak_thresh
 
double _start_thresh
 
double _end_thresh
 

Additional Inherited Members

- Protected Attributes inherited from pmtana::PMTPulseRecoBase
pulse_param_array _pulse_v
 A container array of pulse_param struct objects to store (possibly multiple) reconstructed pulse(s). More...
 
pulse_param _pulse
 A subject pulse_param object to be filled with the last reconstructed pulse parameters. More...
 
std::unique_ptr
< pmtana::RiseTimeCalculatorBase
_risetime_calc_ptr = nullptr
 Tool for rise time calculation. More...
 

Detailed Description

This class implements threshold algorithm to AlgoCFD class.

Definition at line 35 of file AlgoCFD.h.

Constructor & Destructor Documentation

pmtana::AlgoCFD::AlgoCFD ( const std::string  name = "CFD")

Default constructor.

Definition at line 17 of file AlgoCFD.cxx.

19  //*********************************************************************
20  {}
then echo fcl name
PMTPulseRecoBase(const std::string name="noname")
Default constructor with fhicl parameters.
pmtana::AlgoCFD::AlgoCFD ( const fhicl::ParameterSet &  pset,
std::unique_ptr< pmtana::RiseTimeCalculatorBase risetimecalculator = nullptr,
const std::string  name = "CFD" 
)

Alternative ctor.

Definition at line 23 of file AlgoCFD.cxx.

28  //*********************************************************************
29  {
30 
31  _F = pset.get<float>("Fraction");
32  _D = pset.get<int> ("Delay");
33 
34  //_number_presample = pset.get<int> ("BaselinePreSample");
35  _peak_thresh = pset.get<double>("PeakThresh");
36  _start_thresh = pset.get<double>("StartThresh");
37  _end_thresh = pset.get<double>("EndThresh");
38 
39  _risetime_calc_ptr = std::move(risetimecalculator);
40 
41  Reset();
42 
43  }
void Reset()
Implementation of AlgoCFD::reset() method.
Definition: AlgoCFD.cxx:46
double _end_thresh
Definition: AlgoCFD.h:68
double _start_thresh
Definition: AlgoCFD.h:67
std::unique_ptr< pmtana::RiseTimeCalculatorBase > _risetime_calc_ptr
Tool for rise time calculation.
double _peak_thresh
Definition: AlgoCFD.h:66
then echo fcl name
PMTPulseRecoBase(const std::string name="noname")
Default constructor with fhicl parameters.

Member Function Documentation

const std::map< unsigned, double > pmtana::AlgoCFD::LinearZeroPointX ( const std::vector< double > &  trace)
protected

Definition at line 243 of file AlgoCFD.cxx.

243  {
244 
245  std::map<unsigned,double> crossing;
246 
247  //step through the trace and find where slope is POSITIVE across zero
248  for ( unsigned i = 0; i < trace.size() - 1; ++i) {
249 
250  auto si = ::pmtana::sign(trace.at(i));
251  auto sf = ::pmtana::sign(trace.at(i+1));
252 
253  if ( si == sf ) //no sign flip, no zero cross
254  continue;
255 
256  if ( sf < si ) //this is a negative slope, continue
257  continue;
258 
259  //calculate the crossing X based on linear interpolation bt two pts
260 
261  crossing[i] = (double) i - trace.at(i) * ( 1.0 / ( trace.at(i+1) - trace.at(i) ) );
262 
263  }
264 
265 
266  return crossing;
267 
268  }
int sign(double val)
Definition: UtilFunc.cxx:104
bool pmtana::AlgoCFD::RecoPulse ( const pmtana::Waveform_t wf,
const pmtana::PedestalMean_t mean_v,
const pmtana::PedestalSigma_t sigma_v 
)
protectedvirtual

Implementation of AlgoCFD::reco() method.

Implements pmtana::PMTPulseRecoBase.

Definition at line 53 of file AlgoCFD.cxx.

57  {
58 
59  Reset();
60 
61  std::vector<double> cfd; cfd.reserve(wf.size());
62 
63  // follow cfd procedure: invert waveform, multiply by constant fraction
64  // add to delayed waveform.
65  for (unsigned int k = 0; k < wf.size(); ++k) {
66 
67  auto delayed = -1.0 * _F * ( (float) wf.at(k) - mean_v.at(k) );
68 
69  if ((int)k < _D)
70 
71  cfd.push_back( delayed );
72 
73  else
74 
75  cfd.push_back(delayed + ( (float) wf.at(k - _D) - mean_v.at(k) ) );
76  }
77 
78 
79  // Get the zero point crossings, how can I tell which are meaningful?
80  // go to each crossing, see if waveform is above pedestal (high above pedestal)
81 
82  auto crossings = LinearZeroPointX(cfd);
83 
84  // lambda criteria to determine if inside pulse
85 
86  auto in_peak = [&wf,&sigma_v,&mean_v](int i, float thresh) -> bool
87  { return wf.at(i) > sigma_v.at(i) * thresh + mean_v.at(i); };
88 
89  // loop over CFD crossings
90  for(const auto& cross : crossings) {
91 
92  if( in_peak( cross.first, _peak_thresh) ) {
94 
95  int i = cross.first;
96 
97  //backwards
98  while ( in_peak(i, _start_thresh) ){
99  i--;
100  if ( i < 0 ) { i = 0; break; }
101  }
102  _pulse.t_start = i;
103 
104  //walk a little further backwards to see if we can get 5 low RMS
105  // while ( !in_peak(i,_start_thresh) ) {
106  // if (i == ( _pulse.t_start - _number_presample ) ) break;
107  // i--;
108  // if ( i < 0 ) { i = 0; break; }
109  // }
110 
111  // auto before_mean = double{0.0};
112 
113  // if ( _pulse.t_start - i > 0 )
114  // before_mean = std::accumulate(std::begin(mean_v) + i,
115  // std::begin(mean_v) + _pulse.t_start, 0.0) / ((double) (_pulse.t_start - i));
116 
117  i = _pulse.t_start + 1;
118 
119  //forwards
120  while ( in_peak(i,_end_thresh) ) {
121  i++;
122  if ( i > (int)(wf.size()) - 1 ) { i = (int)(wf.size()) - 1; break; }
123  }
124 
125  _pulse.t_end = i;
126 
127  // //walk a little further forwards to see if we can get 5 low RMS
128  // while ( !in_peak(i,_end_thresh) ) {
129  // if (i == ( _pulse.t_end + _number_presample ) ) break;
130  // i++;
131  // if ( i > wf.size() - 1 ) { i = wf.size() - 1; break; }
132  // }
133 
134  // auto after_mean = double{0.0};
135 
136  // if( i - _pulse.t_end > 0)
137  // after_mean = std::accumulate(std::begin(mean_v) + _pulse.t_end + 1,
138  // std::begin(mean_v) + i + 1, 0.0) / ((double) (i - _pulse.t_end));
139 
140 
141  //how to decide before or after? set before for now
142  //if ( wf.size() < 1500 ) //it's cosmic discriminator
143  //before_mean = mean_v.front();
144 
145  // if( after_mean <= 0 and before_mean <= 0 ) {
146  // std::cerr << "\033[93m<<" << __FUNCTION__ << ">>\033[00m Could not find good pedestal for CDF"
147  // << " both before_mean and after_mean are zero or less? Ignoring this crossing." << std::endl;
148  // continue;
149  // }
150 
151  //x
152 
153  auto start_ped = mean_v.at(_pulse.t_start);
154  auto end_ped = mean_v.at(_pulse.t_end);
155 
156  //just take the "smaller one"
157  _pulse.ped_mean = start_ped <= end_ped ? start_ped : end_ped;
158 
159  if(wf.size() < 50) _pulse.ped_mean = mean_v.front(); //is COSMIC DISCRIMINATOR
160 
161  auto it = std::max_element(std::begin(wf) + _pulse.t_start, std::begin(wf) + _pulse.t_end);
162 
163  _pulse.t_max = it - std::begin(wf);
164  _pulse.peak = *it - _pulse.ped_mean;
165  _pulse.t_cfdcross = cross.second;
166 
167  for(auto k = _pulse.t_start; k <= _pulse.t_end; ++k) {
168  auto a = wf.at(k) - _pulse.ped_mean;
169  if ( a > 0 ) _pulse.area += a;
170  }
171 
173  _pulse.t_rise = _risetime_calc_ptr->RiseTime(
174  {wf.begin()+_pulse.t_start, wf.begin()+_pulse.t_end},
175  {mean_v.begin()+_pulse.t_start, mean_v.begin()+_pulse.t_end},
176  true);
177 
178  _pulse_v.push_back(_pulse);
179  }
180 
181  }
182 
183  // Vic:
184  // Very close in time pulses have multiple CFD
185  // crossing points. Should we check that pulses now have
186  // some multiplicity? No lets just delete them.
187 
188  auto pulses_copy = _pulse_v;
189  _pulse_v.clear();
190 
191  std::unordered_map<unsigned,pulse_param> delta;
192 
193  //unsigned width = 0;
194  for( const auto& p : pulses_copy ) {
195 
196  if ( delta.count(p.t_start) ) {
197  if ( (p.t_end - p.t_start) > (delta[p.t_start].t_end - delta[p.t_start].t_start) )
198  delta[p.t_start] = p;
199  else
200  continue;
201  }
202  else {
203  delta[p.t_start] = p;
204  }
205  }
206 
207  for(const auto & p : delta)
208  _pulse_v.push_back(p.second);
209 
210 
211  //do the same now ensure t_final's are all unique
212  //width = 0;
213 
214  pulses_copy.clear();
215  pulses_copy = _pulse_v;
216 
217  _pulse_v.clear();
218  delta.clear();
219 
220  for( const auto& p : pulses_copy ) {
221 
222  if ( delta.count(p.t_end) ) {
223  if ( (p.t_end - p.t_start) > (delta[p.t_end].t_end - delta[p.t_end].t_start) )
224  delta[p.t_end] = p;
225  else
226  continue;
227  }
228  else {
229  delta[p.t_end] = p;
230  }
231  }
232 
233  for(const auto & p : delta)
234  _pulse_v.push_back(p.second);
235 
236  //there should be no overlapping pulses now...
237 
238  return true;
239 
240  }
const std::map< unsigned, double > LinearZeroPointX(const std::vector< double > &trace)
Definition: AlgoCFD.cxx:243
void Reset()
Implementation of AlgoCFD::reset() method.
Definition: AlgoCFD.cxx:46
pdgs p
Definition: selectors.fcl:22
double _end_thresh
Definition: AlgoCFD.h:68
pulse_param _pulse
A subject pulse_param object to be filled with the last reconstructed pulse parameters.
process_name gaushit a
double _start_thresh
Definition: AlgoCFD.h:67
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
std::unique_ptr< pmtana::RiseTimeCalculatorBase > _risetime_calc_ptr
Tool for rise time calculation.
double _peak_thresh
Definition: AlgoCFD.h:66
pdgs k
Definition: selectors.fcl:22
Vector cross(Vector const &a, Vector const &b)
Return cross product of two vectors.
pulse_param_array _pulse_v
A container array of pulse_param struct objects to store (possibly multiple) reconstructed pulse(s)...
void pmtana::AlgoCFD::Reset ( )
virtual

Implementation of AlgoCFD::reset() method.

Reimplemented from pmtana::PMTPulseRecoBase.

Definition at line 46 of file AlgoCFD.cxx.

48  {
50  }
virtual void Reset()
A method to be called event-wise to reset parameters.

Member Data Documentation

int pmtana::AlgoCFD::_D
private

Definition at line 63 of file AlgoCFD.h.

double pmtana::AlgoCFD::_end_thresh
private

Definition at line 68 of file AlgoCFD.h.

float pmtana::AlgoCFD::_F
private

Definition at line 62 of file AlgoCFD.h.

double pmtana::AlgoCFD::_peak_thresh
private

Definition at line 66 of file AlgoCFD.h.

double pmtana::AlgoCFD::_start_thresh
private

Definition at line 67 of file AlgoCFD.h.


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