Belle II Software  release-08-01-10
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 
15 namespace 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,
130  m_triggerBin);
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
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
const std::vector< StripInRawCluster > getStripsInRawCluster() const
Definition: RawCluster.h:110
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