Belle II Software development
eclLeakageCollectorModule.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/* Own header. */
10#include <ecl/modules/eclLeakageCollector/eclLeakageCollectorModule.h>
11
12/* ECL headers. */
13#include <ecl/dataobjects/ECLShower.h>
14#include <ecl/dataobjects/ECLCalDigit.h>
15#include <ecl/geometry/ECLLeakagePosition.h>
16#include <ecl/dataobjects/ECLElementNumbers.h>
17
18/* Basf2 headers. */
19#include <framework/dataobjects/EventMetaData.h>
20#include <framework/geometry/VectorUtil.h>
21#include <mdst/dataobjects/MCParticle.h>
22#include <mdst/dataobjects/EventLevelClusteringInfo.h>
23#include <mdst/dataobjects/ECLCluster.h>
24
25
26/* Root headers. */
27#include <Math/Vector3D.h>
28#include <Math/VectorUtil.h>
29#include <TTree.h>
30
31/* C++ headers. */
32#include <cmath>
33#include <iostream>
34
35using namespace Belle2;
36using namespace ECL;
37
38//-----------------------------------------------------------------
39// Register the Module
40//-----------------------------------------------------------------
41REG_MODULE(eclLeakageCollector);
42
43//-----------------------------------------------------------------
44// Implementation
45//-----------------------------------------------------------------
46
47//-----------------------------------------------------------------
49 m_mcParticleArray("MCParticles"),
50 m_evtMetaData("EventMetaData")
51{
53 setDescription("Store quantities from single photon MC used to calculated ECL energy leakage corrections");
55 addParam("position_bins", m_position_bins, "number of crystal subdivisions in theta and phi", 29);
56 addParam("number_energies", m_number_energies, "number of generated energies", 8);
57 addParam("energies_forward", m_energies_forward, "generated photon energies, forward", std::vector<double> {0.030, 0.050, 0.100, 0.200, 0.483, 1.166, 2.816, 6.800});
58 addParam("energies_barrel", m_energies_barrel, "generated photon energies, barrel", std::vector<double> {0.030, 0.050, 0.100, 0.200, 0.458, 1.049, 2.402, 5.500});
59 addParam("energies_backward", m_energies_backward, "generated photon energies, backward", std::vector<double> {0.030, 0.050, 0.100, 0.200, 0.428, 0.917, 1.962, 4.200});
60 addParam("showerArrayName", m_showerArrayName, "name of ECLShower data object", std::string("ECLTrimmedShowers"));
61}
62
63
64//-----------------------------------------------------------------
66{
67 //-----------------------------------------------------------------
68 //..Parameters and other basic info
69 B2INFO("eclLeakageCollector: Experiment = " << m_evtMetaData->getExperiment() << " run = " << m_evtMetaData->getRun());
70
71 //..Check that input parameters are consistent
72 const int n_e_forward = m_energies_forward.size();
73 const int n_e_barrel = m_energies_barrel.size();
74 const int n_e_backward = m_energies_backward.size();
75 if (n_e_forward != m_number_energies or n_e_barrel != m_number_energies or n_e_backward != m_number_energies) {
76 B2FATAL("eclLeakageCollector: length of energy vectors inconsistent with parameter number_energies: " << n_e_forward << " " <<
77 n_e_barrel << " " << n_e_backward << " " << m_number_energies);
78 }
79
80 //..Store generated energies as integers in MeV
81 i_energies.resize(nLeakReg, std::vector<int>(m_number_energies, 0));
82 for (int ie = 0; ie < m_number_energies; ie++) {
83 i_energies[0][ie] = (int)(1000.*m_energies_forward[ie] + 0.5);
84 i_energies[1][ie] = (int)(1000.*m_energies_barrel[ie] + 0.5);
85 i_energies[2][ie] = (int)(1000.*m_energies_backward[ie] + 0.5);
86 }
87
88 //..Require all energies are different, and that there are at least two
89 if (m_number_energies < 2) {
90 B2FATAL("eclLeakageCollector: require at least two energy points. m_number_energies = " << m_number_energies);
91 }
92 for (int ie = 0; ie < m_number_energies - 1; ie++) {
93 for (int ireg = 0; ireg < nLeakReg; ireg++) {
94 if (i_energies[ireg][ie] == i_energies[ireg][ie + 1]) {
95 B2FATAL("eclLeakageCollector: identical energies, ireg = " << ireg << ", " << i_energies[ireg][ie] << " MeV");
96 }
97 }
98 }
99
100 //-----------------------------------------------------------------
101 //..Write out the input parameters
102 B2INFO("eclLeakageCollector parameters: ");
103 B2INFO("position_bins " << m_position_bins);
104 B2INFO("number_energies " << m_number_energies);
105 std::cout << "energies_forward ";
106 for (int ie = 0; ie < m_number_energies; ie++) {std::cout << m_energies_forward[ie] << " ";}
107 std::cout << std::endl;
108 std::cout << "energies_barrel ";
109 for (int ie = 0; ie < m_number_energies; ie++) {std::cout << m_energies_barrel[ie] << " ";}
110 std::cout << std::endl;
111 std::cout << "energies_backward ";
112 for (int ie = 0; ie < m_number_energies; ie++) {std::cout << m_energies_backward[ie] << " ";}
113 std::cout << std::endl;
114 B2INFO("showerArrayName " << m_showerArrayName);
115
116 //-----------------------------------------------------------------
117 //..Define histogram to store parameters
118 const int nBinX = 3 + nLeakReg * m_number_energies;
119 auto inputParameters = new TH1F("inputParameters", "eclLeakageCollector job parameters", nBinX, 0, nBinX);
120 registerObject<TH1F>("inputParameters", inputParameters);
121
122 //..TTree stores required quantities for each photon
123 auto tree = new TTree("single_photon_leakage", "");
124 tree->Branch("cellID", &t_cellID, "cellID/I");
125 tree->Branch("thetaID", &t_thetaID, "thetaID/I");
126 tree->Branch("region", &t_region, "region/I");
127 tree->Branch("thetaBin", &t_thetaBin, "thetaBin/I");
128 tree->Branch("phiBin", &t_phiBin, "phiBin/I");
129 tree->Branch("phiMech", &t_phiMech, "phiMech/I");
130 tree->Branch("energyBin", &t_energyBin, "energyBin/I");
131 tree->Branch("nCrys", &t_nCrys, "nCrys/I");
132 tree->Branch("energyFrac", &t_energyFrac, "energyFrac/F");
133 tree->Branch("origEnergyFrac", &t_origEnergyFrac, "origEnergyFrac/F");
134 tree->Branch("locationError", &t_locationError, "locationError/F");
135 registerObject<TTree>("tree", tree);
136
137
138 //-----------------------------------------------------------------
139 //..Class to find cellID and position within crystal from theta and phi
140 std::cout << "creating leakagePosition object " << std::endl;
142
143 //-----------------------------------------------------------------
144 //..Required arrays
146 m_mcParticleArray.isRequired();
147 m_eventLevelClusteringInfo.isRequired();
148 m_eclClusterArray.isRequired("ECLClusters");
149
150
151 //-----------------------------------------------------------------
152 //..nOptimal payload. Get optimal number of crystals, and
153 // corresponding correction factors.
154 m_nOptimal2D = m_eclNOptimal->getNOptimal();
155 m_peakFracEnergy = m_eclNOptimal->getPeakFracEnergy();
156 m_bias = m_eclNOptimal->getBias();
157 m_logPeakEnergy = m_eclNOptimal->getLogPeakEnergy();
158 m_groupNumber = m_eclNOptimal->getGroupNumber();
159
160 //..Vectors of energy boundaries for each region
161 std::vector<float> eBoundariesFwd = m_eclNOptimal->getUpperBoundariesFwd();
162 std::vector<float> eBoundariesBrl = m_eclNOptimal->getUpperBoundariesBrl();
163 std::vector<float> eBoundariesBwd = m_eclNOptimal->getUpperBoundariesBwd();
164 m_nEnergyBins = eBoundariesBrl.size();
165
166 //..Copy values to m_eBoundaries
167 m_eBoundaries.resize(m_nLeakReg, std::vector<float>(m_nEnergyBins, 0.));
168 for (int ie = 0; ie < m_nEnergyBins; ie++) {
169 m_eBoundaries[0][ie] = eBoundariesFwd[ie];
170 m_eBoundaries[1][ie] = eBoundariesBrl[ie];
171 m_eBoundaries[2][ie] = eBoundariesBwd[ie];
172 B2INFO(" nOptimal upper boundaries for energy point " << ie << " " << m_eBoundaries[0][ie] << " " << m_eBoundaries[1][ie] << " " <<
173 m_eBoundaries[2][ie]);
174 }
175
176}
177
178//-----------------------------------------------------------------
180{
181
182 //-----------------------------------------------------------------
183 //..First time, store the job parameters
184 if (storeCalib) {
185 getObjectPtr<TH1F>("inputParameters")->Fill(0.01, m_position_bins);
186 getObjectPtr<TH1F>("inputParameters")->Fill(1.01, m_number_energies);
187 double firstBin = 2.01;
188 for (int ie = 0; ie < m_number_energies; ie++) {
189 getObjectPtr<TH1F>("inputParameters")->Fill(firstBin + ie, m_energies_forward[ie]);
190 }
191 firstBin += m_number_energies;
192 for (int ie = 0; ie < m_number_energies; ie++) {
193 getObjectPtr<TH1F>("inputParameters")->Fill(firstBin + ie, m_energies_barrel[ie]);
194 }
195 firstBin += m_number_energies;
196 for (int ie = 0; ie < m_number_energies; ie++) {
197 getObjectPtr<TH1F>("inputParameters")->Fill(firstBin + ie, m_energies_backward[ie]);
198 }
199
200 //..Keep track of how many times inputParameters was filled
201 int lastBin = getObjectPtr<TH1F>("inputParameters")->GetNbinsX();
202 getObjectPtr<TH1F>("inputParameters")->SetBinContent(lastBin, 1.);
203 storeCalib = false;
204 }
205
206 //-----------------------------------------------------------------
207 //..Generated MC particle. Should only be one entry, but check.
208 const int nMC = m_mcParticleArray.getEntries();
209 if (nMC != 1) {return;}
210 double mcLabE = m_mcParticleArray[0]->getEnergy();
211 ROOT::Math::XYZVector mcp3 = m_mcParticleArray[0]->getMomentum();
212 ROOT::Math::XYZVector vertex = m_mcParticleArray[0]->getProductionVertex();
213
214 //-----------------------------------------------------------------
215 //..Find the ECLShower (should only be one when using trimmed data object)
216 const int nShower = m_eclShowerArray.getEntries();
217 double minAngle = 999.;
218 int minShower = -1;
219 for (int is = 0; is < nShower; is++) {
220
221 //..Only interested in photon hypothesis showers
222 if (m_eclShowerArray[is]->getHypothesisId() == ECLShower::c_nPhotons) {
223
224 //..Make a position vector from theta, phi, and R
225 ROOT::Math::XYZVector position;
226 VectorUtil::setMagThetaPhi(
227 position, m_eclShowerArray[is]->getR(),
228 m_eclShowerArray[is]->getTheta(), m_eclShowerArray[is]->getPhi());
229
230 //..Direction is difference between position and vertex
231 ROOT::Math::XYZVector direction = ROOT::Math::XYZVector(position) - vertex;
232
233 double angle = ROOT::Math::VectorUtil::Angle(direction, mcp3);
234 if (angle < minAngle) {
235 minAngle = angle;
236 minShower = is;
237 }
238 }
239 }
240 if (minShower == -1) {return;}
241
242 //-----------------------------------------------------------------
243 //..Location of selected shower.
244 const int maxECellId = m_eclShowerArray[minShower]->getCentralCellId();
245 const float thetaLocation = m_eclShowerArray[minShower]->getTheta();
246 const float phiLocation = m_eclShowerArray[minShower]->getPhi();
247 std::vector<int> positionVector = leakagePosition->getLeakagePosition(maxECellId, thetaLocation, phiLocation, m_position_bins);
248
249 //..TTree items
250 t_cellID = positionVector[0];
251 t_thetaID = positionVector[1];
252 t_region = positionVector[2];
253 t_thetaBin = positionVector[3];
254 t_phiBin = positionVector[4];
255 t_phiMech = positionVector[5];
256
257 //-----------------------------------------------------------------
258 //..Generated and reconstructed energy quantities
259
260 //..Find the generated energy bin by requiring it be close enough to expected value
261 const float genEnergyMeV = 1000.*mcLabE;
262 const float tolerance = std::max(0.002 * genEnergyMeV, 1.0);
263 t_energyBin = -1;
264 for (int ie = 0; ie < m_number_energies; ie++) {
265 if (std::abs(genEnergyMeV - i_energies[t_region][ie]) < tolerance) {
266 t_energyBin = ie;
267 break;
268 }
269 }
270
271 //..Quit if the true energy is not equal to a generated one.
272 // This can happen if the cluster is reconstructed in the wrong region.
273 if (t_energyBin == -1) {return;}
274
275 //..Reconstructed energy after existing leakage correction, normalized to generated
276 t_origEnergyFrac = m_eclShowerArray[minShower]->getEnergy() / mcLabE;
277
278 //..Sum of nOptimal crystals (without leakage correction), when events were generated
279 const double eRaw = m_eclShowerArray[minShower]->getEnergyRaw();
280
281 //-----------------------------------------------------------------
282 //..Find nOptimal from cellID and 3x3 energy found by ECLSplitterN1Module.
283 // Note that payload may have been updated since events were generated, so
284 // we need to redo the sum of energies of the nOptimal crystals.
285 const int ig = m_groupNumber[maxECellId - 1];
286 const double e3x3Orig = m_eclShowerArray[minShower]->getNOptimalEnergy();
287 double e3x3 = e3x3Orig;
288
289 //..Alternate e3x3, for samples produced before nOptimal was introduced
290 const double eHighestCorr = m_eclShowerArray[minShower]->getEnergyHighestCrystal();
291 const double correction = m_eclShowerArray[minShower]->getEnergy() / m_eclShowerArray[minShower]->getEnergyRaw();
292 const double eHighestRaw = eHighestCorr / correction;
293 const double e3x3Alt = eHighestRaw / m_eclShowerArray[minShower]->getE1oE9();
294 if (e3x3 < 0.001) {e3x3 = e3x3Alt;}
295
296 //..Need the detector region to get the energy bin boundaries
297 int iRegion = 1; // barrel
298 if (ECLElementNumbers::isForward(maxECellId)) {iRegion = 0;}
299 if (ECLElementNumbers::isBackward(maxECellId)) {iRegion = 2;}
300
301 //..nOptimal energy bin for this energy.
302 int iEnergy = 0;
303 while (e3x3 > m_eBoundaries[iRegion][iEnergy] and iEnergy < m_nEnergyBins - 1) {iEnergy++;}
304
305 //..nOptimal
306 t_nCrys = m_nOptimal2D.GetBinContent(ig + 1, iEnergy + 1);
307
308 //-----------------------------------------------------------------
309 //..Find the sum of the nOptimal most-energetic digits
310
311 //..Get the ECLCalDigits and rank them by energy
312 std::vector<double> digitEnergies;
313 const auto showerDigitRelations = m_eclShowerArray[minShower]->getRelationsWith<ECLCalDigit>("ECLTrimmedDigits");
314 unsigned int nRelatedDigits = showerDigitRelations.size();
315 for (unsigned int ir = 0; ir < nRelatedDigits; ir++) {
316 const auto calDigit = showerDigitRelations.object(ir);
317 const auto weight = showerDigitRelations.weight(ir);
318 digitEnergies.push_back(calDigit->getEnergy() * weight);
319 }
320
321 //..Rank from lowest to highest
322 std::sort(digitEnergies.begin(), digitEnergies.end());
323
324 //..Sum the highest nOptimal digit energies (if there are that many)
325 double eSumOfN = 1.e-10; // cpp does not like 0
326 for (int isum = 0; isum < t_nCrys; isum++) {
327 const int i = (int)nRelatedDigits - 1 - isum;
328 if (i >= 0) {eSumOfN += digitEnergies[i];}
329 }
330
331 //-----------------------------------------------------------------
332 //..Correct the sum of nOptimal crystals for bias and nCrystal peak energy
333 // We need to do this because the nOptimal payload may have changed
334 // since the events were generated.
335
336 //..To allow for energy interpolation, there are three bins per group and energy:
337 // iy = iEnergy + 1 in all three cases
338 // ix = 3*ig + 1 = value for nominal energy, i.e logPeakEnergy(3*ig+1, iEnergy+1)
339 // ix = 3*ig + 2 = value for lower energy, i.e logPeakEnergy(3*ig+2, iEnergy+1)
340 // ix = 3*ig + 3 = value for higher energy, i.e logPeakEnergy(3*ig+3, iEnergy+1)
341 const int iy = iEnergy + 1;
342
343 const int ixNom = 3 * ig + 1;
344 const int ixLowerE = ixNom + 1;
345 const int ixHigherE = ixNom + 2;
346
347 const double logENom = m_logPeakEnergy.GetBinContent(ixNom, iy);
348 const double logELower = m_logPeakEnergy.GetBinContent(ixLowerE, iy);
349 const double logEHigher = m_logPeakEnergy.GetBinContent(ixHigherE, iy);
350
351 const double biasNom = m_bias.GetBinContent(ixNom, iy);
352 const double biasLower = m_bias.GetBinContent(ixLowerE, iy);
353 const double biasHigher = m_bias.GetBinContent(ixHigherE, iy);
354
355 const double peakNom = m_peakFracEnergy.GetBinContent(ixNom, iy);
356 const double peakLower = m_peakFracEnergy.GetBinContent(ixLowerE, iy);
357 const double peakHigher = m_peakFracEnergy.GetBinContent(ixHigherE, iy);
358
359 //..Interpolate in log energy
360 const double logESumN = log(eSumOfN);
361
362 double logEOther = logELower;
363 double biasOther = biasLower;
364 double peakOther = peakLower;
365 if (logESumN > logENom) {
366 logEOther = logEHigher;
367 biasOther = biasHigher;
368 peakOther = peakHigher;
369 }
370
371 //..The nominal and "other" energies may be identical if this is the first or last energy
372 double bias = biasNom;
373 double peak = peakNom;
374 if (std::abs(logEOther - logENom) > 0.0001) {
375 bias = biasNom + (biasOther - biasNom) * (logESumN - logENom) / (logEOther - logENom);
376 peak = peakNom + (peakOther - peakNom) * (logESumN - logENom) / (logEOther - logENom);
377 }
378
379 //..Normalized reconstructed energy after bias and nCrystal correction
380 t_energyFrac = (eSumOfN - bias) / peak / mcLabE;
381
382 //-----------------------------------------------------------------
383 //..Distance between generated and reconstructed positions
384 const double radius = m_eclShowerArray[minShower]->getR();
385 ROOT::Math::XYZVector measuredLocation;
386 VectorUtil::setMagThetaPhi(
387 measuredLocation, radius, thetaLocation, phiLocation);
388 ROOT::Math::XYZVector measuredDirection = ROOT::Math::XYZVector(measuredLocation) - vertex;
389 t_locationError = radius * ROOT::Math::VectorUtil::Angle(measuredDirection, mcp3);
390
391
392 //--------------------------------------------------------
393 //..Clean up the sample
394
395 //..Get the related ECLCluster
396 double timing = -1000.;
397 double eMCTotal = 0.;
398
399 const auto showerClusterRelations = m_eclShowerArray[minShower]->getRelationsWith<ECLCluster>();
400 const unsigned int nRelatedClusters = showerClusterRelations.size();
401 if (nRelatedClusters > 0) {
402 const auto cluster = showerClusterRelations.object(0);
403 timing = cluster->getTime();
404
405 //..Associated MC true energy
406 const auto clusterMCRelations = cluster->getRelationsWith<MCParticle>();
407 for (unsigned int ir = 0; ir < clusterMCRelations.size(); ++ir) {
408 eMCTotal += clusterMCRelations.weight(ir);
409 }
410 }
411
412 //..True energy content of cluster must be >15% of generated
413 const double minTrueFrac = 0.15;
414 if (eMCTotal < minTrueFrac * mcLabE) {return;}
415
416 //..Standard timing cut
417 const double maxClusterTiming = 200.;
418 if (abs(timing) > maxClusterTiming) {return;}
419
420 //..Out of time crystals.
421 double OutOfTime = m_eventLevelClusteringInfo->getNECLCalDigitsOutOfTime();
422 const double maxOutOfTime = 900.;
423 if (OutOfTime > maxOutOfTime) {return;}
424
425
426 //-----------------------------------------------------------------
427 //..Debug: dump some events
428 if (m_nDump < 100) {
429 m_nDump++;
430 B2INFO(" ");
431 B2INFO("cellID " << t_cellID << " ig " << ig << " iEnergy " << iEnergy << " ie " << t_energyBin << " nOpt " << t_nCrys);
432 B2INFO(" e3x3Orig " << e3x3Orig << " e3x3Alt " << e3x3Alt << " Eraw " << eRaw << " ESum " << eSumOfN << " eFrac " <<
434 B2INFO(" 3 log E " << logELower << " " << logENom << " " << logEHigher << " log E " << logESumN);
435 B2INFO(" 3 biases " << biasLower << " " << biasNom << " " << biasHigher << " bias " << bias);
436 B2INFO(" 3 peaks " << peakLower << " " << peakNom << " " << peakHigher << " peak " << peak);
437 }
438
439 //-----------------------------------------------------------------
440 //..Done
441 getObjectPtr<TTree>("tree")->Fill();
442}
443
void registerObject(const std::string &name, T *obj)
Register object with a name, takes ownership, do not access the pointer beyond prepare()
T * getObjectPtr(const std::string &name)
Calls the CalibObjManager to get the requested stored collector data.
CalibrationCollectorModule()
Constructor. Sets the default prefix for calibration dataobjects.
Class to store calibrated ECLDigits: ECLCalDigits.
Definition ECLCalDigit.h:23
ECL cluster data.
Definition ECLCluster.h:27
@ c_nPhotons
CR is split into n photons (N1)
Definition ECLShower.h:42
Class to get position information for a cluster for leakage corrections.
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
StoreArray< MCParticle > m_mcParticleArray
Required input array of MCParticles.
eclLeakageCollectorModule()
Constructor: Sets the description, the properties and the parameters of the module.
StoreArray< ECLShower > m_eclShowerArray
Required input array of ECLShowers.
TH2F m_logPeakEnergy
log of peak contained energy in GeV
float t_energyFrac
measured energy without leakage correction divided by generated
const int m_nLeakReg
3 ECL regions: 0 = forward, 1 = barrel, 2 = backward
float t_locationError
reconstructed minus generated position (cm)
std::vector< double > m_energies_forward
generated photon energies, forward
const int nLeakReg
Some other useful quantities.
StoreArray< ECLCluster > m_eclClusterArray
Array of ECLClusters.
int m_number_energies
number of generated energies (8)
std::vector< std::vector< int > > i_energies
Generated energies in MeV in each region.
bool storeCalib
store parameters first event
TH2F m_bias
2D histogram of bias = sum of ECLCalDigit energy minus true (GeV)
TH2F m_peakFracEnergy
2D histogram of peak fractional contained energy
virtual void collect() override
Accumulate TTree.
std::string m_showerArrayName
Required arrays.
StoreObjPtr< EventMetaData > m_evtMetaData
dataStore EventMetaData
DBObjPtr< ECLnOptimal > m_eclNOptimal
nOptimal payload
std::vector< double > m_energies_backward
generated photon energies, backward
ECL::ECLLeakagePosition * leakagePosition
location of position of cluster
virtual void prepare() override
Define histograms and read payloads from DB.
int t_phiBin
binned location in phi relative to crystal edge.
int t_phiMech
0: mechanical structure next to phi edge; 1: no mech structure
int t_region
region of photon 0=forward 1=barrel 2=backward
int m_nEnergyBins
number of energies bins in nOptimal payload
int t_thetaBin
binned location in theta relative to crystal edge
int t_nCrys
number of crystals used to calculate energy
std::vector< double > m_energies_barrel
generated photon energies, barrel
int m_position_bins
Parameters to pass along to the algorithm.
StoreObjPtr< EventLevelClusteringInfo > m_eventLevelClusteringInfo
EventLevelClusteringInfo.
float t_origEnergyFrac
original leakage-corrected energy / generated
std::vector< std::vector< float > > m_eBoundaries
energy boundaries each region
TH2F m_nOptimal2D
2D hist of nOptimal for Ebin vs groupID
std::vector< int > m_groupNumber
group number for each crystal
int m_nDump
Number of events with diagnostic printouts.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
bool isForward(int cellId)
Check whether the crystal is in forward ECL.
bool isBackward(int cellId)
Check whether the crystal is in backward ECL.
Abstract base class for different kinds of events.