10#include <ecl/modules/eclLeakageCollector/eclLeakageCollectorModule.h>
13#include <ecl/dataobjects/ECLShower.h>
14#include <ecl/dataobjects/ECLCalDigit.h>
15#include <ecl/geometry/ECLLeakagePosition.h>
16#include <ecl/dataobjects/ECLElementNumbers.h>
19#include <framework/dataobjects/EventMetaData.h>
20#include <framework/geometry/VectorUtil.h>
21#include <mdst/dataobjects/MCParticle.h>
24#include <Math/Vector3D.h>
25#include <Math/VectorUtil.h>
45 m_mcParticleArray(
"MCParticles"),
46 m_evtMetaData(
"EventMetaData")
49 setDescription(
"Store quantities from single photon MC used to calculated ECL energy leakage corrections");
53 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});
54 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});
55 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});
72 B2FATAL(
"eclLeakageCollector: length of energy vectors inconsistent with parameter number_energies: " << n_e_forward <<
" " <<
86 B2FATAL(
"eclLeakageCollector: require at least two energy points. m_number_energies = " <<
m_number_energies);
89 for (
int ireg = 0; ireg <
nLeakReg; ireg++) {
91 B2FATAL(
"eclLeakageCollector: identical energies, ireg = " << ireg <<
", " <<
i_energies[ireg][ie] <<
" MeV");
98 B2INFO(
"eclLeakageCollector parameters: ");
101 std::cout <<
"energies_forward ";
103 std::cout << std::endl;
104 std::cout <<
"energies_barrel ";
106 std::cout << std::endl;
107 std::cout <<
"energies_backward ";
109 std::cout << std::endl;
115 auto inputParameters =
new TH1F(
"inputParameters",
"eclLeakageCollector job parameters", nBinX, 0, nBinX);
116 registerObject<TH1F>(
"inputParameters", inputParameters);
119 auto tree =
new TTree(
"single_photon_leakage",
"");
120 tree->Branch(
"cellID", &
t_cellID,
"cellID/I");
121 tree->Branch(
"thetaID", &
t_thetaID,
"thetaID/I");
122 tree->Branch(
"region", &
t_region,
"region/I");
123 tree->Branch(
"thetaBin", &
t_thetaBin,
"thetaBin/I");
124 tree->Branch(
"phiBin", &
t_phiBin,
"phiBin/I");
125 tree->Branch(
"phiMech", &
t_phiMech,
"phiMech/I");
126 tree->Branch(
"energyBin", &
t_energyBin,
"energyBin/I");
127 tree->Branch(
"nCrys", &
t_nCrys,
"nCrys/I");
128 tree->Branch(
"energyFrac", &
t_energyFrac,
"energyFrac/F");
131 registerObject<TTree>(
"tree", tree);
136 std::cout <<
"creating leakagePosition object " << std::endl;
154 std::vector<float> eBoundariesFwd =
m_eclNOptimal->getUpperBoundariesFwd();
155 std::vector<float> eBoundariesBrl =
m_eclNOptimal->getUpperBoundariesBrl();
156 std::vector<float> eBoundariesBwd =
m_eclNOptimal->getUpperBoundariesBwd();
165 B2INFO(
" nOptimal upper boundaries for energy point " << ie <<
" " <<
m_eBoundaries[0][ie] <<
" " <<
m_eBoundaries[1][ie] <<
" " <<
180 double firstBin = 2.01;
186 getObjectPtr<TH1F>(
"inputParameters")->Fill(firstBin + ie,
m_energies_barrel[ie]);
194 int lastBin = getObjectPtr<TH1F>(
"inputParameters")->GetNbinsX();
195 getObjectPtr<TH1F>(
"inputParameters")->SetBinContent(lastBin, 1.);
202 if (nMC != 1) {
return;}
210 double minAngle = 999.;
212 for (
int is = 0; is < nShower; is++) {
218 ROOT::Math::XYZVector position;
219 VectorUtil::setMagThetaPhi(
224 ROOT::Math::XYZVector direction = ROOT::Math::XYZVector(position) - vertex;
226 double angle = ROOT::Math::VectorUtil::Angle(direction, mcp3);
227 if (angle < minAngle) {
233 if (minShower == -1) {
return;}
254 const float genEnergyMeV = 1000.*mcLabE;
255 const float tolerance = std::max(0.002 * genEnergyMeV, 1.0);
280 double e3x3 = e3x3Orig;
283 const double eHighestCorr =
m_eclShowerArray[minShower]->getEnergyHighestCrystal();
285 const double eHighestRaw = eHighestCorr / correction;
286 const double e3x3Alt = eHighestRaw /
m_eclShowerArray[minShower]->getE1oE9();
287 if (e3x3 < 0.001) {e3x3 = e3x3Alt;}
305 std::vector<double> digitEnergies;
307 unsigned int nRelatedDigits = showerDigitRelations.size();
308 for (
unsigned int ir = 0; ir < nRelatedDigits; ir++) {
309 const auto calDigit = showerDigitRelations.object(ir);
310 const auto weight = showerDigitRelations.weight(ir);
311 digitEnergies.push_back(calDigit->getEnergy() * weight);
315 std::sort(digitEnergies.begin(), digitEnergies.end());
318 double eSumOfN = 1.e-10;
319 for (
int isum = 0; isum <
t_nCrys; isum++) {
320 const int i = (int)nRelatedDigits - 1 - isum;
321 if (i >= 0) {eSumOfN += digitEnergies[i];}
334 const int iy = iEnergy + 1;
336 const int ixNom = 3 * ig + 1;
337 const int ixLowerE = ixNom + 1;
338 const int ixHigherE = ixNom + 2;
342 const double logEHigher =
m_logPeakEnergy.GetBinContent(ixHigherE, iy);
344 const double biasNom =
m_bias.GetBinContent(ixNom, iy);
345 const double biasLower =
m_bias.GetBinContent(ixLowerE, iy);
346 const double biasHigher =
m_bias.GetBinContent(ixHigherE, iy);
353 const double logESumN = log(eSumOfN);
355 double logEOther = logELower;
356 double biasOther = biasLower;
357 double peakOther = peakLower;
358 if (logESumN > logENom) {
359 logEOther = logEHigher;
360 biasOther = biasHigher;
361 peakOther = peakHigher;
365 double bias = biasNom;
366 double peak = peakNom;
367 if (abs(logEOther - logENom) > 0.0001) {
368 bias = biasNom + (biasOther - biasNom) * (logESumN - logENom) / (logEOther - logENom);
369 peak = peakNom + (peakOther - peakNom) * (logESumN - logENom) / (logEOther - logENom);
378 ROOT::Math::XYZVector measuredLocation;
379 VectorUtil::setMagThetaPhi(
380 measuredLocation, radius, thetaLocation, phiLocation);
381 ROOT::Math::XYZVector measuredDirection = ROOT::Math::XYZVector(measuredLocation) - vertex;
382 t_locationError = radius * ROOT::Math::VectorUtil::Angle(measuredDirection, mcp3);
391 B2INFO(
" e3x3Orig " << e3x3Orig <<
" e3x3Alt " << e3x3Alt <<
" Eraw " << eRaw <<
" ESum " << eSumOfN <<
" eFrac " <<
393 B2INFO(
" 3 log E " << logELower <<
" " << logENom <<
" " << logEHigher <<
" log E " << logESumN);
394 B2INFO(
" 3 biases " << biasLower <<
" " << biasNom <<
" " << biasHigher <<
" bias " << bias);
395 B2INFO(
" 3 peaks " << peakLower <<
" " << peakNom <<
" " << peakHigher <<
" peak " << peak);
400 getObjectPtr<TTree>(
"tree")->Fill();
Calibration collector module base class.
Class to store calibrated ECLDigits: ECLCalDigits.
@ 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...
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
int getEntries() const
Get the number of objects in the array.
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
int t_energyBin
generated energy point
const int nLeakReg
Some other useful quantities.
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
int t_thetaID
thetaID of photon
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.
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 ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#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 isBackward(int cellId)
Check whether the crystal is in backward ECL.
Abstract base class for different kinds of events.