Belle II Software development
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
13using namespace std;
14
15namespace 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]
TOPSignalShape()
Default constructor.
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.
STL namespace.