Belle II Software  release-08-01-10
TOPSignalShape.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <top/dbobjects/TOPSignalShape.h>
10 #include <framework/logging/Logger.h>
11 #include <math.h>
12 
13 using namespace std;
14 
15 namespace Belle2 {
21  TOPSignalShape::TOPSignalShape(std::vector<double> shape, double timeBin, double tau,
22  double pole1, double pole2):
23  m_shape(shape), m_tau(tau), m_pole1(pole1), m_pole2(pole2)
24  {
25  m_tmax = m_tmin + (shape.size() - 1) * timeBin;
26 
27  // find peaking value (positive pulse maximum!)
28 
29  int samplePeak = 0;
30  for (unsigned i = 0; i < shape.size(); i++) {
31  if (shape[i] > shape[samplePeak]) samplePeak = i;
32  }
33 
34  TSpline5 spline("spline", m_tmin, m_tmax, shape.data(), shape.size());
35  double t1 = m_tmin + (samplePeak - 1) * timeBin;
36  double t2 = m_tmin + (samplePeak + 1) * timeBin;
37  for (int i = 0; i < 20; i++) {
38  double t = (t1 + t2) / 2;
39  if (spline.Derivative(t) > 0) {
40  t1 = t;
41  } else {
42  t2 = t;
43  }
44  }
45  double vPeak = spline.Eval((t1 + t2) / 2);
46 
47  // normalize waveform
48 
49  for (auto& value : m_shape) value /= vPeak;
50 
51  // find 50% CF crossing time (positive pulse!)
52 
53  auto sampleRise = samplePeak;
54  while (sampleRise >= 0 and m_shape[sampleRise] > 0.5) sampleRise--;
55  t1 = m_tmin + sampleRise * timeBin;
56  t2 = m_tmin + (sampleRise + 1) * timeBin;
57  for (int i = 0; i < 20; i++) {
58  double t = (t1 + t2) / 2;
59  if (spline.Eval(t) < vPeak / 2) {
60  t1 = t;
61  } else {
62  t2 = t;
63  }
64  }
65  double crossingTime = (t1 + t2) / 2;
66 
67  // set 50% CF crossing to happen at t = 0
68 
69  m_tmin -= crossingTime;
70  m_tmax -= crossingTime;
71 
72  }
73 
74 
75  double TOPSignalShape::getValue(double t) const
76  {
77  if (m_shape.empty()) {
78  B2ERROR("TOPSignalShape::getValue: object not initialized");
79  return 0;
80  }
81  if (isnan(t)) return 0; // to prevent interpolator to crash with seg. fault
82  if (t < m_tmin) return 0;
83  if (t > m_tmax) return m_shape.back() * exp(-(t - m_tmax) / m_tau);
84  if (!m_interpolator) {
85  std::vector<double> shape(m_shape); // since argument in TSpline5 is not const!
86  m_interpolator = new TSpline5("signalShape", m_tmin, m_tmax,
87  shape.data(), shape.size());
88  }
89  return m_interpolator->Eval(t);
90  }
91 
92 
94  {
95  if (m_peakTime == 0) {
96  double t1 = 0;
97  double t2 = 1;
98  while (getValue(t2) > 0.5) t2 += 1;
99  for (int i = 0; i < 20; i++) {
100  double t = (t1 + t2) / 2;
101  if (m_interpolator->Derivative(t) > 0) {
102  t1 = t;
103  } else {
104  t2 = t;
105  }
106  }
107  m_peakTime = (t1 + t2) / 2;
108  }
109 
110  return m_peakTime;
111  }
112 
113 
115 } // end Belle2 namespace
double m_peakTime
do not write out
std::vector< double > m_shape
waveform values
TSpline5 * m_interpolator
cache for the interpolator
double m_tau
time constant of the exponential tail [ns]
double m_tmin
time of the first waveform sample [ns]
double m_tmax
time of the last waveform sample [ns]
double getPeakingTime() const
Returns peaking time of the signal.
double getValue(double t) const
Returns value at time t of the normalized waveform using interpolator.
Abstract base class for different kinds of events.