Belle II Software  release-05-02-19
ECLDigitCalibratorModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2020 - Belle II Collaboration *
4  * *
5  * Digit Calibration. *
6  * *
7  * This module converts the fitted amplitude into calibrated energy, *
8  * fitted time into calibrated time, and determines the time resolution *
9  * per digit. It furthermore determines the background level by counting *
10  * out of time digits above a certain energy threshold. *
11  * *
12  * Author: The Belle II Collaboration *
13  * Contributors: Torben Ferber (torben.ferber@desy.de) (TF) *
14  * Chris Hearty (hearty@physics.ubc.ca) (CH) *
15  * Ewan Hill (ehill@mail.ubc.ca) *
16  * *
17  * This software is provided "as is" without any warranty. *
18  **************************************************************************/
19 //This module
20 #include <ecl/modules/eclDigitCalibration/ECLDigitCalibratorModule.h>
21 
22 //STL
23 #include <unordered_map>
24 
25 // ROOT
26 #include "TH1F.h"
27 #include "TFile.h"
28 
29 // ECL
30 #include <ecl/dataobjects/ECLDigit.h>
31 #include <ecl/dataobjects/ECLCalDigit.h>
32 #include <ecl/digitization/EclConfiguration.h>
33 #include <ecl/dataobjects/ECLPureCsIInfo.h>
34 #include <ecl/dataobjects/ECLDsp.h>
35 #include <ecl/utility/utilityFunctions.h>
36 #include <ecl/geometry/ECLGeometryPar.h>
37 #include <ecl/dbobjects/ECLCrystalCalib.h>
38 
39 // FRAMEWORK
40 #include <framework/gearbox/Unit.h>
41 #include <framework/logging/Logger.h>
42 #include <framework/utilities/FileSystem.h>
43 #include <framework/geometry/B2Vector3.h>
44 #include <framework/core/Environment.h>
45 
46 //MDST
47 #include <mdst/dataobjects/EventLevelClusteringInfo.h>
48 
49 using namespace std;
50 using namespace Belle2;
51 using namespace ECL;
52 
53 //-----------------------------------------------------------------
54 // Register the Modules
55 //-----------------------------------------------------------------
56 REG_MODULE(ECLDigitCalibrator)
57 REG_MODULE(ECLDigitCalibratorPureCsI)
58 
59 //-----------------------------------------------------------------
60 // Implementation
61 //-----------------------------------------------------------------
62 
63 // constructor
65  m_calibrationCrystalElectronics("ECLCrystalElectronics"),
66  m_calibrationCrystalEnergy("ECLCrystalEnergy"),
67  m_calibrationCrystalElectronicsTime("ECLCrystalElectronicsTime"),
68  m_calibrationCrystalTimeOffset("ECLCrystalTimeOffset"),
69  m_calibrationCrateTimeOffset("ECLCrateTimeOffset"),
70  m_calibrationCrystalFlightTime("ECLCrystalFlightTime"),
71  m_eclDigits(eclDigitArrayName()),
72  m_eclCalDigits(eclCalDigitArrayName()),
73  m_eclDsps(eclDspArrayName()),
74  m_eclPureCsIInfo(eclPureCsIInfoArrayName())
75 {
76  // Set module properties
77  setDescription("Applies digit energy, time and time-resolution calibration to each ECL digit. Counts number of out-of-time background digits to determine the event-by-event background level.");
78  addParam("backgroundEnergyCut", m_backgroundEnergyCut, "Energy cut used to count background digits", 7.0 * Belle2::Unit::MeV);
79  addParam("backgroundTimingCut", m_backgroundTimingCut, "Timing cut used to count background digits", 110.0 * Belle2::Unit::ns);
80  addParam("fileBackgroundName", m_fileBackgroundName, "Background filename.",
81  FileSystem::findFile("/data/ecl/background_norm.root"));
82  addParam("simulatePure", m_simulatePure, "Flag to simulate pure CsI option", false);
83 
84  // t-t0 = p1 + pow( (p3/(amplitude+p2)), p4 ) + p5*exp(-amplitude/p6) ("Energy dependence equation")
85  addParam("energyDependenceTimeOffsetFitParam_p1", m_energyDependenceTimeOffsetFitParam_p1,
86  "Fit parameter (p1) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
87  addParam("energyDependenceTimeOffsetFitParam_p2", m_energyDependenceTimeOffsetFitParam_p2,
88  "Fit parameter (p2) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
89  addParam("energyDependenceTimeOffsetFitParam_p3", m_energyDependenceTimeOffsetFitParam_p3,
90  "Fit parameter (p3) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
91  addParam("energyDependenceTimeOffsetFitParam_p4", m_energyDependenceTimeOffsetFitParam_p4,
92  "Fit parameter (p4) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
93  addParam("energyDependenceTimeOffsetFitParam_p5", m_energyDependenceTimeOffsetFitParam_p5,
94  "Fit parameter (p5) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
95  addParam("energyDependenceTimeOffsetFitParam_p6", m_energyDependenceTimeOffsetFitParam_p6,
96  "Fit parameter (p6) for applying correction to the time offset as a function of the energy (amplitude)", -999.0);
97 
98 
99  // Parallel processing certification
100  setPropertyFlags(c_ParallelProcessingCertified);
101 
102  m_averageBG = 0;
103  m_pol2Max = 0.0;
104  m_timeInverseSlope = 0.0;
105 
106 }
107 
108 // destructor
109 ECLDigitCalibratorModule::~ECLDigitCalibratorModule()
110 {
111 }
112 
113 // initialize calibration
114 void ECLDigitCalibratorModule::initializeCalibration()
115 {
116 
117  m_timeInverseSlope = 1.0 / (4.0 * EclConfiguration::m_rf) *
118  1e3; // 1/(4fRF) = 0.4913 ns/clock tick, where fRF is the accelerator RF frequency, fRF=508.889 MHz. Same for all crystals.
119  m_pureCsIEnergyCalib = 0.00005; //conversion factor from ADC counts to GeV
120  m_pureCsITimeCalib = 0.1; //conversion factor from eclPureCsIDigitizer to ns
121  m_pureCsITimeOffset = 0.31; //ad-hoc offset correction for pureCsI timing
122 
123  callbackCalibration(m_calibrationCrystalElectronics, v_calibrationCrystalElectronics, v_calibrationCrystalElectronicsUnc);
124  callbackCalibration(m_calibrationCrystalEnergy, v_calibrationCrystalEnergy, v_calibrationCrystalEnergyUnc);
125  callbackCalibration(m_calibrationCrystalElectronicsTime, v_calibrationCrystalElectronicsTime,
126  v_calibrationCrystalElectronicsTimeUnc);
127  callbackCalibration(m_calibrationCrystalTimeOffset, v_calibrationCrystalTimeOffset, v_calibrationCrystalTimeOffsetUnc);
128  callbackCalibration(m_calibrationCrateTimeOffset, v_calibrationCrateTimeOffset, v_calibrationCrateTimeOffsetUnc);
129  callbackCalibration(m_calibrationCrystalFlightTime, v_calibrationCrystalFlightTime, v_calibrationCrystalFlightTimeUnc);
130 }
131 
132 // callback calibration
133 void ECLDigitCalibratorModule::callbackCalibration(DBObjPtr<ECLCrystalCalib>& cal, std::vector<float>& constants,
134  std::vector<float>& constantsUnc)
135 {
136  constants = cal->getCalibVector();
137  constantsUnc = cal->getCalibUncVector();
138 }
139 
140 
141 // initialize
142 void ECLDigitCalibratorModule::initialize()
143 {
144  //mdst dataobjects
145  m_eventLevelClusteringInfo.registerInDataStore(eventLevelClusteringInfoName());
146 
147  // Register Digits, CalDigits and their relation in datastore
148  m_eclDigits.registerInDataStore(eclDigitArrayName());
149  m_eclDsps.registerInDataStore(eclDspArrayName());
150  m_eclCalDigits.registerInDataStore(eclCalDigitArrayName());
151  m_eclCalDigits.registerRelationTo(m_eclDigits);
152 
153  //Special information for pure CsI simulation
154  m_eclPureCsIInfo.registerInDataStore(eclPureCsIInfoArrayName());
155 
156  // initialize calibration
157  initializeCalibration();
158 
159  // initialize time resolution (not yet from the database)
160  // read the Background correction factors (for full background)
161  m_fileBackground = new TFile(m_fileBackgroundName.c_str(), "READ");
162  if (!m_fileBackground) B2FATAL("Could not find file: " << m_fileBackgroundName);
163  m_th1fBackground = dynamic_cast<TH1F*>(m_fileBackground->Get("background"));
164  if (!m_th1fBackground) B2FATAL("Could not find m_th1fBackground");
165 
166  // average BG value from m_th1fBackground
167  m_averageBG = m_th1fBackground->Integral() / m_th1fBackground->GetEntries();
168 
169  // get maximum position ("x") of 2-order pol background for t99
170  if (fabs(c_pol2Var3) > 1e-12) {
171  m_pol2Max = -c_pol2Var2 / (2 * c_pol2Var3);
172  } else {
173  m_pol2Max = 0.;
174  }
175 
176  if ((m_energyDependenceTimeOffsetFitParam_p1 != -999) &&
177  (m_energyDependenceTimeOffsetFitParam_p2 != -999) &&
178  (m_energyDependenceTimeOffsetFitParam_p3 != -999) &&
179  (m_energyDependenceTimeOffsetFitParam_p4 != -999) &&
180  (m_energyDependenceTimeOffsetFitParam_p5 != -999) &&
181  (m_energyDependenceTimeOffsetFitParam_p6 != -999)) {
182  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p1 = " << m_energyDependenceTimeOffsetFitParam_p1);
183  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p2 = " << m_energyDependenceTimeOffsetFitParam_p2);
184  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p3 = " << m_energyDependenceTimeOffsetFitParam_p3);
185  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p4 = " << m_energyDependenceTimeOffsetFitParam_p4);
186  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p5 = " << m_energyDependenceTimeOffsetFitParam_p5);
187  B2DEBUG(80, "m_energyDependenceTimeOffsetFitParam_p6 = " << m_energyDependenceTimeOffsetFitParam_p6);
188 
189  ECLTimeUtil->setTimeWalkFuncParams(m_energyDependenceTimeOffsetFitParam_p1,
190  m_energyDependenceTimeOffsetFitParam_p2,
191  m_energyDependenceTimeOffsetFitParam_p3,
192  m_energyDependenceTimeOffsetFitParam_p4,
193  m_energyDependenceTimeOffsetFitParam_p5,
194  m_energyDependenceTimeOffsetFitParam_p6) ;
195  }
196 }
197 
198 // begin run
199 void ECLDigitCalibratorModule::beginRun()
200 {
201  // Check if any of the calibration constants have changed
202  if (m_calibrationCrystalElectronics.hasChanged()) {
203  if (m_calibrationCrystalElectronics) {
204  callbackCalibration(m_calibrationCrystalElectronics, v_calibrationCrystalElectronics, v_calibrationCrystalElectronicsUnc);
205  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrystalElectronics for current run!");
206  }
207 
208  if (m_calibrationCrystalEnergy.hasChanged()) {
209  if (m_calibrationCrystalEnergy) {
210  callbackCalibration(m_calibrationCrystalEnergy, v_calibrationCrystalEnergy, v_calibrationCrystalEnergyUnc);
211  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrystalEnergy for current run!");
212  }
213 
214  if (m_calibrationCrystalElectronicsTime.hasChanged()) {
215  if (m_calibrationCrystalElectronicsTime) {
216  callbackCalibration(m_calibrationCrystalElectronicsTime, v_calibrationCrystalElectronicsTime,
217  v_calibrationCrystalElectronicsTimeUnc);
218  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrystalElectronicsTime for current run!");
219  }
220 
221  if (m_calibrationCrystalTimeOffset.hasChanged()) {
222  if (m_calibrationCrystalTimeOffset) {
223  callbackCalibration(m_calibrationCrystalTimeOffset, v_calibrationCrystalTimeOffset, v_calibrationCrystalTimeOffsetUnc);
224  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrystalTimeOffset for current run!");
225  }
226 
227  if (m_calibrationCrateTimeOffset.hasChanged()) {
228  if (m_calibrationCrateTimeOffset) {
229  callbackCalibration(m_calibrationCrateTimeOffset, v_calibrationCrateTimeOffset, v_calibrationCrateTimeOffsetUnc);
230  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrateTimeOffset for current run!");
231  }
232 
233  if (m_calibrationCrystalFlightTime.hasChanged()) {
234  if (m_calibrationCrystalFlightTime) {
235  callbackCalibration(m_calibrationCrystalFlightTime, v_calibrationCrystalFlightTime, v_calibrationCrystalFlightTimeUnc);
236  } else B2ERROR("ECLDigitCalibratorModule::beginRun - Couldn't find m_calibrationCrystalFlightTime for current run!");
237  }
238 
239 }
240 
241 // event
242 void ECLDigitCalibratorModule::event()
243 {
244 
245  // Loop over the input array
246  for (auto& aECLDigit : m_eclDigits) {
247 
248  bool is_pure_csi = 0;
249 
250  // append an ECLCalDigit to the storearray
251  const auto aECLCalDigit = m_eclCalDigits.appendNew();
252 
253  // get the cell id from the ECLDigit as identifier
254  const int cellid = aECLDigit.getCellId();
255 
256  // check that the cell id is valid
257  if (cellid < 1 or cellid > c_nCrystals) {
258  B2FATAL("ECLDigitCalibrationModule::event():" << cellid << " out of range!");
259  }
260 
261  // perform the digit energy calibration: E = A * Ce * Cs
262  const int amplitude = aECLDigit.getAmp();
263  double calibratedEnergy = 0;
264 
265  if (m_simulatePure) {
266  if (aECLDigit.getRelated<ECLPureCsIInfo>(eclPureCsIInfoArrayName()) != NULL) {
267  if (aECLDigit.getRelated<ECLPureCsIInfo>(eclPureCsIInfoArrayName())->getPureCsI())
268  is_pure_csi = 1;
269  }
270  }
271 
272  if (is_pure_csi) {
273  calibratedEnergy = amplitude * m_pureCsIEnergyCalib;
274  } else {
275  calibratedEnergy = amplitude * v_calibrationCrystalElectronics[cellid - 1] * v_calibrationCrystalEnergy[cellid - 1];
276  }
277  if (calibratedEnergy < 0.0) calibratedEnergy = 0.0;
278 
279  // perform the digit timing calibration: t = c * (tfit - Te - Ts)
280  const int time = aECLDigit.getTimeFit();
281  const int quality = aECLDigit.getQuality();
282  double calibratedTime = c_timeForFitFailed;
283  if (quality == 1) {
284  aECLCalDigit->addStatus(ECLCalDigit::c_IsFailedFit); //this is used to flag failed fits
285  } else { //only calibrate digit time if we have a good waveform fit
286  if (is_pure_csi) {
287  calibratedTime = m_pureCsITimeCalib * m_timeInverseSlope * (time - v_calibrationCrystalElectronicsTime[cellid - 1] -
288  v_calibrationCrystalTimeOffset[cellid - 1] -
289  v_calibrationCrateTimeOffset[cellid - 1])
290  - v_calibrationCrystalFlightTime[cellid - 1] + m_pureCsITimeOffset ;
291  } else {
292  calibratedTime = m_timeInverseSlope * (time - v_calibrationCrystalElectronicsTime[cellid - 1] -
293  v_calibrationCrystalTimeOffset[cellid - 1] -
294  v_calibrationCrateTimeOffset[cellid - 1])
295  - v_calibrationCrystalFlightTime[cellid - 1] ;
296  }
297 
298  // For data, apply a correction to the time as a function of the signal amplitude. Correction determined from a fit.
299  // No correction for MC
300  bool m_IsMCFlag = Environment::Instance().isMC();
301  B2DEBUG(35, "cellid = " << cellid << ", m_IsMCFlag = " << m_IsMCFlag) ;
302 
303  if (!m_IsMCFlag) {
304  double energyTimeShift = ECLTimeUtil->energyDependentTimeOffsetElectronic(amplitude * v_calibrationCrystalElectronics[cellid - 1]) *
305  m_timeInverseSlope ;
306  B2DEBUG(35, "cellid = " << cellid << ", amplitude = " << amplitude << ", corrected amplitude = " << amplitude *
307  v_calibrationCrystalElectronics[cellid - 1] << ", time before t(E) shift = " << calibratedTime << ", t(E) shift = " <<
308  energyTimeShift << " ns") ;
309  calibratedTime -= energyTimeShift ;
310  }
311  }
312 
313  B2DEBUG(35, "cellid = " << cellid << ", amplitude = " << amplitude << ", calibrated energy = " << calibratedEnergy);
314  B2DEBUG(35, "cellid = " << cellid << ", time = " << time << ", calibratedTime = " << calibratedTime);
315 
316  //Calibrating offline fit results
317  ECLDsp* aECLDsp = aECLDigit.getRelatedFrom<ECLDsp>();
318  aECLCalDigit->setTwoComponentChi2(-1);
319  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonHadron, -1);
320  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonHadronBackgroundPhoton, -1);
321  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonDiodeCrossing, -1);
322  aECLCalDigit->setTwoComponentTotalEnergy(-1);
323  aECLCalDigit->setTwoComponentHadronEnergy(-1);
324  aECLCalDigit->setTwoComponentDiodeEnergy(-1);
325  if (aECLDsp) {
326  //require ECLDigit to have offline waveform
327  if (aECLDsp->getTwoComponentChi2() > 0) {
328  //require offline waveform to have offline fit result
329 
330  const double calibratedTwoComponentTotalEnergy = aECLDsp->getTwoComponentTotalAmp() * v_calibrationCrystalElectronics[cellid - 1] *
331  v_calibrationCrystalEnergy[cellid - 1];
332  const double calibratedTwoComponentHadronEnergy = aECLDsp->getTwoComponentHadronAmp() * v_calibrationCrystalElectronics[cellid -
333  1] *
334  v_calibrationCrystalEnergy[cellid - 1];
335  const double calibratedTwoComponentDiodeEnergy = aECLDsp->getTwoComponentDiodeAmp() * v_calibrationCrystalElectronics[cellid - 1] *
336  v_calibrationCrystalEnergy[cellid - 1];
337  const double twoComponentChi2 = aECLDsp->getTwoComponentChi2();
338  const ECLDsp::TwoComponentFitType twoComponentFitType = aECLDsp->getTwoComponentFitType();
339 
340  aECLCalDigit->setTwoComponentTotalEnergy(calibratedTwoComponentTotalEnergy);
341  aECLCalDigit->setTwoComponentHadronEnergy(calibratedTwoComponentHadronEnergy);
342  aECLCalDigit->setTwoComponentDiodeEnergy(calibratedTwoComponentDiodeEnergy);
343  aECLCalDigit->setTwoComponentChi2(twoComponentChi2);
344  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonHadron, aECLDsp->getTwoComponentSavedChi2(ECLDsp::photonHadron));
345  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonHadronBackgroundPhoton,
346  aECLDsp->getTwoComponentSavedChi2(ECLDsp::photonHadronBackgroundPhoton));
347  aECLCalDigit->setTwoComponentSavedChi2(ECLDsp::photonDiodeCrossing, aECLDsp->getTwoComponentSavedChi2(ECLDsp::photonDiodeCrossing));
348  aECLCalDigit->setTwoComponentFitType(twoComponentFitType);
349 
350  }
351  }
352 
353  // fill the ECLCalDigit with the cell id, the calibrated information and calibration status
354  aECLCalDigit->setCellId(cellid);
355 
356  aECLCalDigit->setEnergy(calibratedEnergy);
357  aECLCalDigit->addStatus(ECLCalDigit::c_IsEnergyCalibrated);
358 
359  aECLCalDigit->setTime(calibratedTime);
360  aECLCalDigit->addStatus(ECLCalDigit::c_IsTimeCalibrated);
361 
362  // set a relation to the ECLDigit
363  aECLCalDigit->addRelationTo(&aECLDigit);
364  }
365 
366  // determine background level
367  const int bgCount = determineBackgroundECL();
368 
369  // set the t99 (time resolution)
370  for (auto& aECLCalDigit : m_eclCalDigits) {
371 
372  // perform the time resolution calibration
373  const double t99 = getT99(aECLCalDigit.getCellId(),
374  aECLCalDigit.getEnergy(),
375  aECLCalDigit.hasStatus(ECLCalDigit::c_IsFailedFit),
376  bgCount); // calibrated time resolution
377  aECLCalDigit.setTimeResolution(t99);
378 
379  if (t99 == c_timeResolutionForFitFailed) {
380  aECLCalDigit.addStatus(ECLCalDigit::c_IsFailedTimeResolution);
381  }
382 
383  aECLCalDigit.addStatus(ECLCalDigit::c_IsTimeResolutionCalibrated);
384  }
385 }
386 
387 // end run
388 void ECLDigitCalibratorModule::endRun()
389 {
390 
391 }
392 
393 // terminate
394 void ECLDigitCalibratorModule::terminate()
395 {
396 
397 }
398 
399 // Time resolution calibration
400 double ECLDigitCalibratorModule::getT99(const int cellid, const double energy, const bool fitfailed, const int bgcount) const
401 {
402 
403  // if this digit is calibrated to the trigger time, we set the resolution to 'very bad' (to be discussed)
404  if (fitfailed) return c_timeResolutionForFitFailed;
405 
406  // Get the background level [MeV / mus]
407  const double bglevel = TMath::Min((double) bgcount / (double) c_nominalBG * m_th1fBackground->GetBinContent(cellid) / m_averageBG,
408  m_pol2Max); // c_nominalBG = 183 for actual version of digitizer, m_averageBG is about 2 MeV/ mus
409 
410  // Get p1 as function of background level
411  const double p1 = c_pol2Var1 + c_pol2Var2 * bglevel + c_pol2Var3 * bglevel * bglevel;
412 
413  // inverse energy in 1/MeV
414  double einv = 0.;
415  if (energy > 1e-12) einv = 1. / (energy / Belle2::Unit::MeV);
416 
417  // calculate t99 using the inverse energy and p1 (p0 is zero)
418  double t99 = p1 * einv;
419 
420  // for high energies we fix t99 to 3.5ns
421  if (t99 < c_minT99) t99 = c_minT99;
422 
423  B2DEBUG(35, "ECLDigitCalibratorModule::getCalibratedTimeResolution: dose = " << m_th1fBackground->GetBinContent(
424  cellid) << ", bglevel = " << bglevel << ", cellid = " << cellid << ", t99 = " << t99 << ", energy = " << energy /
426 
427  return t99;
428 }
429 
430 // Determine background level by event by counting out-of-time digits above threshold.
431 int ECLDigitCalibratorModule::determineBackgroundECL()
432 {
433  //EventLevelClustering counters
434  using regionCounter = std::unordered_map<ECL::DetectorRegion, uint>;
435 
436  regionCounter outOfTimeCount {{ECL::DetectorRegion::FWD, 0},
437  {ECL::DetectorRegion::BRL, 0},
438  {ECL::DetectorRegion::BWD, 0}};
439 
440  ECLGeometryPar* geom = ECLGeometryPar::Instance();
441 
442  // Loop over the input array
443  for (auto& aECLCalDigit : m_eclCalDigits) {
444  if (abs(aECLCalDigit.getTime()) >= m_backgroundTimingCut) {
445  if (aECLCalDigit.getEnergy() >= m_backgroundEnergyCut) {
446  //Get digit theta
447  const B2Vector3D position = geom->GetCrystalPos(aECLCalDigit.getCellId() - 1);
448  const double theta = position.Theta();
449 
450  //Get detector region
451  const auto detectorRegion = ECL::getDetectorRegion(theta);
452 
453  //Count out of time digits per region
454  ++outOfTimeCount.at(detectorRegion);
455  }
456  }
457  }
458 
459  //Save EventLevelClusteringInfo
460  if (!m_eventLevelClusteringInfo) {
461  m_eventLevelClusteringInfo.create();
462  }
463 
464  m_eventLevelClusteringInfo->setNECLCalDigitsOutOfTimeFWD(outOfTimeCount.at(ECL::DetectorRegion::FWD));
465  m_eventLevelClusteringInfo->setNECLCalDigitsOutOfTimeBarrel(outOfTimeCount.at(ECL::DetectorRegion::BRL));
466  m_eventLevelClusteringInfo->setNECLCalDigitsOutOfTimeBWD(outOfTimeCount.at(ECL::DetectorRegion::BWD));
467 
468  B2DEBUG(35, "ECLDigitCalibratorModule::determineBackgroundECL found " << outOfTimeCount.at(ECL::DetectorRegion::FWD) << ", " <<
469  outOfTimeCount.at(ECL::DetectorRegion::BRL) << ", " <<
470  outOfTimeCount.at(ECL::DetectorRegion::BWD) << " out of time digits in FWD, BRL, BWD");
471 
472  return m_eventLevelClusteringInfo->getNECLCalDigitsOutOfTime();
473 
474 }
475 
476 
Belle2::ECLPureCsIInfo
Class to store ECL crystal type relation to ECLDigit for the simulation pure CsI upgrade option fille...
Definition: ECLPureCsIInfo.h:34
Belle2::ECLDsp::getTwoComponentChi2
double getTwoComponentChi2() const
get two comp chi2
Definition: ECLDsp.h:159
Belle2::Unit::ns
static const double ns
Standard of [time].
Definition: Unit.h:58
Belle2::ECLDsp::TwoComponentFitType
TwoComponentFitType
Offline two component fit type.
Definition: ECLDsp.h:42
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::ECLDsp
Class to store ECL ShaperDSP waveform ADC data.
Definition: ECLDsp.h:38
Belle2::ECLDsp::getTwoComponentHadronAmp
double getTwoComponentHadronAmp() const
get two comp hadron amp
Definition: ECLDsp.h:149
Belle2::DBObjPtr
Class for accessing objects in the database.
Definition: DBObjPtr.h:31
Belle2::B2Vector3< double >
Belle2::Unit::MeV
static const double MeV
[megaelectronvolt]
Definition: Unit.h:124
Belle2::ECLDigitCalibratorModule
Class to find calibrate digits and convert waveform fit information to physics quantities.
Definition: ECLDigitCalibratorModule.h:51
Belle2::ECLDsp::setTwoComponentChi2
void setTwoComponentChi2(double input)
Set two comp chi2.
Definition: ECLDsp.h:95
Belle2::ECLDsp::getTwoComponentDiodeAmp
double getTwoComponentDiodeAmp() const
get two comp diode amp
Definition: ECLDsp.h:154
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::ECLDsp::getTwoComponentFitType
TwoComponentFitType getTwoComponentFitType() const
get two comp fit type
Definition: ECLDsp.h:184
Belle2::ECLDsp::getTwoComponentTotalAmp
double getTwoComponentTotalAmp() const
get two comp total amp
Definition: ECLDsp.h:144
Belle2::ECLDsp::getTwoComponentSavedChi2
double getTwoComponentSavedChi2(TwoComponentFitType FitTypeIn) const
get two comp chi2 for a fit type see enum TwoComponentFitType in ECLDsp.h for description of fit type...
Definition: ECLDsp.h:165
Belle2::ECL::ECLGeometryPar
The Class for ECL Geometry Parameters.
Definition: ECLGeometryPar.h:45
Belle2::B2Vector3::Theta
DataType Theta() const
The polar angle.
Definition: B2Vector3.h:152
Belle2::RelationsInterface::getRelatedFrom
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
Definition: RelationsObject.h:265