10#include <ecl/modules/eclShowerCorrection/ECLShowerCorrectorModule.h>
13#include <framework/logging/Logger.h>
16#include <ecl/dbobjects/ECLLeakageCorrections.h>
17#include <ecl/dataobjects/ECLShower.h>
18#include <ecl/geometry/ECLLeakagePosition.h>
19#include <ecl/dataobjects/ECLElementNumbers.h>
35 m_eclShowers(eclShowerArrayName()),
36 m_eclLeakageCorrections(
"ECLLeakageCorrections")
40 setDescription(
"ECLShowerCorrectorModule: Corrects energy of ECLShowers and highest energy crystal for shower leakage, beam backgrounds, and clustering");
53 B2DEBUG(28,
"ECLShowerCorrectorModule::initialize()");
77 B2INFO(
"ECLShowerCorrector beginRun: Number of energies = " <<
nEnergies);
82 leakLogE[0][ie] = logEnergiesFwd[ie];
83 leakLogE[1][ie] = logEnergiesBrl[ie];
84 leakLogE[2][ie] = logEnergiesBwd[ie];
95 B2FATAL(
"ECLShowerCorrectorModule: missing eclLeakageCorrections payload");
117 B2FATAL(
"ECLShowerCorrectorModule: missing eclNOptimal payload");
152 const double energyRaw = eclShower.getEnergy();
153 const double energyRawHighest = eclShower.getEnergyHighestCrystal();
157 const int iGroup = eclShower.getNOptimalGroupIndex();
158 const int iEnergy = eclShower.getNOptimalEnergyBin();
159 const double e3x3 = eclShower.getNOptimalEnergy();
169 const int iy = iEnergy + 1;
171 const int ixNom = 3 * iGroup + 1;
172 const int ixLowerE = ixNom + 1;
173 const int ixHigherE = ixNom + 2;
177 const double logEHigher =
m_logPeakEnergy.GetBinContent(ixHigherE, iy);
179 const double biasNom =
m_bias.GetBinContent(ixNom, iy);
180 const double biasLower =
m_bias.GetBinContent(ixLowerE, iy);
181 const double biasHigher =
m_bias.GetBinContent(ixHigherE, iy);
188 const double logESumN = log(energyRaw);
190 double logEOther = logELower;
191 double biasOther = biasLower;
192 double peakOther = peakLower;
193 if (logESumN > logENom) {
194 logEOther = logEHigher;
195 biasOther = biasHigher;
196 peakOther = peakHigher;
200 double bias = biasNom;
201 double peak = peakNom;
202 if (std::abs(logEOther - logENom) > 0.0001) {
203 bias = biasNom + (biasOther - biasNom) * (logESumN - logENom) / (logEOther - logENom);
204 peak = peakNom + (peakOther - peakNom) * (logESumN - logENom) / (logEOther - logENom);
208 const double ePartialCorr = (energyRaw - bias) / peak;
214 const int icellIDMaxE = eclShower.getCentralCellId();
215 const float thetaLocation = eclShower.getTheta();
216 const float phiLocation = eclShower.getPhi();
221 const int iThetaID = positionVector[1];
222 const int iRegion = positionVector[2];
223 const int iThetaBin = positionVector[3];
224 const int iPhiBin = positionVector[4];
225 const int iPhiMech = positionVector[5];
229 float logEnergy = log(ePartialCorr);
231 if (logEnergy <
leakLogE[iRegion][0]) {
236 while (logEnergy >
leakLogE[iRegion][ie0 + 1]) {ie0++;}
241 int iXBin = iThetaID + ie0 *
nThetaID + 1;
244 const double cor0 = thetaCor * phiCor;
247 iXBin = iThetaID + (ie0 + 1) *
nThetaID + 1;
250 const double cor1 = thetaCor * phiCor;
253 const double positionCor = cor0 + (cor1 - cor0) * (logEnergy -
leakLogE[iRegion][ie0]) / (
leakLogE[iRegion][ie0 + 1] -
258 const double correctedEnergy = ePartialCorr / positionCor;
259 const double overallCorrection = energyRaw / correctedEnergy;
260 const double correctedEnergyHighest = energyRawHighest / overallCorrection;
263 eclShower.setEnergy(correctedEnergy);
264 eclShower.setEnergyHighestCrystal(correctedEnergyHighest);
266 B2DEBUG(28,
"ECLShowerCorrectorModule: cellID: " << positionVector[0] <<
" iG: " << iGroup <<
" iE: " << iEnergy <<
" Eraw: " <<
267 energyRaw <<
" E3x3: " << e3x3 <<
" Ecor: " << correctedEnergy);
268 B2DEBUG(28,
" peakNom: " << peakNom <<
" biasNom: " << biasNom <<
" positionCor: " << positionCor <<
" overallCor: " <<
275 uint16_t nShowersPerRegion[
nLeakReg] = {};
278 const int iCellId = eclShower.getCentralCellId();
static constexpr unsigned int nLeakReg
0 = forward, 1 = barrel, 2 = backward
virtual const char * eclShowerArrayName() const
We need names for the data objects to differentiate between PureCsI and default.
TH2F m_logPeakEnergy
log of peak energy (GeV) contained in nOptimal crystals
TH2F phiCorrection
histogram of phi-dependent corrections
StoreArray< ECLShower > m_eclShowers
Store array: ECLShower.
ECLShowerCorrectorModule()
Constructor.
virtual void initialize() override
Initialize.
virtual void event() override
Event.
const unsigned int nThetaID
69 thetaIDs
virtual void endRun() override
End run.
int nEnergies
number of energies for which there are leakage corrections
TH2F m_bias
2D histogram of bias = sum of ECLCalDigit energy minus true (GeV)
virtual void terminate() override
Terminate.
TH2F thetaCorrection
histogram of theta-dependent corrections
~ECLShowerCorrectorModule()
Destructor.
std::vector< std::vector< float > > leakLogE
log(E) values for each region
int nXBins
number of thetaID x energy bins
TH2F m_peakFracEnergy
2D histogram of peak fractional contained energy
DBObjPtr< ECLnOptimal > m_eclNOptimal
nOptimal payload: bias from beam background, and correction from number of crystals
virtual void beginRun() override
Begin run.
DBObjPtr< ECLLeakageCorrections > m_eclLeakageCorrections
Leakage correction from database: leakage correction as a function of position.
ECL::ECLLeakagePosition * m_leakagePosition
location of cluster; cellID and position within the crystal
int nPositionBins
number of locations across crystal
StoreObjPtr< EventLevelClusteringInfo > m_eventLevelClusteringInfo
EventLevelClusteringInfo.
@ c_nPhotons
CR is split into n photons (N1)
Class to get position information for a cluster for leakage corrections.
std::vector< int > getLeakagePosition(const int cellIDFromEnergy, const float theta, const float phi, const int nPositions)
Return position.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
bool isForward(int cellId)
Check whether the crystal is in forward ECL.
bool isBarrel(int cellId)
Check whether the crystal is in barrel ECL.
bool isBackward(int cellId)
Check whether the crystal is in backward ECL.
Abstract base class for different kinds of events.