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 {
20
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
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()
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