11 #include <ecl/modules/eclGammaGammaECollector/eclGammaGammaECollectorModule.h>
17 #include <analysis/utility/PCmsLabTransform.h>
18 #include <analysis/ClusterUtility/ClusterUtils.h>
21 #include <framework/gearbox/Const.h>
22 #include <framework/dataobjects/EventMetaData.h>
23 #include <framework/datastore/RelationVector.h>
26 #include <mdst/dataobjects/TRGSummary.h>
27 #include <mdst/dataobjects/HitPatternCDC.h>
28 #include <mdst/dataobjects/TrackFitResult.h>
29 #include <mdst/dataobjects/Track.h>
30 #include <mdst/dataobjects/ECLCluster.h>
33 #include <ecl/dataobjects/ECLDigit.h>
34 #include <ecl/dataobjects/ECLCalDigit.h>
35 #include <ecl/dbobjects/ECLCrystalCalib.h>
55 m_ECLExpGammaGammaE("ECLExpGammaGammaE"),
56 m_ElectronicsCalib("ECLCrystalElectronics"), m_GammaGammaECalib("ECLCrystalEnergyGammaGamma")
59 setDescription(
"Calibration Collector Module for ECL single crystal energy calibration using gamma gamma events");
60 setPropertyFlags(c_ParallelProcessingCertified);
61 addParam(
"thetaLabMinDeg", m_thetaLabMinDeg,
"miniumum photon theta in lab (degrees)", 0.);
62 addParam(
"thetaLabMaxDeg", m_thetaLabMaxDeg,
"maximum photon theta in lab (degrees)", 180.);
63 addParam(
"minPairMass", m_minPairMass,
"minimum invariant mass of the pair of photons (GeV/c^2)", 9.);
64 addParam(
"mindPhi", m_mindPhi,
"minimum delta phi between clusters (deg)", 179.);
65 addParam(
"maxTime", m_maxTime,
"maximum (time-<t>)/dt99 of photons", 1.);
66 addParam(
"measureTrueEnergy", m_measureTrueEnergy,
"use MC events to obtain expected energies",
false);
67 addParam(
"requireL1", m_requireL1,
"only use events that have a level 1 trigger",
true);
74 void eclGammaGammaECollectorModule::prepare()
78 B2INFO(
"eclGammaGammaECollector: Experiment = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
82 auto EnVsCrysID =
new TH2F(
"EnVsCrysID",
"Normalized energy for each crystal;crystal ID;E/Expected", 8736, 0, 8736, 140, 0, 1.4);
83 registerObject<TH2F>(
"EnVsCrysID", EnVsCrysID);
85 auto ExpEvsCrys =
new TH1F(
"ExpEvsCrys",
"Sum expected energy vs crystal ID;crystal ID;Energy (GeV)", 8736, 0, 8736);
86 registerObject<TH1F>(
"ExpEvsCrys", ExpEvsCrys);
88 auto ElecCalibvsCrys =
new TH1F(
"ElecCalibvsCrys",
"Sum electronics calib const vs crystal ID;crystal ID;calibration constant",
90 registerObject<TH1F>(
"ElecCalibvsCrys", ElecCalibvsCrys);
92 auto InitialCalibvsCrys =
new TH1F(
"InitialCalibvsCrys",
93 "Sum initial gamma gamma calib const vs crystal ID;crystal ID;calibration constant", 8736, 0, 8736);
94 registerObject<TH1F>(
"InitialCalibvsCrys", InitialCalibvsCrys);
96 auto CalibEntriesvsCrys =
new TH1F(
"CalibEntriesvsCrys",
"Entries in calib vs crys histograms;crystal ID;Entries per crystal", 8736,
98 registerObject<TH1F>(
"CalibEntriesvsCrys", CalibEntriesvsCrys);
101 auto RawDigitAmpvsCrys =
new TH2F(
"RawDigitAmpvsCrys",
"Digit Amplitude vs crystal ID;crystal ID;Amplitude", 8736, 0, 8736, 200, 0,
103 registerObject<TH2F>(
"RawDigitAmpvsCrys", RawDigitAmpvsCrys);
105 auto RawDigitTimevsCrys =
new TH2F(
"RawDigitTimevsCrys",
"Digit Time vs crystal ID;crystal ID;Time", 8736, 0, 8736, 200, -2000,
107 registerObject<TH2F>(
"RawDigitTimevsCrys", RawDigitTimevsCrys);
109 auto TimeMinusAverage =
new TH1F(
"TimeMinusAverage",
"Photon time - average / dt99;(T-T_ave)/dt99 ", 100, -10, 10);
110 registerObject<TH1F>(
"TimeMinusAverage", TimeMinusAverage);
115 B2INFO(
"Input parameters to eclGammaGammaECollector:");
116 B2INFO(
"thetaLabMinDeg: " << m_thetaLabMinDeg);
117 B2INFO(
"thetaLabMaxDeg: " << m_thetaLabMaxDeg);
118 thetaLabMin = m_thetaLabMinDeg / TMath::RadToDeg();
119 thetaLabMax = m_thetaLabMaxDeg / TMath::RadToDeg();
120 B2INFO(
"minPairMass: " << m_minPairMass);
121 B2INFO(
"mindPhi: " << m_mindPhi);
122 B2INFO(
"maxTime: " << m_maxTime);
123 B2INFO(
"measureTrueEnergy: " << m_measureTrueEnergy);
124 B2INFO(
"requireL1: " << m_requireL1);
127 EperCrys.resize(8736);
131 if (m_ECLExpGammaGammaE.hasChanged()) {ExpGammaGammaE = m_ECLExpGammaGammaE->getCalibVector();}
132 if (m_ElectronicsCalib.hasChanged()) {ElectronicsCalib = m_ElectronicsCalib->getCalibVector();}
133 if (m_GammaGammaECalib.hasChanged()) {GammaGammaECalib = m_GammaGammaECalib->getCalibVector();}
136 for (
int ic = 1; ic < 9000; ic += 1000) {
137 B2INFO(
"DB constants for cellID=" << ic <<
": ExpGammaGammaE = " << ExpGammaGammaE[ic - 1] <<
" ElectronicsCalib = " <<
138 ElectronicsCalib[ic - 1]
139 <<
" GammaGammaECalib = " << GammaGammaECalib[ic - 1]);
143 for (
int crysID = 0; crysID < 8736; crysID++) {
144 if (ElectronicsCalib[crysID] <= 0) {B2FATAL(
"eclGammaGammaECollector: ElectronicsCalib = " << ElectronicsCalib[crysID] <<
" for crysID = " << crysID);}
145 if (ExpGammaGammaE[crysID] == 0) {B2FATAL(
"eclGammaGammaECollector: ExpGammaGammaE = 0 for crysID = " << crysID);}
146 if (GammaGammaECalib[crysID] == 0) {B2FATAL(
"eclGammaGammaECollector: GammaGammaECalib = 0 for crysID = " << crysID);}
151 m_trackArray.isRequired();
152 m_eclClusterArray.isRequired();
153 m_eclCalDigitArray.isRequired();
154 m_eclDigitArray.isRequired();
161 void eclGammaGammaECollectorModule::collect()
166 for (
int crysID = 0; crysID < 8736; crysID++) {
167 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysID + 0.001, ExpGammaGammaE[crysID]);
168 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysID + 0.001, ElectronicsCalib[crysID]);
169 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysID + 0.001, GammaGammaECalib[crysID]);
170 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysID + 0.001);
177 bool newConst =
false;
178 if (m_ECLExpGammaGammaE.hasChanged()) {
180 B2INFO(
"ECLExpGammaGammaE has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
181 ExpGammaGammaE = m_ECLExpGammaGammaE->getCalibVector();
183 if (m_ElectronicsCalib.hasChanged()) {
185 B2INFO(
"ECLCrystalElectronics has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
186 ElectronicsCalib = m_ElectronicsCalib->getCalibVector();
188 if (m_GammaGammaECalib.hasChanged()) {
190 B2INFO(
"ECLCrystalEnergyGammaGamma has changed, exp = " << m_evtMetaData->getExperiment() <<
" run = " << m_evtMetaData->getRun());
191 GammaGammaECalib = m_GammaGammaECalib->getCalibVector();
195 for (
int ic = 1; ic < 9000; ic += 1000) {
196 B2INFO(
"DB constants for cellID=" << ic <<
": ExpGammaGammaE = " << ExpGammaGammaE[ic - 1] <<
" ElectronicsCalib = " <<
197 ElectronicsCalib[ic - 1]
198 <<
" GammaGammaECalib = " << GammaGammaECalib[ic - 1]);
202 for (
int crysID = 0; crysID < 8736; crysID++) {
203 if (ElectronicsCalib[crysID] <= 0) {B2FATAL(
"eclGammaGammaECollector: ElectronicsCalib = " << ElectronicsCalib[crysID] <<
" for crysID = " << crysID);}
204 if (ExpGammaGammaE[crysID] == 0) {B2FATAL(
"eclGammaGammaECollector: ExpGammaGammaE = 0 for crysID = " << crysID);}
205 if (GammaGammaECalib[crysID] == 0) {B2FATAL(
"eclGammaGammaECollector: GammaGammaECalib = 0 for crysID = " << crysID);}
212 unsigned int L1TriggerResults = m_TRGResults->getTRGSummary(0);
213 if (L1TriggerResults == 0) {
return;}
219 for (
auto& track : m_trackArray) {
223 double z0 = temptrackFit->
getZ0();
224 double d0 = temptrackFit->
getD0();
225 double pValue = temptrackFit->
getPValue();
227 if (pt > minTrkpt && abs(z0) < maxZ0 && abs(d0) < maxD0 && pValue > minpValue && nCDChits >= minCDChits) {nGoodTrk++;}
230 if (nGoodTrk > 0) {
return;}
235 int icMax[2] = { -1, -1};
236 double maxClustE[2] = { -1., -1.};
237 int nclust = m_eclClusterArray.getEntries();
238 for (
int ic = 0; ic < nclust; ic++) {
239 if (m_eclClusterArray[ic]->hasHypothesis(usePhotons)) {
240 double eClust = m_eclClusterArray[ic]->getEnergy(usePhotons);
241 if (eClust > maxClustE[0]) {
242 maxClustE[1] = maxClustE[0];
244 maxClustE[0] = eClust;
246 }
else if (eClust > maxClustE[1]) {
247 maxClustE[1] = eClust;
256 if (icMax[0] == -1 || icMax[1] == -1) {
return;}
257 double theta0 = m_eclClusterArray[icMax[0]]->getTheta();
258 double theta1 = m_eclClusterArray[icMax[1]]->getTheta();
259 if (theta0 < thetaLabMin || theta0 > thetaLabMax || theta1 < thetaLabMin || theta1 > thetaLabMax) {
return;}
262 double t0 = m_eclClusterArray[icMax[0]]->getTime();
263 double t990 = m_eclClusterArray[icMax[0]]->getDeltaTime99();
264 double t1 = m_eclClusterArray[icMax[1]]->getTime();
265 double t991 = m_eclClusterArray[icMax[1]]->getDeltaTime99();
266 double taverage = (t0 / (t990 * t990) + t1 / (t991 * t991)) / (1. / (t990 * t990) + 1. / (t991 * t991));
267 if (abs(t0 - taverage) > t990 * m_maxTime || abs(t1 - taverage) > t991 * m_maxTime) {
return;}
273 double phi0 = m_eclClusterArray[icMax[0]]->getPhi();
274 TVector3 p30(0., 0., maxClustE[0]);
275 p30.SetTheta(theta0);
277 const TLorentzVector p40 = cUtil.
Get4MomentumFromCluster(m_eclClusterArray[icMax[0]], clustervertex, usePhotons);
279 double phi1 = m_eclClusterArray[icMax[1]]->getPhi();
280 TVector3 p31(0., 0., maxClustE[1]);
281 p31.SetTheta(theta1);
283 const TLorentzVector p41 = cUtil.
Get4MomentumFromCluster(m_eclClusterArray[icMax[1]], clustervertex, usePhotons);
285 double pairmass = (p40 + p41).M();
286 if (pairmass < m_minPairMass) {
return;}
292 double dphi = abs(p41COM.Phi() - p40COM.Phi()) * TMath::RadToDeg();
293 if (dphi > 180.) {dphi = 360. - dphi;}
294 if (dphi < m_mindPhi) {
return;}
298 memset(&EperCrys[0], 0, EperCrys.size()*
sizeof EperCrys[0]);
299 for (
auto& eclDigit : m_eclDigitArray) {
300 int crysID = eclDigit.getCellId() - 1;
301 getObjectPtr<TH2F>(
"RawDigitAmpvsCrys")->Fill(crysID + 0.001, eclDigit.getAmp());
304 EperCrys[crysID] = eclDigit.getAmp() * abs(GammaGammaECalib[crysID]) * ElectronicsCalib[crysID];
305 if (EperCrys[crysID] > 0.01) {
306 getObjectPtr<TH2F>(
"RawDigitTimevsCrys")->Fill(crysID + 0.001, eclDigit.getTimeFit());
311 if (m_measureTrueEnergy) {
312 for (
auto& eclCalDigit : m_eclCalDigitArray) {
313 int tempCrysID = eclCalDigit.getCellId() - 1;
314 double tempE = eclCalDigit.getEnergy();
315 EperCrys[tempCrysID] = tempE;
321 int crysIDMax[2] = { -1, -1};
322 double crysEMax[2] = { -1., -1.};
323 for (
int imax = 0; imax < 2; imax++) {
324 auto eclClusterRelations = m_eclClusterArray[icMax[imax]]->getRelationsTo<
ECLCalDigit>(
"ECLCalDigits");
325 for (
unsigned int ir = 0; ir < eclClusterRelations.size(); ir++) {
326 const auto calDigit = eclClusterRelations.object(ir);
327 int tempCrysID = calDigit->
getCellId() - 1;
328 float tempE = EperCrys[tempCrysID];
329 if (tempE > crysEMax[imax]) {
330 crysEMax[imax] = tempE;
331 crysIDMax[imax] = tempCrysID;
338 for (
int ic = 0; ic < 2; ic++) {
339 if (crysIDMax[ic] >= 0) {
341 getObjectPtr<TH2F>(
"EnVsCrysID")->Fill(crysIDMax[ic] + 0.001, EperCrys[crysIDMax[ic]] / abs(ExpGammaGammaE[crysIDMax[ic]]));
342 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysIDMax[ic] + 0.001, ExpGammaGammaE[crysIDMax[ic]]);
343 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysIDMax[ic] + 0.001, ElectronicsCalib[crysIDMax[ic]]);
344 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysIDMax[ic] + 0.001, GammaGammaECalib[crysIDMax[ic]]);
345 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysIDMax[ic] + 0.001);
348 if (crysIDMax[0] >= 0 && crysIDMax[1] >= 0) {
349 getObjectPtr<TH1F>(
"TimeMinusAverage")->Fill((t0 - taverage) / t990);
350 getObjectPtr<TH1F>(
"TimeMinusAverage")->Fill((t1 - taverage) / t991);