Belle II Software development
SVDClusterTime.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 <framework/logging/Logger.h>
10#include <framework/utilities/MathHelpers.h>
11#include <svd/reconstruction/SVDClusterTime.h>
12#include <svd/reconstruction/SVDMaxSumAlgorithm.h>
13#include <TMath.h>
14#include <numeric>
15
16namespace Belle2 {
21
22 namespace SVD {
23
24 void SVDClusterTime::applyCoG6Time(const Belle2::SVD::RawCluster& rawCluster, double& time, double& timeError, int& firstFrame)
25 {
26
27 // ISSUES:
28 // 1. time error not computed
29
30 //the first frame is 0 by definition
31 firstFrame = 0;
32
33 //take the strips in the rawCluster
34 std::vector<Belle2::SVD::StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
35
36 //initialize time, stripTime and sumAmplitudes
37 time = 0;
38 timeError = 0;
39 float sumAmplitudes = 0;
40
41 for (int i = 0; i < (int)strips.size(); i++) {
42
43 Belle2::SVD::StripInRawCluster strip = strips.at(i);
44
45 double stripTime = 0;
46 float stripSumAmplitudes = 0;
47
48 for (int k = 0; k < 6; k ++) {
49 stripTime += k * strip.samples[k];
50 stripSumAmplitudes += strip.samples[k];
51 }
52 if (stripSumAmplitudes != 0) {
53 stripTime /= (stripSumAmplitudes);
54 stripTime *= m_apvClockPeriod;
55 } else {
56 stripTime = -1;
57 B2WARNING("Trying to divide by 0 (ZERO)! Sum of amplitudes is nullptr! Skipping this SVDShaperDigit!");
58 }
59
60 // correct strip by the CalPeak
61 stripTime -= m_PulseShapeCal.getPeakTime(rawCluster.getSensorID(), rawCluster.isUSide(), strip.cellID);
62
63 if (std::isnan(float(m_triggerBin)))
64 B2FATAL("OOPS, we can't continue, you have to set the trigger bin!");
65
67 // calibrate strip time (cellID not used)
68 stripTime = m_CoG6TimeCal.getCorrectedTime(rawCluster.getSensorID(), rawCluster.isUSide(), strip.cellID, stripTime, m_triggerBin);
69
70 //update cluster time
71 time += stripTime * strip.maxSample;
72 sumAmplitudes += strip.maxSample;
73 }
74
75 //finally compute cluster time
76 time = time / sumAmplitudes;
77 }
78
79 void SVDClusterTime::applyCoG3Time(const Belle2::SVD::RawCluster& rawCluster, double& time, double& timeError, int& firstFrame)
80 {
81 //take the MaxSum 3 samples
82 SVDMaxSumAlgorithm maxSum = SVDMaxSumAlgorithm(rawCluster.getClsSamples(false));
83
84 std::vector<float> selectedSamples = maxSum.getSelectedSamples();
85 firstFrame = maxSum.getFirstFrame();
86
87
88 auto begin = selectedSamples.begin();
89 const auto end = selectedSamples.end();
90
91 auto retval = 0., norm = 0.;
92 for (auto step = 0.; begin != end; ++begin, step += m_apvClockPeriod) {
93 norm += static_cast<double>(*begin);
94 retval += static_cast<double>(*begin) * step;
95 }
96 float rawtime = retval / norm;
97
98 if (std::isnan(float(m_triggerBin)))
99 B2FATAL("OOPS, we can't continue, you have to set the trigger bin!");
100
102 time = rawtime;
103 else
104 //cellID = 10 not used for calibration
105 time = m_CoG3TimeCal.getCorrectedTime(rawCluster.getSensorID(), rawCluster.isUSide(), 10, rawtime, m_triggerBin);
106
107
108
109 // now compute the CoG3 time error
110 // assumptions:
111 // 1. calibration function parameters error not taken into account
112 // 2. 100% correlation among different strip noises
113 // 3. error on the sample amplitude = strip noise for all samples
114
115 //compute the noise of the clustered sample
116 //it is the same for all samples
117 //computed assuming 2. (-> linear sum, not quadratic)
118 std::vector<Belle2::SVD::StripInRawCluster> strips = rawCluster.getStripsInRawCluster();
119 float noise = std::accumulate(strips.begin(), strips.end(), 0., [](float sum, const Belle2::SVD::StripInRawCluster & strip) { return sum + strip.noise; });
120
121 //compute the noise of the raw time
122 //assuming only the clustered sample amplitude carries an uncertainty
123 double rawtimeError = 0;
124 begin = selectedSamples.begin();
125 for (float i = 0.; begin != end; ++begin, i += 1)
126 rawtimeError += square((m_apvClockPeriod * i - rawtime) / norm);
127 rawtimeError = sqrt(rawtimeError) * noise;
128
129 //compute the error on the calibrated time
130 timeError = m_CoG3TimeCal.getCorrectedTimeError(rawCluster.getSensorID(), rawCluster.isUSide(), 10, rawtime, rawtimeError,
132 }
133
134
135 void SVDClusterTime::applyELS3Time(const Belle2::SVD::RawCluster& rawCluster, double& time, double& timeError, int& firstFrame)
136 {
137
138 // ISSUES:
139 // 1. ELS3 tau hardcoded
140 // 2. time error not computer
141
142 timeError = 0;
143 float m_ELS3tau = 55;
144
145 //take the MaxSum 3 samples
146 SVDMaxSumAlgorithm maxSum = SVDMaxSumAlgorithm(rawCluster.getClsSamples(false));
147
148 std::vector<float> selectedSamples = maxSum.getSelectedSamples();
149 firstFrame = maxSum.getFirstFrame();
150
151 auto begin = selectedSamples.begin();
152 const double E = std::exp(- m_apvClockPeriod / m_ELS3tau);
153 const double E2 = E * E;
154 const double E4 = E2 * E2;
155 double a0 = (*begin);
156 double a1 = (*(begin + 1));
157 double a2 = (*(begin + 2));
158
159 //compute raw time
160 const double w = (a0 - E2 * a2) / (2 * a0 + E * a1);
161 auto rawtime_num = 2 * E4 + w * E2;
162 auto rawtime_den = 1 - E4 - w * (2 + E2);
163 double rawtime = - m_apvClockPeriod * rawtime_num / rawtime_den;
164
165 if (std::isnan(float(m_triggerBin)))
166 B2FATAL("OOPS, we can't continue, you have to set the trigger bin!");
167
169 time = rawtime;
170 else
171 time = m_ELS3TimeCal.getCorrectedTime(rawCluster.getSensorID(), rawCluster.isUSide(), 10, rawtime, m_triggerBin);
172
173 }
174
175 } //SVD namespace
177} //Belle2 namespace
R E
internal precision of FFTW codelets
Class representing a raw cluster candidate during clustering of the SVD.
Definition RawCluster.h:33
const std::vector< StripInRawCluster > getStripsInRawCluster() const
Definition RawCluster.h:110
Belle2::SVDShaperDigit::APVFloatSamples getClsSamples(bool inElectrons) const
VxdID getSensorID() const
Definition RawCluster.h:80
void applyELS3Time(const Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame)
ELS3 Time Algorithm.
void applyCoG6Time(const Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame)
CoG6 Time Algorithm.
SVD3SampleCoGTimeCalibrations m_CoG3TimeCal
CoG3 time calibration wrapper.
SVDCoGTimeCalibrations m_CoG6TimeCal
CoG6 time calibration wrapper.
SVDPulseShapeCalibrations m_PulseShapeCal
SVDPulseShaper calibration wrapper.
void applyCoG3Time(const Belle2::SVD::RawCluster &rawCluster, double &time, double &timeError, int &firstFrame)
CoG3 Time Algorithm.
SVD3SampleELSTimeCalibrations m_ELS3TimeCal
ELS3 time calibration wrapper.
double m_apvClockPeriod
APV clock period.
bool m_returnRawClusterTime
to be used for time calibration
Class implementing the MaxSum algorithm.
std::vector< float > getSelectedSamples()
constexpr T square(const T &x)
Calculate the square of the input.
Definition MathHelpers.h:21
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Abstract base class for different kinds of events.
structure containing the relevant information of each strip of the raw cluster
Definition RawCluster.h:20
Belle2::SVDShaperDigit::APVFloatSamples samples
ADC of the acquired samples.
Definition RawCluster.h:25
int maxSample
ADC max of the acquired samples.
Definition RawCluster.h:23