LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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...
 
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)
 
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
 

Protected Attributes

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...
 

Private Attributes

float _F
 
int _D
 
double _peak_thresh
 
double _start_thresh
 
double _end_thresh
 

Detailed Description

This class implements threshold algorithm to AlgoCFD class.

Definition at line 36 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.

17  : PMTPulseRecoBase(name)
18  //*********************************************************************
19  {}
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 22 of file AlgoCFD.cxx.

References _D, _end_thresh, _F, _peak_thresh, pmtana::PMTPulseRecoBase::_risetime_calc_ptr, _start_thresh, fhicl::ParameterSet::get(), and Reset().

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

Member Function Documentation

bool pmtana::PMTPulseRecoBase::Derivative ( const std::vector< short > &  wf,
std::vector< int32_t > &  diff,
size_t  begin = 0,
size_t  end = 0 
) const
protectedinherited

A method to compute derivative, which is a simple subtraction of previous ADC sample from each sample. The result is stored in the input "diff" reference vector which is int32_t type as a derivative could be negative.

Definition at line 121 of file PMTPulseRecoBase.cxx.

References util::begin(), pmtana::CheckIndex(), and util::end().

126  {
127 
128  if (CheckIndex(wf, begin, end)) {
129 
130  diff.clear();
131  diff.reserve(end - begin);
132 
133  for (size_t index = begin; index <= end; ++index)
134 
135  diff.push_back(wf.at(index + 1) - wf.at(index));
136 
137  return true;
138  }
139 
140  return false;
141  }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
bool CheckIndex(const std::vector< short > &wf, const size_t &begin, size_t &end)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
size_t pmtana::PMTPulseRecoBase::GetNPulse ( ) const
inlineinherited

A getter for the number of reconstructed pulses from the input waveform.

Definition at line 101 of file PMTPulseRecoBase.h.

Referenced by opdet::LEDCalibrationAna::analyze().

101 { return _pulse_v.size(); };
pulse_param_array _pulse_v
A container array of pulse_param struct objects to store (possibly multiple) reconstructed pulse(s)...
const pulse_param & pmtana::PMTPulseRecoBase::GetPulse ( size_t  index = 0) const
inherited

A getter for the pulse_param struct object. Reconstruction algorithm may have more than one pulse reconstructed from an input waveform. Note you must, accordingly, provide an index key to specify which pulse_param object to be retrieved.

Definition at line 74 of file PMTPulseRecoBase.cxx.

References pmtana::PMTPulseRecoBase::_pulse_v.

Referenced by opdet::LEDCalibrationAna::analyze().

76  {
77 
78  if (index >= _pulse_v.size()) {
79 
80  std::cerr << "\033[93m"
81  << "Invalid pulse index: " << index << "\033[00m" << std::endl;
82 
83  throw std::exception();
84  }
85 
86  else
87  return _pulse_v.at(index);
88  }
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
const pulse_param_array & pmtana::PMTPulseRecoBase::GetPulses ( ) const
inherited

A getter for the whole array of pulse_param struct object.

Definition at line 91 of file PMTPulseRecoBase.cxx.

References pmtana::PMTPulseRecoBase::_pulse_v.

Referenced by opdet::RunHitFinder().

93  {
94  return _pulse_v;
95  }
pulse_param_array _pulse_v
A container array of pulse_param struct objects to store (possibly multiple) reconstructed pulse(s)...
bool pmtana::PMTPulseRecoBase::Integral ( const std::vector< short > &  wf,
double &  result,
size_t  begin = 0,
size_t  end = 0 
) const
protectedinherited

A method to integrate an waveform from index "begin" to the "end". The result is filled in "result" reference. If the "end" is default (=0), then "end" is set to the last index of the waveform.

Definition at line 98 of file PMTPulseRecoBase.cxx.

References util::begin(), pmtana::CheckIndex(), and util::end().

Referenced by pmtana::AlgoFixedWindow::RecoPulse().

103  {
104 
105  if (!CheckIndex(wf, begin, end)) return false;
106 
107  std::vector<short>::const_iterator begin_iter(wf.begin());
108 
109  std::vector<short>::const_iterator end_iter(wf.begin());
110 
111  begin_iter = begin_iter + begin;
112 
113  end_iter = end_iter + end + 1;
114 
115  result = (double)(std::accumulate(begin_iter, end_iter, 0));
116 
117  return true;
118  }
intermediate_table::const_iterator const_iterator
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
bool CheckIndex(const std::vector< short > &wf, const size_t &begin, size_t &end)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
const std::map< unsigned, double > pmtana::AlgoCFD::LinearZeroPointX ( const std::vector< double > &  trace)
protected

Definition at line 244 of file AlgoCFD.cxx.

References pmtana::sign().

Referenced by RecoPulse().

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

A method to return the maximum value of ADC sample within the index from "begin" to "end". If the "end" is default (=0), then "end" is set to the last index of the waveform.

