11 #include <ecl/modules/eclee5x5Collector/eclee5x5CollectorModule.h>
17 #include <analysis/ClusterUtility/ClusterUtils.h>
20 #include <framework/dataobjects/EventMetaData.h>
21 #include <framework/datastore/RelationVector.h>
24 #include <mdst/dataobjects/TRGSummary.h>
25 #include <mdst/dataobjects/ECLCluster.h>
28 #include <ecl/dataobjects/ECLDigit.h>
29 #include <ecl/dataobjects/ECLCalDigit.h>
30 #include <ecl/dbobjects/ECLCrystalCalib.h>
49 m_ECLExpee5x5E("ECLExpee5x5E"), m_ElectronicsCalib("ECLCrystalElectronics"), m_ee5x5Calib("ECLCrystalEnergyee5x5"),
50 m_selectdPhiData("ECLeedPhiData"), m_selectdPhiMC("ECLeedPhiMC")
53 setDescription(
"Calibration Collector Module for ECL single crystal energy calibration using Bhabha events");
54 setPropertyFlags(c_ParallelProcessingCertified);
55 addParam(
"thetaLabMinDeg", m_thetaLabMinDeg,
"miniumum ecl cluster theta in lab (degrees)", 17.);
56 addParam(
"thetaLabMaxDeg", m_thetaLabMaxDeg,
"maximum ecl cluster theta in lab (degrees)", 150.);
57 addParam(
"minE0", m_minE0,
"minimum energy of cluster 0: E*0/sqrts", 0.45);
58 addParam(
"minE1", m_minE1,
"minimum energy of cluster 1: E*1/sqrts", 0.40);
59 addParam(
"maxdThetaSum", m_maxdThetaSum,
"maximum diff between 180 deg and sum of cluster theta* (deg)", 2.);
60 addParam(
"dPhiScale", m_dPhiScale,
"scale dPhi* cut by this factor", 1.);
61 addParam(
"maxTime", m_maxTime,
"maximum cluster time diff abs(t1-t0)/dt99", 10.);
62 addParam(
"useCalDigits", m_useCalDigits,
"use MC events to obtain expected energies",
false);
63 addParam(
"requireL1", m_requireL1,
"only use events that have a level 1 trigger",
false);
70 void eclee5x5CollectorModule::prepare()
74 m_sqrts = m_boostrotate.getCMSEnergy();
75 B2INFO(
"eclee5x5Collector: Experiment = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun() <<
" sqrts = "
81 auto EnVsCrysID =
new TH2F(
"EnVsCrysID",
"Normalized 5x5 energy for each crystal;crystal ID;E25/Expected", 8736, 0, 8736, 200, 0.7,
83 registerObject<TH2F>(
"EnVsCrysID", EnVsCrysID);
85 auto RvsCrysID =
new TH1F(
"RvsCrysID",
"E_exp x E_crysID / sigma^2;crysID;sum of E_exp x E_crysID/sigma^2", 8736, 0, 8736);
86 registerObject(
"RvsCrysID", RvsCrysID);
88 auto NRvsCrysID =
new TH1F(
"NRvsCrysID",
"Entries in RvsCrysID vs crysID;crysID;Entries in RvsCrysID", 8736, 0, 8736);
89 registerObject(
"NRvsCrysID", NRvsCrysID);
91 auto Qmatrix =
new TH2F(
"Qmatrix",
"E_i x E_j/sigma^2;crysID i;crysID j", 8736, 0, 8736, 8736, 0, 8736);
92 registerObject(
"Qmatrix", Qmatrix);
95 auto ElecCalibvsCrys =
new TH1F(
"ElecCalibvsCrys",
"Sum electronics calib const vs crystal ID;crystal ID;calibration constant",
97 registerObject<TH1F>(
"ElecCalibvsCrys", ElecCalibvsCrys);
98 auto ExpEvsCrys =
new TH1F(
"ExpEvsCrys",
"Sum expected energy calib const vs crystalID;crystal ID;calibration constant", 8736, 0,
100 registerObject<TH1F>(
"ExpEvsCrys", ExpEvsCrys);
101 auto InitialCalibvsCrys =
new TH1F(
"InitialCalibvsCrys",
"Sum initial calib const vs crystal ID;crystal ID;calibration constant",
103 registerObject<TH1F>(
"InitialCalibvsCrys", InitialCalibvsCrys);
105 auto CalibEntriesvsCrys =
new TH1F(
"CalibEntriesvsCrys",
"Entries in calib vs crys histograms;crystal ID;Entries per crystal", 8736,
107 registerObject<TH1F>(
"CalibEntriesvsCrys", CalibEntriesvsCrys);
109 auto EntriesvsCrys =
new TH1F(
"EntriesvsCrys",
"Selected Bhabha clusters vs crystal ID;crystal ID;Entries", 8736, 0, 8736);
110 registerObject<TH1F>(
"EntriesvsCrys", EntriesvsCrys);
112 auto dPhivsThetaID =
new TH2F(
"dPhivsThetaID",
113 "Phi* vs thetaID forward, pass thetaSum,E0,E1;thetaID of forward cluster;dPhi COM (deg)", 69, 0, 69, 150, 165, 180);
114 registerObject<TH2F>(
"dPhivsThetaID", dPhivsThetaID);
118 B2INFO(
"Input parameters to eclee5x5Collector:");
119 B2INFO(
"thetaLabMinDeg: " << m_thetaLabMinDeg);
120 B2INFO(
"thetaLabMaxDeg: " << m_thetaLabMaxDeg);
121 m_thetaLabMin = m_thetaLabMinDeg / TMath::RadToDeg();
122 m_thetaLabMax = m_thetaLabMaxDeg / TMath::RadToDeg();
123 B2INFO(
"minE0: " << m_minE0);
124 B2INFO(
"minE1: " << m_minE1);
125 B2INFO(
"maxdThetaSum: " << m_maxdThetaSum);
126 B2INFO(
"dPhiScale: " << m_dPhiScale);
127 B2INFO(
"maxTime: " << m_maxTime);
128 B2INFO(
"useCalDigits: " << m_useCalDigits);
129 B2INFO(
"requireL1: " << m_requireL1);
132 EperCrys.resize(8736);
133 m_thetaID.resize(8736);
140 if (m_ECLExpee5x5E.hasChanged()) {
141 Expee5x5E = m_ECLExpee5x5E->getCalibVector();
142 Expee5x5Sigma = m_ECLExpee5x5E->getCalibUncVector();
144 if (m_ElectronicsCalib.hasChanged()) {ElectronicsCalib = m_ElectronicsCalib->getCalibVector();}
145 if (m_ee5x5Calib.hasChanged()) {ee5x5Calib = m_ee5x5Calib->getCalibVector();}
146 if (m_selectdPhiMC.hasChanged() and m_useCalDigits) {
147 meandPhi = m_selectdPhiMC->getCalibVector();
148 widthdPhi = m_selectdPhiMC->getCalibUncVector();
149 }
else if (m_selectdPhiData.hasChanged()) {
150 meandPhi = m_selectdPhiData->getCalibVector();
151 widthdPhi = m_selectdPhiData->getCalibUncVector();
155 for (
int ic = 1; ic < 9000; ic += 1000) {
156 B2INFO(
"DB constants for cellID=" << ic <<
": ee5x5Calib = " << ee5x5Calib[ic - 1] <<
" Expee5x5E = " << Expee5x5E[ic - 1] <<
157 " ElectronicsCalib = " <<
158 ElectronicsCalib[ic - 1]);
162 for (
int crysID = 0; crysID < 8736; crysID++) {
163 if (ElectronicsCalib[crysID] <= 0) {B2FATAL(
"eclee5x5Collector: ElectronicsCalib = " << ElectronicsCalib[crysID] <<
" for crysID = " << crysID);}
164 if (Expee5x5E[crysID] == 0) {B2FATAL(
"eclee5x5Collector: Expee5x5E = 0 for crysID = " << crysID);}
165 if (ee5x5Calib[crysID] == 0) {B2FATAL(
"eclee5x5Collector: ee5x5Calib = 0 for crysID = " << crysID);}
170 m_eclClusterArray.isRequired();
171 m_eclCalDigitArray.isRequired();
172 m_eclDigitArray.isRequired();
173 m_evtMetaData.isRequired();
178 for (
int it = 0; it < 69; it++) {
181 m_dPhiMin.push_back(meandPhi[crysID] - m_dPhiScale * widthdPhi[crysID]);
182 m_dPhiMax.push_back(meandPhi[crysID] + m_dPhiScale * widthdPhi[crysID]);
183 for (
int ic = 0; ic < m_eclNeighbours5x5->getCrystalsPerRing(it); ic++) {
184 m_thetaID.at(crysID) = it;
194 void eclee5x5CollectorModule::collect()
199 for (
int crysID = 0; crysID < 8736; crysID++) {
200 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysID + 0.001, Expee5x5E[crysID]);
201 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysID + 0.001, ElectronicsCalib[crysID]);
202 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysID + 0.001, ee5x5Calib[crysID]);
203 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysID + 0.001);
210 bool newConst =
false;
211 if (m_ECLExpee5x5E.hasChanged()) {
213 B2INFO(
"ECLExpee5x5E has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
214 Expee5x5E = m_ECLExpee5x5E->getCalibVector();
215 Expee5x5Sigma = m_ECLExpee5x5E->getCalibUncVector();
217 if (m_ElectronicsCalib.hasChanged()) {
219 B2INFO(
"ECLCrystalElectronics has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
220 ElectronicsCalib = m_ElectronicsCalib->getCalibVector();
222 if (m_ee5x5Calib.hasChanged()) {
224 B2INFO(
"ECLCrystalEnergyee5x5 has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
225 ee5x5Calib = m_ee5x5Calib->getCalibVector();
229 for (
int ic = 1; ic < 9000; ic += 1000) {
230 B2INFO(
"DB constants for cellID=" << ic <<
": ee5x5Calib = " << ee5x5Calib[ic - 1] <<
" Expee5x5E = " << Expee5x5E[ic - 1] <<
231 " ElectronicsCalib = " <<
232 ElectronicsCalib[ic - 1]);
236 for (
int crysID = 0; crysID < 8736; crysID++) {
237 if (ElectronicsCalib[crysID] <= 0) {B2FATAL(
"eclee5x5Collector: ElectronicsCalib = " << ElectronicsCalib[crysID] <<
" for crysID = " << crysID);}
238 if (Expee5x5E[crysID] == 0) {B2FATAL(
"eclee5x5Collector: Expee5x5E = 0 for crysID = " << crysID);}
239 if (ee5x5Calib[crysID] == 0) {B2FATAL(
"eclee5x5Collector: ee5x5Calib = 0 for crysID = " << crysID);}
246 unsigned int L1TriggerResults = m_TRGResults->getTRGSummary(0);
247 if (L1TriggerResults == 0) {
return;}
252 int icMax[2] = { -1, -1};
253 double maxClustE[2] = { -1., -1.};
254 int nclust = m_eclClusterArray.getEntries();
255 for (
int ic = 0; ic < nclust; ic++) {
258 if (eClust > maxClustE[0]) {
259 maxClustE[1] = maxClustE[0];
261 maxClustE[0] = eClust;
263 }
else if (eClust > maxClustE[1]) {
264 maxClustE[1] = eClust;
273 if (icMax[1] == -1) {
return;}
274 double theta0 = m_eclClusterArray[icMax[0]]->getTheta();
275 double theta1 = m_eclClusterArray[icMax[1]]->getTheta();
276 if (theta0 < m_thetaLabMin || theta0 > m_thetaLabMax || theta1 < m_thetaLabMin || theta1 > m_thetaLabMax) {
return;}
279 double t0 = m_eclClusterArray[icMax[0]]->getTime();
280 double dt990 = m_eclClusterArray[icMax[0]]->getDeltaTime99();
281 double t1 = m_eclClusterArray[icMax[1]]->getTime();
282 double dt991 = m_eclClusterArray[icMax[1]]->getDeltaTime99();
283 double dt99min = dt990;
284 if (dt991 < dt990) {dt99min = dt991;}
285 if (dt99min <= 0) {dt99min = 0.0001;}
286 if (abs(t1 - t0) > dt99min * m_maxTime) {
return;}
293 double phi0 = m_eclClusterArray[icMax[0]]->getPhi();
294 TVector3 p30(0., 0., maxClustE[0]);
295 p30.SetTheta(theta0);
298 ECLCluster::EHypothesisBit::c_nPhotons);
300 double phi1 = m_eclClusterArray[icMax[1]]->getPhi();
301 TVector3 p31(0., 0., maxClustE[1]);
302 p31.SetTheta(theta1);
305 ECLCluster::EHypothesisBit::c_nPhotons);
308 TLorentzVector p40COM = m_boostrotate.rotateLabToCms() * p40;
309 TLorentzVector p41COM = m_boostrotate.rotateLabToCms() * p41;
310 double theta01COM = (p41COM.Theta() + p40COM.Theta()) * TMath::RadToDeg();
311 if (abs(theta01COM - 180.) > m_maxdThetaSum) {
return;}
314 if (p40COM.E() < m_minE0 * m_sqrts and p41COM.E() < m_minE0 * m_sqrts) {
return;}
315 if (p40COM.E() < m_minE1 * m_sqrts or p41COM.E() < m_minE1 * m_sqrts) {
return;}
320 int crysIDMax[2] = { -1, -1};
321 double crysEMax[2] = { -1., -1.};
322 for (
int imax = 0; imax < 2; imax++) {
323 auto eclClusterRelations = m_eclClusterArray[icMax[imax]]->getRelationsTo<
ECLCalDigit>(
"ECLCalDigits");
324 for (
unsigned int ir = 0; ir < eclClusterRelations.size(); ir++) {
325 const auto calDigit = eclClusterRelations.object(ir);
326 int tempCrysID = calDigit->
getCellId() - 1;
327 float tempE = calDigit->getEnergy();
328 if (tempE > crysEMax[imax]) {
329 crysEMax[imax] = tempE;
330 crysIDMax[imax] = tempCrysID;
336 double dphiCOM = abs(p41COM.Phi() - p40COM.Phi()) * TMath::RadToDeg();
337 if (dphiCOM > 180.) {dphiCOM = 360. - dphiCOM;}
339 int thetaIDmin = m_thetaID[crysIDMax[0]];
340 if (m_thetaID[crysIDMax[1]] < m_thetaID[crysIDMax[0]]) {thetaIDmin = m_thetaID[crysIDMax[1]];}
341 getObjectPtr<TH2F>(
"dPhivsThetaID")->Fill(thetaIDmin + 0.001, dphiCOM);
342 if (dphiCOM<m_dPhiMin.at(thetaIDmin) or dphiCOM>m_dPhiMax.at(thetaIDmin)) {
return;}
347 memset(&EperCrys[0], 0, EperCrys.size()*
sizeof EperCrys[0]);
349 if (m_useCalDigits) {
350 for (
auto& eclCalDigit : m_eclCalDigitArray) {
351 int tempCrysID = eclCalDigit.getCellId() - 1;
352 EperCrys[tempCrysID] = eclCalDigit.getEnergy();
355 for (
auto& eclDigit : m_eclDigitArray) {
356 int tempCrysID = eclDigit.getCellId() - 1;
358 EperCrys[tempCrysID] = eclDigit.getAmp() * abs(ee5x5Calib[tempCrysID]) * ElectronicsCalib[tempCrysID];
364 for (
int ic = 0; ic < 2; ic++) {
365 int crysMax = crysIDMax[ic];
366 float expE = abs(Expee5x5E[crysMax]);
367 float sigmaExp = Expee5x5Sigma[crysMax];
368 std::vector<short int> neighbours = m_eclNeighbours5x5->getNeighbours(crysMax + 1);
371 double reducedExpE = expE;
373 for (
auto& cellID : neighbours) {
374 E25 += EperCrys[cellID - 1];
375 if (ee5x5Calib[cellID - 1] < 0.) {
376 reducedExpE -= EperCrys[cellID - 1];
381 double rexpE = reducedExpE / sigmaExp;
382 for (
auto& celli : neighbours) {
383 if (ee5x5Calib[celli - 1] > 0.) {
384 float rEi = EperCrys[celli - 1] / sigmaExp;
385 getObjectPtr<TH1F>(
"RvsCrysID")->Fill(celli - 0.999, rexpE * rEi);
386 getObjectPtr<TH1F>(
"NRvsCrysID")->Fill(celli - 0.999);
387 for (
auto& cellj : neighbours) {
388 if (ee5x5Calib[cellj - 1] > 0.) {
389 float rEj = EperCrys[cellj - 1] / sigmaExp;
390 getObjectPtr<TH2F>(
"Qmatrix")->Fill(celli - 0.999, cellj - 0.999, rEi * rEj);
397 getObjectPtr<TH2F>(
"EnVsCrysID")->Fill(crysMax + 0.001, E25 / expE);
398 getObjectPtr<TH1F>(
"EntriesvsCrys")->Fill(crysMax + 0.001);
399 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysMax + 0.001, Expee5x5E[crysMax]);
400 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysMax + 0.001, ElectronicsCalib[crysMax]);
401 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysMax + 0.001, ee5x5Calib[crysMax]);
402 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysMax + 0.001);