Belle II Software  release-06-02-00
ECLShowerCorrectorModule.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 //..This module
10 #include <ecl/modules/eclShowerCorrection/ECLShowerCorrectorModule.h>
11 
12 //..Framework
13 #include <framework/logging/Logger.h>
14 
15 //..ECL
16 #include <ecl/dbobjects/ECLLeakageCorrections.h>
17 #include <ecl/dataobjects/ECLShower.h>
18 #include <ecl/geometry/ECLLeakagePosition.h>
19 
20 using namespace Belle2;
21 using namespace ECL;
22 
23 //-----------------------------------------------------------------
24 // Register the Module
25 //-----------------------------------------------------------------
26 REG_MODULE(ECLShowerCorrector)
27 REG_MODULE(ECLShowerCorrectorPureCsI)
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
34  m_eclShowers(eclShowerArrayName()),
35  m_eclLeakageCorrections("ECLLeakageCorrections")
36 {
37 
38  // Set description
39  setDescription("ECLShowerCorrectorModule: Corrects energy of ECLShowers and highest energy crystal for shower leakage, beam backgrounds, and clustering");
40  setPropertyFlags(c_ParallelProcessingCertified);
41 
42 }
43 
45 {
46  if (m_leakagePosition != nullptr)
47  delete m_leakagePosition;
48 }
49 
51 {
52  B2DEBUG(28, "ECLShowerCorrectorModule::initialize()");
53 
54  //..Register in datastore
55  m_eclShowers.registerInDataStore(eclShowerArrayName());
56 
57  //..Class to find cellID and position within crystal from theta and phi
58  m_leakagePosition = new ECLLeakagePosition();
59 
60 }
61 
63 {
64  //-----------------------------------------------------------------
65  //..Read in leakage corrections from database
66  if (m_eclLeakageCorrections.hasChanged()) {
67 
68  //..Vectors of log(E) for each region
69  std::vector<float> logEnergiesFwd = m_eclLeakageCorrections->getlogEnergiesFwd();
70  std::vector<float> logEnergiesBrl = m_eclLeakageCorrections->getlogEnergiesBrl();
71  std::vector<float> logEnergiesBwd = m_eclLeakageCorrections->getlogEnergiesBwd();
72 
73  //..Adjust the size of the vector of log energies to match the number in the payload
74  nEnergies = logEnergiesBrl.size();
75  B2INFO("ECLShowerCorrector beginRun: Number of energies = " << nEnergies);
76  leakLogE.resize(nLeakReg, std::vector<float>(nEnergies, 0.));
77 
78  //..Copy values to leakLogE
79  for (int ie = 0; ie < nEnergies; ie++) {
80  leakLogE[0][ie] = logEnergiesFwd[ie];
81  leakLogE[1][ie] = logEnergiesBrl[ie];
82  leakLogE[2][ie] = logEnergiesBwd[ie];
83  }
84 
85  //..Position and nCrys dependent corrections
86  thetaCorrection = m_eclLeakageCorrections->getThetaCorrections();
87  phiCorrection = m_eclLeakageCorrections->getPhiCorrections();
88  crysCorrection = m_eclLeakageCorrections->getnCrystalCorrections();
89 
90  //..Relevant parameters
91  nPositionBins = thetaCorrection.GetNbinsY();
92  nCrysMax = crysCorrection.GetNbinsY();
93  nXBins = nThetaID * nEnergies;
94  }
95 }
96 
98 {
99 
100  //-----------------------------------------------------------------
101  //..Loop over all ECLShowers.
102  for (auto& eclShower : m_eclShowers) {
103 
104  //..Only want to correct EM showers
105  if (eclShower.getHypothesisId() != ECLShower::c_nPhotons) {break;}
106 
107  //-----------------------------------------------------------------
108  //..Shower quantities needed to find the correction.
109  const double energyRaw = eclShower.getEnergy();
110  const double energyRawHighest = eclShower.getEnergyHighestCrystal();
111 
112  //..Crystals used to calculate energy
113  int nForEnergy = (int)(eclShower.getNumberOfCrystalsForEnergy() + 0.001);
114  const int nCrys = std::min(nCrysMax, nForEnergy);
115 
116  //..Location starting point
117  const int icellIDMaxE = eclShower.getCentralCellId();
118  const float thetaLocation = eclShower.getTheta();
119  const float phiLocation = eclShower.getPhi();
120 
121  //-----------------------------------------------------------------
122  //..Location of shower. cellID = positionVector[0] is for debugging only
123  std::vector<int> positionVector = m_leakagePosition->getLeakagePosition(icellIDMaxE, thetaLocation, phiLocation, nPositionBins);
124  const int iThetaID = positionVector[1];
125  const int iRegion = positionVector[2];
126  const int iThetaBin = positionVector[3];
127  const int iPhiBin = positionVector[4];
128  const int iPhiMech = positionVector[5];
129 
130  //-----------------------------------------------------------------
131  //..The correction is a function of corrected energy, so will need to iterate
132  double correction = 0.96; // typical correction as starting point
133  for (int iter = 0; iter < 2; iter++) {
134 
135  //..Energy points that bracket this value
136  float logEnergy = log(energyRaw / correction);
137  int ie0 = 0;
138  if (logEnergy < leakLogE[iRegion][0]) {
139  ie0 = 0;
140  } else if (logEnergy > leakLogE[iRegion][nEnergies - 1]) {
141  ie0 = nEnergies - 2;
142  } else {
143  while (logEnergy > leakLogE[iRegion][ie0 + 1]) {ie0++;}
144  }
145 
146  //..Correction from lower energy point.
147  // The following include +1 because first histogram bin is 1 not 0.
148  int iXBin = iThetaID + ie0 * nThetaID + 1; // thetaID / energy bin
149  double thetaCor = thetaCorrection.GetBinContent(iXBin, iThetaBin + 1);
150  double phiCor = phiCorrection.GetBinContent(iXBin + iPhiMech * nXBins, iPhiBin + 1);
151  double crysCor = crysCorrection.GetBinContent(iXBin, nCrys + 1);
152  const double cor0 = thetaCor * phiCor * crysCor;
153 
154  //..Correction from upper energy point
155  iXBin = iThetaID + (ie0 + 1) * nThetaID + 1;
156  thetaCor = thetaCorrection.GetBinContent(iXBin, iThetaBin + 1);
157  phiCor = phiCorrection.GetBinContent(iXBin + iPhiMech * nXBins, iPhiBin + 1);
158  crysCor = crysCorrection.GetBinContent(iXBin, nCrys + 1);
159  const double cor1 = thetaCor * phiCor * crysCor;
160 
161  //..Interpolate (in logE)
162  correction = cor0 + (cor1 - cor0) * (logEnergy - leakLogE[iRegion][ie0]) / (leakLogE[iRegion][ie0 + 1] - leakLogE[iRegion][ie0]);
163  }
164 
165  //-----------------------------------------------------------------
166  //..Apply correction
167  const double correctedEnergy = energyRaw / correction;
168  const double correctedEnergyHighest = energyRawHighest / correction;
169  B2DEBUG(28, "Correction factor=" << correction << ", correctedEnergy=" << correctedEnergy << ", correctedEnergyHighest=" <<
170  correctedEnergyHighest);
171 
172  //..Set the corrected energies
173  eclShower.setEnergy(correctedEnergy);
174  eclShower.setEnergyHighestCrystal(correctedEnergyHighest);
175 
176  } // end loop over showers
177 
178 }
179 
181 {
182  ;
183 }
184 
186 {
187  ;
188 }
DB object to store leakage corrections, including nCrys dependence
Class to perform the shower correction.
virtual void initialize() override
Initialize.
virtual void event() override
Event.
virtual void endRun() override
End run.
virtual void terminate() override
Terminate.
virtual void beginRun() override
Begin run.
@ c_nPhotons
CR is split into n photons (N1)
Definition: ECLShower.h:37
Class to get position information for a cluster for leakage corrections.
Base class for Modules.
Definition: Module.h:72
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.