Definition at line 144 of file PMTPulseRecoBase.cxx.

References util::begin(), pmtana::CheckIndex(), and util::end().

Referenced by pmtana::AlgoFixedWindow::RecoPulse().

149  {
150 
151  size_t target_index = wf.size() + 1;
152 
153  result = 0;
154 
155  if (CheckIndex(wf, begin, end)) {
156 
157  for (size_t index = begin; index <= end; ++index)
158 
159  if (result < wf.at(index)) {
160  target_index = index;
161  result = (double)(wf.at(index));
162  }
163  }
164 
165  return target_index;
166  }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
bool CheckIndex(const std::vector< short > &wf, const size_t &begin, size_t &end)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
size_t pmtana::PMTPulseRecoBase::Min ( const std::vector< short > &  wf,
double &  result,
size_t  begin = 0,
size_t  end = 0 
) const
protectedinherited

A method to return the minimum value of ADC sample within the index from "begin" to "end". If the "end" is default (=0), then "end" is set to the last index of the waveform.

Definition at line 169 of file PMTPulseRecoBase.cxx.

References util::begin(), pmtana::CheckIndex(), and util::end().

174  {
175 
176  size_t target_index = wf.size() + 1;
177 
178  result = 4096;
179 
180  if (CheckIndex(wf, begin, end)) {
181 
182  for (size_t index = begin; index <= end; ++index)
183 
184  if (result > wf.at(index)) {
185  target_index = index;
186  result = (double)(wf.at(index));
187  }
188  }
189 
190  return target_index;
191  }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
bool CheckIndex(const std::vector< short > &wf, const size_t &begin, size_t &end)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
const std::string & pmtana::PMTPulseRecoBase::Name ( ) const
inherited

Name getter.

Definition at line 22 of file PMTPulseRecoBase.cxx.

References pmtana::PMTPulseRecoBase::_name.

24  {
25  return _name;
26  }
std::string _name
Unique name.
bool pmtana::PMTPulseRecoBase::Reconstruct ( const pmtana::Waveform_t wf,
const pmtana::PedestalMean_t mean_v,
const pmtana::PedestalSigma_t sigma_v 
)
inherited

A core method: this executes the algorithm and stores reconstructed parameters in the pulse_param struct object.

Definition at line 36 of file PMTPulseRecoBase.cxx.

References pmtana::PMTPulseRecoBase::_status, and pmtana::PMTPulseRecoBase::RecoPulse().

40  {
41  _status = this->RecoPulse(wf, mean_v, sigma_v);
42  return _status;
43  }
bool _status
Status after pulse reconstruction.
virtual bool RecoPulse(const pmtana::Waveform_t &, const pmtana::PedestalMean_t &, const pmtana::PedestalSigma_t &)=0
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 51 of file AlgoCFD.cxx.

References _D, _end_thresh, _F, _peak_thresh, pmtana::PMTPulseRecoBase::_pulse, pmtana::PMTPulseRecoBase::_pulse_v, pmtana::PMTPulseRecoBase::_risetime_calc_ptr, _start_thresh, pmtana::pulse_param::area, util::begin(), geo::vect::cross(), LinearZeroPointX(), pmtana::pulse_param::peak, pmtana::pulse_param::ped_mean, Reset(), pmtana::pulse_param::reset_param(), pmtana::pulse_param::t_cfdcross, pmtana::pulse_param::t_end, pmtana::pulse_param::t_max, pmtana::pulse_param::t_rise, and pmtana::pulse_param::t_start.

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

References pmtana::PMTPulseRecoBase::Reset().

Referenced by AlgoCFD(), and RecoPulse().

46  {
48  }
virtual void Reset()
A method to be called event-wise to reset parameters.
bool pmtana::PMTPulseRecoBase::Status ( ) const
inherited

Status getter.

Definition at line 29 of file PMTPulseRecoBase.cxx.

References pmtana::PMTPulseRecoBase::_status.

31  {
32  return _status;
33  }
bool _status
Status after pulse reconstruction.

Member Data Documentation

int pmtana::AlgoCFD::_D
private

Definition at line 61 of file AlgoCFD.h.

Referenced by AlgoCFD(), and RecoPulse().

double pmtana::AlgoCFD::_end_thresh
private

Definition at line 66 of file AlgoCFD.h.

Referenced by AlgoCFD(), and RecoPulse().

float pmtana::AlgoCFD::_F
private

Definition at line 60 of file AlgoCFD.h.

Referenced by AlgoCFD(), and RecoPulse().

double pmtana::AlgoCFD::_peak_thresh
private

Definition at line 64 of file AlgoCFD.h.

Referenced by AlgoCFD(), and RecoPulse().

pulse_param pmtana::PMTPulseRecoBase::_pulse
protectedinherited
double pmtana::AlgoCFD::_start_thresh
private

Definition at line 65 of file AlgoCFD.h.

Referenced by AlgoCFD(), and RecoPulse().


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