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