13 #include <ecl/modules/eclBhabhaTCollector/ECLBhabhaTCollectorModule.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 #include <framework/gearbox/Const.h>
16 #include <ecl/dbobjects/ECLCrystalCalib.h>
17 #include <ecl/dbobjects/ECLReferenceCrystalPerCrateCalib.h>
18 #include <ecl/dataobjects/ECLDigit.h>
19 #include <ecl/dataobjects/ECLCalDigit.h>
20 #include <mdst/dataobjects/ECLCluster.h>
21 #include <mdst/dataobjects/Track.h>
22 #include <mdst/dataobjects/HitPatternCDC.h>
23 #include <tracking/dataobjects/RecoTrack.h>
24 #include <ecl/digitization/EclConfiguration.h>
25 #include <analysis/utility/PCmsLabTransform.h>
26 #include <analysis/ClusterUtility/ClusterUtils.h>
27 #include <boost/optional.hpp>
28 #include <ecl/geometry/ECLGeometryPar.h>
48 m_ElectronicsDB("ECLCrystalElectronics"),
49 m_ElectronicsTimeDB("ECLCrystalElectronicsTime"),
50 m_FlightTimeDB("ECLCrystalFlightTime"),
51 m_PreviousCrystalTimeDB("ECLCrystalTimeOffset"),
52 m_CrateTimeDB("ECLCrateTimeOffset"),
57 setDescription(
"This module generates sum of all event times per crystal");
59 addParam(
"timeAbsMax", m_timeAbsMax,
60 "Events with fabs(getTimeFit) > m_timeAbsMax "
61 "are excluded", (
short)80);
63 addParam(
"minCrystal", m_minCrystal,
64 "First CellId to handle.", 1);
65 addParam(
"maxCrystal", m_maxCrystal,
66 "Last CellId to handle.", 8736);
68 addParam(
"saveTree", m_saveTree,
69 "If true, TTree 'tree' with more detailed event info is saved in "
70 "the output file specified by HistoManager",
73 addParam(
"looseTrkZ0", m_looseTrkZ0,
"max Z0 for loose tracks (cm)", 10.);
74 addParam(
"tightTrkZ0", m_tightTrkZ0,
"max Z0 for tight tracks (cm)", 2.);
75 addParam(
"looseTrkD0", m_looseTrkD0,
"max D0 for loose tracks (cm)", 2.);
76 addParam(
"tightTrkD0", m_tightTrkD0,
"max D0 for tight tracks (cm)", 0.5);
78 addParam(
"hadronEventT0_TO_bhabhaEventT0_correction", m_hadronEventT0_TO_bhabhaEventT0_correction,
79 "CDC bhabha t0 bias correction (ns)", 0.);
82 setPropertyFlags(c_ParallelProcessingCertified);
94 m_dbgTree_electrons =
new TTree(
"tree_electrons",
"Debug data for bhabha time calibration - one entry per electron");
95 m_dbgTree_electrons->Branch(
"EventNum", &m_tree_evtNum)->SetTitle(
"Event number");
96 m_dbgTree_electrons->Branch(
"CrystalCellID", &m_tree_cid)->SetTitle(
"Cell ID, 1..8736");
97 m_dbgTree_electrons->Branch(
"ADCamplitude", &m_tree_amp)->SetTitle(
"Amplitude, ADC units");
98 m_dbgTree_electrons->Branch(
"maxEcrystalEnergy", &m_tree_en)->SetTitle(
"Max Energy Crystal Energy, GeV");
99 m_dbgTree_electrons->Branch(
"maxEcrystalEnergyDIVclusterE",
100 &m_tree_E1Etot)->SetTitle(
"Max Energy Crystal Fraction Energy of Cluster");
101 m_dbgTree_electrons->Branch(
"E1divE2crystal",
102 &m_tree_E1E2)->SetTitle(
"Max Energy Crystal DIV second max energy crystal in cluster");
103 m_dbgTree_electrons->Branch(
"E1crystal_DIV_p", &m_tree_E1p)->SetTitle(
"Max Energy Crystal in cluster DIV track p");
104 m_dbgTree_electrons->Branch(
"timetsPreviousTimeCalibs",
105 &m_tree_timetsPreviousTimeCalibs)->SetTitle(
"Time t_psi after application of previous Ts, ns");
106 m_dbgTree_electrons->Branch(
"E_DIV_p", &m_E_DIV_p)->SetTitle(
"E DIV p");
107 m_dbgTree_electrons->Branch(
"timeF", &m_tree_timeF)->SetTitle(
"Time F, ns");
108 m_dbgTree_electrons->Branch(
"time_t_psi", &m_tree_time)->SetTitle(
"Time t_psi for Ts, ns");
109 m_dbgTree_electrons->Branch(
"quality", &m_tree_quality)->SetTitle(
"ECL FPGA fit quality, see Confluence article");
110 m_dbgTree_electrons->Branch(
"t0", &m_tree_t0)->SetTitle(
"T0, ns");
111 m_dbgTree_electrons->Branch(
"t0_unc", &m_tree_t0_unc)->SetTitle(
"T0 uncertainty, ns");
112 m_dbgTree_electrons->Branch(
"CrateID", &m_crystalCrate)->SetTitle(
"Crate id for crystal");
113 m_dbgTree_electrons->Branch(
"runNum", &m_runNum)->SetTitle(
"Run number");
115 m_dbgTree_electrons->SetAutoSave(10);
119 m_dbgTree_tracks =
new TTree(
"tree_tracks",
"Debug data for bhabha time calibration - one entry per track");
120 m_dbgTree_tracks->Branch(
"d0", &m_tree_d0)->SetTitle(
"d0, cm");
121 m_dbgTree_tracks->Branch(
"z0", &m_tree_z0)->SetTitle(
"z0, cm");
122 m_dbgTree_tracks->Branch(
"p", &m_tree_p)->SetTitle(
"track momentum, GeV");
123 m_dbgTree_tracks->Branch(
"charge", &m_charge)->SetTitle(
"track electric charge");
124 m_dbgTree_tracks->Branch(
"Num_CDC_hits", &m_tree_nCDChits)->SetTitle(
"Num CDC hits");
126 m_dbgTree_tracks->SetAutoSave(10);
129 m_dbgTree_crystals =
new TTree(
"tree_crystals",
130 "Debug data for bhabha time calibration - one entry per electron - one entry per crystal");
131 m_dbgTree_crystals->Branch(
"clustCrysE_DIV_maxEcrys",
132 &m_tree_clustCrysE_DIV_maxEcrys)->SetTitle(
"E of crystal i from cluster / E of max E crystal");
133 m_dbgTree_crystals->Branch(
"Crystal_E", &m_tree_clustCrysE) ->SetTitle(
"E of crystal i from cluster");
134 m_dbgTree_crystals->Branch(
"time_t_psi", &m_tree_time)->SetTitle(
"Time for Ts, ns");
135 m_dbgTree_crystals->Branch(
"Crystal_cell_ID", &m_tree_cid)->SetTitle(
"Cell ID, 1..8736");
136 m_dbgTree_crystals->Branch(
"quality", &m_tree_quality)->SetTitle(
"ECL FPGA fit quality, see Confluence article");
138 m_dbgTree_crystals->SetAutoSave(10);
142 m_dbgTree_event =
new TTree(
"tree_event",
"Debug data for bhabha time calibration - one entry per event");
143 m_dbgTree_event->Branch(
"massInvTracks", &m_massInvTracks)->SetTitle(
"Invariant mass of the two tracks");
145 m_dbgTree_event->SetAutoSave(10);
148 m_dbgTree_evt_allCuts =
new TTree(
"tree_evt_allCuts",
149 "Debug data for bhabha time calibration - one entry per event after all the cuts");
150 m_dbgTree_evt_allCuts->Branch(
"EclustPlus", &m_tree_enPlus)->SetTitle(
"Energy of cluster with +ve charge, GeV");
151 m_dbgTree_evt_allCuts->Branch(
"EclustNeg", &m_tree_enNeg)->SetTitle(
"Energy of cluster with -ve charge, GeV");
152 m_dbgTree_evt_allCuts->Branch(
"clustTimePos", &m_tree_tClustPos)->SetTitle(
"Cluster time of cluster with +ve charge, GeV");
153 m_dbgTree_evt_allCuts->Branch(
"clustTimeNeg", &m_tree_tClustNeg)->SetTitle(
"Cluster time of cluster with -ve charge, GeV");
154 m_dbgTree_evt_allCuts->Branch(
"maxEcrysTimePosClust",
155 &m_tree_maxEcrystPosClust)->SetTitle(
"Time of maximum energy crystal in cluster with +ve charge, GeV");
156 m_dbgTree_evt_allCuts->Branch(
"maxEcrysTimeNegClust",
157 &m_tree_maxEcrystNegClust)->SetTitle(
"Time of maximum energy crystal in cluster with -ve charge, GeV");
158 m_dbgTree_evt_allCuts->Branch(
"t0", &m_tree_t0)->SetTitle(
"T0, ns");
159 m_dbgTree_evt_allCuts->Branch(
"t0_ECL_closestCDC", &m_tree_t0_ECLclosestCDC)->SetTitle(
"T0 ECL closest to CDC t0, ns");
160 m_dbgTree_evt_allCuts->Branch(
"t0_ECL_minChi2", &m_tree_t0_ECL_minChi2)->SetTitle(
"T0 ECL with smallest chi squared, ns");
162 m_dbgTree_evt_allCuts->SetAutoSave(10);
166 m_dbgTree_crys_allCuts =
new TTree(
"m_dbgTree_crys_allCuts",
167 "Debug data for bhabha time calibration - one entry per crystal per cluster entry after all cuts");
169 m_dbgTree_crys_allCuts->Branch(
"runNum", &m_runNum)->SetTitle(
"Run number");
170 m_dbgTree_crys_allCuts->Branch(
"EventNum", &m_tree_evtNum)->SetTitle(
"Event number");
171 m_dbgTree_crys_allCuts->Branch(
"m_tree_ECLCalDigitTime",
172 &m_tree_ECLCalDigitTime)
173 ->SetTitle(
"Time of a crystal within the cluster after application of previous calibrations except t0, ns");
174 m_dbgTree_crys_allCuts->Branch(
"m_tree_ECLCalDigitE", &m_tree_ECLCalDigitE)->SetTitle(
"Energy of crystal, GeV");
175 m_dbgTree_crys_allCuts->Branch(
"m_tree_ECLDigitAmplitude",
176 &m_tree_ECLDigitAmplitude)->SetTitle(
"Amplitude of crystal signal pulse");
177 m_dbgTree_crys_allCuts->Branch(
"timetsPreviousTimeCalibs",
178 &m_tree_timetsPreviousTimeCalibs)->SetTitle(
"Time t_psi after application of previous Ts, ns");
179 m_dbgTree_crys_allCuts->Branch(
"t0", &m_tree_t0)->SetTitle(
"T0, ns");
180 m_dbgTree_crys_allCuts->Branch(
"t0_ECL_closestCDC", &m_tree_t0_ECLclosestCDC)->SetTitle(
"T0 ECL closest to CDC t0, ns");
181 m_dbgTree_crys_allCuts->Branch(
"t0_ECL_minChi2", &m_tree_t0_ECL_minChi2)->SetTitle(
"T0 ECL with smallest chi squared, ns");
182 m_dbgTree_crys_allCuts->Branch(
"CrystalCellID", &m_tree_cid)->SetTitle(
"Cell ID, 1..8736");
184 m_dbgTree_crys_allCuts->SetAutoSave(10);
192 m_dbgTree_allCuts =
new TTree(
"tree_allCuts",
193 "Debug data for bhabha time calibration - one entry per max E crystal entry after cuts");
195 m_dbgTree_allCuts->Branch(
"time_t_psi", &m_tree_time)->SetTitle(
"Time t_psi for Ts, ns");
196 m_dbgTree_allCuts->Branch(
"crateID", &m_crystalCrate)->SetTitle(
"Crate id for crystal");
197 m_dbgTree_allCuts->Branch(
"EventNum", &m_tree_evtNum)->SetTitle(
"Event number");
198 m_dbgTree_allCuts->Branch(
"runNum", &m_runNum)->SetTitle(
"Run number");
199 m_dbgTree_allCuts->Branch(
"CrystalCellID", &m_tree_cid)->SetTitle(
"Cell ID, 1..8736");
200 m_dbgTree_allCuts->Branch(
"maxEcrystalEnergy", &m_tree_en)->SetTitle(
"Max Energy Crystal Energy, GeV");
201 m_dbgTree_allCuts->Branch(
"maxEcrystalEnergyDIVclusterE",
202 &m_tree_E1Etot)->SetTitle(
"Max Energy Crystal Fraction Energy of Cluster");
203 m_dbgTree_allCuts->Branch(
"E1divE2crystal",
204 &m_tree_E1E2)->SetTitle(
"Max Energy Crystal DIV second max energy crystal in cluster");
205 m_dbgTree_allCuts->Branch(
"E1crystalDIVp", &m_tree_E1p)->SetTitle(
"Max Energy Crystal in cluster DIV track p");
206 m_dbgTree_allCuts->Branch(
"timetsPreviousTimeCalibs",
207 &m_tree_timetsPreviousTimeCalibs)->SetTitle(
"Time t_psi after application of previous Ts, ns");
208 m_dbgTree_allCuts->Branch(
"massInvTracks", &m_massInvTracks)->SetTitle(
"Invariant mass of the two tracks");
209 m_dbgTree_allCuts->Branch(
"t0", &m_tree_t0)->SetTitle(
"T0, ns");
210 m_dbgTree_allCuts->Branch(
"t0_ECL_closestCDC", &m_tree_t0_ECLclosestCDC)->SetTitle(
"T0 ECL closest to CDC t0, ns");
211 m_dbgTree_allCuts->Branch(
"t0_ECL_minChi2", &m_tree_t0_ECL_minChi2)->SetTitle(
"T0 ECL with smallest chi squared, ns");
213 m_dbgTree_allCuts->Branch(
"clusterTime", &m_tree_tClust)->SetTitle(
"Cluster time of cluster with +ve charge, GeV");
215 m_dbgTree_allCuts->SetAutoSave(10);
224 B2INFO(
"ECLBhabhaTCollector: Experiment = " << evtMetaData->getExperiment() <<
225 " run = " << evtMetaData->getRun());
229 int nbins = m_timeAbsMax * 8;
230 int max_t = m_timeAbsMax;
231 int min_t = -m_timeAbsMax;
234 auto TimevsCrysPrevCrateCalibPrevCrystCalib =
new TH2F(
"TimevsCrysPrevCrateCalibPrevCrystCalib",
235 "Time t psi - ts - tcrate (previous calibs) vs crystal cell ID;crystal cell ID;Time t_psi with previous calib (ns)",
236 8736, 1, 8736 + 1, nbins, min_t, max_t);
237 registerObject<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib", TimevsCrysPrevCrateCalibPrevCrystCalib);
239 auto TimevsCratePrevCrateCalibPrevCrystCalib =
new TH2F(
"TimevsCratePrevCrateCalibPrevCrystCalib",
240 "Time t psi - ts - tcrate (previous calibs) vs crate ID;crate ID;Time t_psi previous calib (ns)",
241 52, 1, 52 + 1, nbins, min_t, max_t);
242 registerObject<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib", TimevsCratePrevCrateCalibPrevCrystCalib);
244 auto TimevsCrysNoCalibrations =
new TH2F(
"TimevsCrysNoCalibrations",
245 "Time tpsi vs crystal cell ID;crystal cell ID;Time t_psi (ns)", 8736, 1, 8736 + 1, nbins, min_t, max_t);
246 registerObject<TH2F>(
"TimevsCrysNoCalibrations", TimevsCrysNoCalibrations);
248 auto TimevsCrateNoCalibrations =
new TH2F(
"TimevsCrateNoCalibrations",
249 "Time tpsi vs crate ID;crate ID;Time t_psi (ns)", 52, 1, 52 + 1, nbins, min_t, max_t);
250 registerObject<TH2F>(
"TimevsCrateNoCalibrations", TimevsCrateNoCalibrations);
252 auto TimevsCrysPrevCrateCalibNoCrystCalib =
new TH2F(
"TimevsCrysPrevCrateCalibNoCrystCalib",
253 "Time tpsi - tcrate (previous calib) vs crystal cell ID;crystal cell ID;Time t_psi including previous crate calib (ns)",
254 8736, 1, 8736 + 1, nbins, min_t, max_t);
255 registerObject<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib", TimevsCrysPrevCrateCalibNoCrystCalib);
257 auto TimevsCrateNoCrateCalibPrevCrystCalib =
new TH2F(
"TimevsCrateNoCrateCalibPrevCrystCalib",
258 "Time tpsi - ts (previous calib) vs crate ID;crate ID;Time t_psi including previous crystal calib (ns)",
259 52, 1, 52 + 1, nbins, min_t, max_t);
260 registerObject<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib", TimevsCrateNoCrateCalibPrevCrystCalib);
263 auto TsDatabase =
new TH1F(
"TsDatabase",
";cell id;Ts from database", 8736, 1, 8736 + 1);
264 registerObject<TH1F>(
"TsDatabase", TsDatabase);
266 auto TsDatabaseUnc =
new TH1F(
"TsDatabaseUnc",
";cell id;Ts uncertainty from database", 8736, 1, 8736 + 1);
267 registerObject<TH1F>(
"TsDatabaseUnc", TsDatabaseUnc);
269 auto TcrateDatabase =
new TH1F(
"TcrateDatabase",
";cell id;Tcrate from database", 8736, 1, 8736 + 1);
270 registerObject<TH1F>(
"TcrateDatabase", TcrateDatabase);
272 auto TcrateUncDatabase =
new TH1F(
"TcrateUncDatabase",
";cell id;Tcrate uncertainty from database", 8736, 1, 8736 + 1);
273 registerObject<TH1F>(
"TcrateUncDatabase", TcrateUncDatabase);
276 auto tcrateDatabase_ns =
new TH1F(
"tcrateDatabase_ns",
";crate id;tcrate derived from database", 52, 1, 52 + 1);
277 registerObject<TH1F>(
"tcrateDatabase_ns", tcrateDatabase_ns);
280 auto databaseCounter =
new TH1I(
"databaseCounter",
281 ";A database was read in;Number of times database was saved to histogram", 1, 1, 2);
282 registerObject<TH1I>(
"databaseCounter", databaseCounter);
285 auto numCrystalEntriesPerEvent =
new TH1F(
"numCrystalEntriesPerEvent",
286 ";Number crystal entries;Number of events", 15, 0, 15);
287 registerObject<TH1F>(
"numCrystalEntriesPerEvent", numCrystalEntriesPerEvent);
289 auto cutflow =
new TH1F(
"cutflow",
";Cut label number;Number of events passing cut", 20, 0, 20);
290 registerObject<TH1F>(
"cutflow", cutflow);
292 auto maxEcrsytalEnergyFraction =
new TH1F(
"maxEcrsytalEnergyFraction",
293 ";Maximum energy crystal energy / (sum) cluster energy;Number", 22, 0, 1.1);
294 registerObject<TH1F>(
"maxEcrsytalEnergyFraction", maxEcrsytalEnergyFraction);
296 auto refCrysIDzeroingCrate =
new TH1F(
"refCrysIDzeroingCrate",
";cell id;Boolean - is reference crystal", 8736, 1, 8736 + 1);
297 registerObject<TH1F>(
"refCrysIDzeroingCrate", refCrysIDzeroingCrate);
299 auto CDCEventT0Correction =
new TH1F(
"CDCEventT0Correction",
";;CDC event t0 offset correction [ns]", 1, 1, 2);
300 registerObject<TH1F>(
"CDCEventT0Correction", CDCEventT0Correction);
304 m_eventT0.isRequired();
306 m_eclClusterArray.isRequired();
307 m_eclCalDigitArray.isRequired();
308 m_eclDigitArray.isRequired();
310 B2INFO(
"hadronEventT0_TO_bhabhaEventT0_correction = " << m_hadronEventT0_TO_bhabhaEventT0_correction <<
311 " ns correction to CDC event t0 will be applied");
317 int cutIndexPassed = 0;
318 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
319 B2DEBUG(22,
"Cutflow: no cuts: index = " << cutIndexPassed);
320 B2DEBUG(22,
"Event number = " << m_EventMetaData->getEvent());
332 if (m_ElectronicsDB.hasChanged()) {
333 m_Electronics = m_ElectronicsDB->getCalibVector();
335 if (m_ElectronicsTimeDB.hasChanged()) {
336 m_ElectronicsTime = m_ElectronicsTimeDB->getCalibVector();
338 if (m_FlightTimeDB.hasChanged()) {
339 m_FlightTime = m_FlightTimeDB->getCalibVector();
344 if (m_PreviousCrystalTimeDB.hasChanged()) {
345 m_PreviousCrystalTime = m_PreviousCrystalTimeDB->getCalibVector();
346 m_PreviousCrystalTimeUnc = m_PreviousCrystalTimeDB->getCalibUncVector();
349 B2DEBUG(29,
"Finished checking if previous crystal time payload has changed");
350 if (m_CrateTimeDB.hasChanged()) {
351 m_CrateTime = m_CrateTimeDB->getCalibVector();
352 m_CrateTimeUnc = m_CrateTimeDB->getCalibUncVector();
354 B2DEBUG(29,
"Finished checking if previous crate time payload has changed");
355 B2DEBUG(29,
"m_CrateTime size = " << m_CrateTime.size());
356 B2DEBUG(25,
"Crate time +- uncertainty [0]= " << m_CrateTime[0] <<
" +- " << m_CrateTimeUnc[0]);
357 B2DEBUG(25,
"Crate time +- uncertainty [8735]= " << m_CrateTime[8735] <<
" +- " << m_CrateTimeUnc[8735]);
359 B2DEBUG(29,
"Finished checking if previous crate time payload has changed");
360 if (m_RefCrystalsCalibDB.hasChanged()) {
361 m_RefCrystalsCalib = m_RefCrystalsCalibDB->getReferenceCrystals();
363 B2DEBUG(29,
"Finished checking if reference crystal cell ids payload has changed");
366 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLCrystalTimeOffset from the database"
367 <<
LogVar(
"IoV", m_PreviousCrystalTimeDB.getIoV())
368 <<
LogVar(
"Checksum", m_PreviousCrystalTimeDB.getChecksum()));
369 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLCrateTimeOffset from the database"
370 <<
LogVar(
"IoV", m_CrateTimeDB.getIoV())
371 <<
LogVar(
"Checksum", m_CrateTimeDB.getChecksum()));
372 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLCrystalElectronics from the database"
373 <<
LogVar(
"IoV", m_ElectronicsDB.getIoV())
374 <<
LogVar(
"Checksum", m_ElectronicsDB.getChecksum()));
375 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLCrystalElectronicsTime from the database"
376 <<
LogVar(
"IoV", m_ElectronicsTimeDB.getIoV())
377 <<
LogVar(
"Checksum", m_ElectronicsTimeDB.getChecksum()));
378 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLCrystalFlightTime from the database"
379 <<
LogVar(
"IoV", m_FlightTimeDB.getIoV())
380 <<
LogVar(
"Checksum", m_FlightTimeDB.getChecksum()));
381 B2DEBUG(25,
"ECLBhabhaTCollector:: loaded ECLReferenceCrystalPerCrateCalib from the database"
382 <<
LogVar(
"IoV", m_RefCrystalsCalibDB.getIoV())
383 <<
LogVar(
"Checksum", m_RefCrystalsCalibDB.getChecksum()));
393 vector<float> Crate_time_ns(52, 0.0);
396 for (
int crysID = 1; crysID <= 8736; crysID++) {
397 int crateID_temp = crystalMapper->
getCrateID(crysID);
398 Crate_time_ns[crateID_temp - 1] = m_CrateTime[crysID] * TICKS_TO_NS;
408 for (
int crateID_temp = 1; crateID_temp <= 52; crateID_temp++) {
409 getObjectPtr<TH1F>(
"refCrysIDzeroingCrate")->Fill(m_RefCrystalsCalib[crateID_temp - 1] + 0.001);
414 for (
int crysID = 1; crysID <= 8736; crysID++) {
415 getObjectPtr<TH1F>(
"TsDatabase")->SetBinContent(crysID + 0.001, m_PreviousCrystalTime[crysID - 1]);
416 getObjectPtr<TH1F>(
"TsDatabaseUnc")->SetBinContent(crysID + 0.001, m_PreviousCrystalTimeUnc[crysID - 1]);
417 getObjectPtr<TH1F>(
"TcrateDatabase")->SetBinContent(crysID + 0.001, m_CrateTime[crysID - 1]);
418 getObjectPtr<TH1F>(
"TcrateUncDatabase")->SetBinContent(crysID + 0.001, m_CrateTimeUnc[crysID - 1]);
421 B2INFO(
"ECLBhabhaTCollector:: ECLCrystalTimeOffset from the database information:"
422 <<
LogVar(
"IoV", m_PreviousCrystalTimeDB.getIoV())
423 <<
LogVar(
"Checksum", m_PreviousCrystalTimeDB.getChecksum()));
424 B2INFO(
"First event so print out previous ts values");
425 for (
int crysID = 1; crysID <= 8736; crysID++) {
426 B2INFO(
"cid = " << crysID <<
", Ts previous = " << m_PreviousCrystalTime[crysID - 1]);
428 m_storeCalib =
false;
434 for (
int crateID_temp = 1; crateID_temp <= 52; crateID_temp++) {
435 getObjectPtr<TH1F>(
"tcrateDatabase_ns")->SetBinContent(crateID_temp + 0.001, Crate_time_ns[crateID_temp - 1]);
440 getObjectPtr<TH1I>(
"databaseCounter")->SetBinContent(1, 1);
445 getObjectPtr<TH1F>(
"CDCEventT0Correction")->SetBinContent(1, m_hadronEventT0_TO_bhabhaEventT0_correction);
452 double evt_t0_unc = -1;
453 double evt_t0_ECL_closestCDC = -1;
454 double evt_t0_ECL_minChi2 = -1;
457 if (!m_eventT0.isValid()) {
460 }
else if (!m_eventT0->hasTemporaryEventT0(Const::EDetector::CDC)) {
466 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
467 B2DEBUG(22,
"Cutflow: Event t0 exists: index = " << cutIndexPassed);
472 vector<EventT0::EventT0Component> evt_t0_list = m_eventT0->getTemporaryEventT0s(Const::EDetector::CDC);
473 evt_t0 = evt_t0_list.back().eventT0;
474 evt_t0_unc = evt_t0_list.back().eventT0Uncertainty;
478 evt_t0 = evt_t0 + m_hadronEventT0_TO_bhabhaEventT0_correction;
482 if (m_eventT0->hasTemporaryEventT0(Const::EDetector::ECL)) {
483 vector<EventT0::EventT0Component> evt_t0_list_ECL = m_eventT0->getTemporaryEventT0s(Const::EDetector::ECL);
486 double smallest_CDC_ECL_t0_diff = fabs(evt_t0_list_ECL[0].eventT0 - evt_t0);
487 int smallest_CDC_ECL_t0_diff_idx = 0;
488 for (
long unsigned int ECLi = 0; ECLi < evt_t0_list_ECL.size(); ECLi++) {
489 double tempt_ECL_t0 = evt_t0_list_ECL[ECLi].eventT0;
490 if (fabs(tempt_ECL_t0 - evt_t0) < smallest_CDC_ECL_t0_diff) {
491 smallest_CDC_ECL_t0_diff = fabs(tempt_ECL_t0 - evt_t0);
492 smallest_CDC_ECL_t0_diff_idx = ECLi;
496 evt_t0_ECL_closestCDC = evt_t0_list_ECL[smallest_CDC_ECL_t0_diff_idx].eventT0;
497 B2DEBUG(26,
"evt_t0_ECL_closestCDC = " << evt_t0_ECL_closestCDC);
501 double smallest_ECL_t0_minChi2 = evt_t0_list_ECL[0].quality;
502 int smallest_ECL_t0_minChi2_idx = 0;
504 B2DEBUG(26,
"evt_t0_list_ECL[0].quality = " << evt_t0_list_ECL[0].quality
505 <<
", with ECL event t0 = " << evt_t0_list_ECL[0].eventT0);
507 for (
long unsigned int ECLi = 0; ECLi < evt_t0_list_ECL.size(); ECLi++) {
508 B2DEBUG(26,
"evt_t0_list_ECL[" << ECLi <<
"].quality = " << evt_t0_list_ECL[ECLi].quality
509 <<
", with ECL event t0 = " <<
510 evt_t0_list_ECL[ECLi].eventT0);
511 if (evt_t0_list_ECL[ECLi].quality < smallest_ECL_t0_minChi2) {
512 smallest_ECL_t0_minChi2 = evt_t0_list_ECL[ECLi].quality;
513 smallest_ECL_t0_minChi2_idx = ECLi;
517 evt_t0_ECL_minChi2 = evt_t0_list_ECL[smallest_ECL_t0_minChi2_idx].eventT0;
519 B2DEBUG(26,
"evt_t0_ECL_minChi2 = " << evt_t0_ECL_minChi2);
520 B2DEBUG(26,
"smallest_ECL_t0_minChi2_idx = " << smallest_ECL_t0_minChi2_idx);
531 m_EperCrys.resize(8736);
532 m_eclCalDigitID.resize(8736);
533 m_eclDigitID.resize(8736);
537 for (
auto& eclCalDigit : m_eclCalDigitArray) {
538 int tempCrysID = eclCalDigit.getCellId() - 1;
539 m_EperCrys[tempCrysID] = eclCalDigit.getEnergy();
540 m_eclCalDigitID[tempCrysID] = idx;
545 for (
auto& eclDigit : m_eclDigitArray) {
546 int tempCrysID = eclDigit.getCellId() - 1;
547 m_eclDigitID[tempCrysID] = idx;
563 double maxp[2] = {0., 0.};
564 int maxiTrk[2] = { -1, -1};
565 int nTrkAll = tracks.getEntries();
573 for (
int iTrk = 0; iTrk < nTrkAll; iTrk++) {
577 if (not tempTrackFit) {
continue;}
580 short charge = tempTrackFit->getChargeSign();
581 double z0 = tempTrackFit->getZ0();
582 double d0 = tempTrackFit->getD0();
583 int nCDChits = tempTrackFit->getHitPatternCDC().getNHits();
584 double p = tempTrackFit->getMomentum().Mag();
592 m_tree_nCDChits = nCDChits;
595 m_dbgTree_tracks->Fill();
603 if (fabs(d0) > m_looseTrkD0) {
606 if (fabs(z0) > m_looseTrkZ0) {
626 if (fabs(d0) > m_tightTrkD0) {
629 if (fabs(z0) > m_tightTrkZ0) {
637 if (charge > 0) {icharge = 1;}
638 if (p > maxp[icharge]) {
640 maxiTrk[icharge] = iTrk;
649 if (nTrkTight != 2) {
654 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
655 B2DEBUG(22,
"Cutflow: Two tight tracks: index = " << cutIndexPassed);
658 if (nTrkLoose != 2) {
663 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
664 B2DEBUG(22,
"Cutflow: No additional loose tracks: index = " << cutIndexPassed);
670 bool oppositelyChargedTracksPassed = maxiTrk[0] != -1 && maxiTrk[1] != -1;
671 if (!oppositelyChargedTracksPassed) {
676 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
677 B2DEBUG(22,
"Cutflow: Oppositely charged tracks: index = " << cutIndexPassed);
686 double trkEClustLab[2] = {0., 0.};
687 double trkEClustCOM[2] = {0., 0.};
690 TLorentzVector trkp4Lab[2];
691 TLorentzVector trkp4COM[2];
694 int crysIDMax[2] = { -1, -1 };
695 double crysEMax[2] = { -1, -1 };
696 double crysE2Max[2] = { -1, -1 };
697 int numClustersPerTrack[2] = { 0, 0 };
699 double clusterTime[2] = {0, 0};
703 vector<double> time_ECLCaldigits_bothClusters;
704 vector<int> cid_ECLCaldigits_bothClusters;
705 vector<double> E_ECLCaldigits_bothClusters;
706 vector<double> amp_ECLDigits_bothClusters;
707 vector<int> chargeID_ECLCaldigits_bothClusters;
709 for (
int icharge = 0; icharge < 2; icharge++) {
710 if (maxiTrk[icharge] > -1) {
711 B2DEBUG(22,
"looping over the 2 max pt tracks");
714 if (not tempTrackFit) {
continue;}
715 trkp4Lab[icharge] = tempTrackFit->get4Momentum();
716 trkp4COM[icharge] = boostrotate.
rotateLabToCms() * trkp4Lab[icharge];
717 trkpLab[icharge] = trkp4Lab[icharge].Rho();
718 trkpCOM[icharge] = trkp4COM[icharge].Rho();
724 auto eclClusterRelationsFromTracks = tracks[maxiTrk[icharge]]->getRelationsTo<
ECLCluster>();
725 for (
unsigned int clusterIdx = 0; clusterIdx < eclClusterRelationsFromTracks.size(); clusterIdx++) {
727 B2DEBUG(22,
"Looking at clusters. index = " << clusterIdx);
728 auto cluster = eclClusterRelationsFromTracks[clusterIdx];
729 bool goodClusterType =
false;
733 goodClusterType =
true;
734 numClustersPerTrack[icharge]++;
737 if (goodClusterType) {
739 clusterTime[icharge] = cluster->getTime();
741 auto eclClusterRelations = cluster->getRelationsTo<
ECLCalDigit>(
"ECLCalDigits");
744 for (
unsigned int ir = 0; ir < eclClusterRelations.size(); ir++) {
745 const auto calDigit = eclClusterRelations.object(ir);
746 int tempCrysID = calDigit->
getCellId() - 1;
747 double tempE = m_EperCrys[tempCrysID];
749 int eclDigitIndex = m_eclDigitID[tempCrysID];
750 ECLDigit* ecl_dig = m_eclDigitArray[eclDigitIndex];
753 if (tempE > crysEMax[icharge]) {
755 crysE2Max[icharge] = crysEMax[icharge];
757 crysEMax[icharge] = tempE;
758 crysIDMax[icharge] = tempCrysID;
761 if (tempE > crysE2Max[icharge] && tempCrysID != crysIDMax[icharge]) {
762 crysE2Max[icharge] = tempE;
769 B2DEBUG(26,
"calDigit(ir" << ir <<
") time = " << calDigit->getTime() <<
"ns , with E = " << tempE <<
" GeV");
770 time_ECLCaldigits_bothClusters.push_back(calDigit->getTime());
771 cid_ECLCaldigits_bothClusters.push_back(tempCrysID);
772 E_ECLCaldigits_bothClusters.push_back(tempE);
773 amp_ECLDigits_bothClusters.push_back(ecl_dig->
getAmp());
774 chargeID_ECLCaldigits_bothClusters.push_back(icharge);
779 trkEClustCOM[icharge] = trkEClustLab[icharge] * trkpCOM[icharge] / trkpLab[icharge];
784 E_DIV_p[icharge] = trkEClustCOM[icharge] / trkpCOM[icharge];
798 int numCrystalsPassingCuts = 0;
800 int crystalIDs[2] = { -1, -1};
801 int crateIDs[2] = { -1, -1};
802 double ts_prevCalib[2] = { -1, -1};
803 double tcrate_prevCalib[2] = { -1, -1};
804 double times_noPreviousCalibrations[2] = { -1, -1};
805 bool crystalCutsPassed[2] = {
false,
false};
806 double crystalEnergies[2] = { -1, -1};
807 double crystalEnergies2[2] = { -1, -1};
809 for (
int iCharge = 0; iCharge < 2; iCharge++) {
810 int crystal_idx = crysIDMax[iCharge];
811 int eclCalDigitIndex = m_eclCalDigitID[crystal_idx];
812 int eclDigitIndex = m_eclDigitID[crystal_idx];
814 ECLDigit* ecl_dig = m_eclDigitArray[eclDigitIndex];
815 ECLCalDigit* ecl_cal = m_eclCalDigitArray[eclCalDigitIndex];
820 auto amplitude = ecl_dig->
getAmp();
821 crystalEnergies[iCharge] = en;
824 time = ecl_dig->
getTimeFit() * TICKS_TO_NS - evt_t0;
827 time -= m_ElectronicsTime[cid - 1] * TICKS_TO_NS;
828 time -= m_FlightTime[cid - 1];
833 double energyTimeShift = m_ECLTimeUtil->energyDependentTimeOffsetElectronic(amplitude * m_Electronics[cid - 1]) * TICKS_TO_NS;
835 B2DEBUG(29,
"cellid = " << cid <<
", amplitude = " << amplitude <<
", time before t(E) shift = " << time <<
836 ", t(E) shift = " << energyTimeShift <<
" ns");
837 time -= energyTimeShift;
841 if (cid < m_minCrystal || cid > m_maxCrystal)
continue;
844 if (fabs(time) > m_timeAbsMax)
continue;
850 crystalIDs[iCharge] = cid;
854 ts_prevCalib[iCharge] = m_PreviousCrystalTime[cid - 1] * TICKS_TO_NS;
855 tcrate_prevCalib[iCharge] = m_CrateTime[cid - 1] * TICKS_TO_NS;
856 times_noPreviousCalibrations[iCharge] = time;
859 B2DEBUG(26,
"iCharge = " << iCharge);
860 B2DEBUG(26,
"crateIDs[iCharge] = " << crateIDs[iCharge]);
861 B2DEBUG(26,
"times_noPreviousCalibrations[iCharge] = " << times_noPreviousCalibrations[iCharge]);
862 B2DEBUG(26,
"tcrate_prevCalib[iCharge] = " << tcrate_prevCalib[iCharge]);
863 B2DEBUG(26,
"ts_prevCalib[iCharge] = " << ts_prevCalib[iCharge]);
866 crystalCutsPassed[iCharge] =
true;
870 crystalEnergies2[iCharge] = crysE2Max[iCharge];
878 m_tree_amp = ecl_dig->
getAmp();
880 m_tree_E1Etot = en / trkEClustLab[iCharge];
881 m_tree_E1E2 = en / crystalEnergies2[iCharge];
882 m_tree_E1p = en / trkpLab[iCharge];
883 m_tree_timetsPreviousTimeCalibs = time - ts_prevCalib[iCharge] - tcrate_prevCalib[iCharge];
884 m_tree_timeF = ecl_dig->
getTimeFit() * TICKS_TO_NS;
888 m_tree_t0_unc = evt_t0_unc;
889 m_E_DIV_p = E_DIV_p[iCharge];
890 m_tree_evtNum = evtMetaData->getEvent();
892 m_runNum = evtMetaData->getRun();
895 m_dbgTree_electrons->Fill();
900 getObjectPtr<TH1F>(
"maxEcrsytalEnergyFraction")->Fill(en / trkEClustLab[iCharge]);
910 bool E_DIV_p_instance_passed[2] = {
false,
false};
911 double E_DIV_p_CUT = 0.7;
912 for (
int icharge = 0; icharge < 2; icharge++) {
913 E_DIV_p_instance_passed[icharge] = E_DIV_p[icharge] > E_DIV_p_CUT;
915 if (!E_DIV_p_instance_passed[0] || !E_DIV_p_instance_passed[1]) {
920 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
921 B2DEBUG(22,
"Cutflow: E_i/p_i > " << E_DIV_p_CUT <<
": index = " << cutIndexPassed);
927 double invMassTrk = (trkp4Lab[0] + trkp4Lab[1]).M();
928 double invMass_CUT = 0.9;
929 m_massInvTracks = invMassTrk;
933 m_dbgTree_event->Fill();
937 bool invMassCutsPassed = invMassTrk > (invMass_CUT * boostrotate.
getCMSEnergy());
938 if (!invMassCutsPassed) {
943 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
944 B2DEBUG(22,
"Cutflow: m(track 1+2) > " << invMass_CUT <<
"*E_COM = " << invMass_CUT <<
" * " << boostrotate.
getCMSEnergy() <<
945 " : index = " << cutIndexPassed);
950 for (
int iCharge = 0; iCharge < 2; iCharge++) {
951 if (crystalCutsPassed[iCharge]) {
952 getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib")->Fill((crystalIDs[iCharge]) + 0.001,
953 times_noPreviousCalibrations[iCharge] - ts_prevCalib[iCharge] - tcrate_prevCalib[iCharge] , 1);
954 getObjectPtr<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib")->Fill((crateIDs[iCharge]) + 0.001,
955 times_noPreviousCalibrations[iCharge] - ts_prevCalib[iCharge] - tcrate_prevCalib[iCharge], 1);
956 getObjectPtr<TH2F>(
"TimevsCrysNoCalibrations")->Fill((crystalIDs[iCharge]) + 0.001, times_noPreviousCalibrations[iCharge], 1);
957 getObjectPtr<TH2F>(
"TimevsCrateNoCalibrations")->Fill((crateIDs[iCharge]) + 0.001, times_noPreviousCalibrations[iCharge], 1);
958 getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib")->Fill((crystalIDs[iCharge]) + 0.001,
959 times_noPreviousCalibrations[iCharge] - tcrate_prevCalib[iCharge], 1);
960 getObjectPtr<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib")->Fill((crateIDs[iCharge]) + 0.001,
961 times_noPreviousCalibrations[iCharge] - ts_prevCalib[iCharge] , 1);
964 numCrystalsPassingCuts++;
972 if (crystalCutsPassed[0] || crystalCutsPassed[1]) {
975 getObjectPtr<TH1F>(
"cutflow")->Fill(cutIndexPassed);
976 B2DEBUG(22,
"Cutflow: At least one crystal time and quality cuts passed: index = " << cutIndexPassed);
978 getObjectPtr<TH1F>(
"numCrystalEntriesPerEvent")->Fill(numCrystalsPassingCuts);
983 for (
int iCharge = 0; iCharge < 2; iCharge++) {
984 if (crystalCutsPassed[iCharge]) {
987 m_tree_evtNum = evtMetaData->getEvent();
988 m_tree_cid = crystalIDs[iCharge];
990 m_tree_time = times_noPreviousCalibrations[iCharge];
991 m_crystalCrate = crateIDs[iCharge];
992 m_runNum = evtMetaData->getRun();
993 m_tree_en = crystalEnergies[iCharge];
994 m_tree_E1Etot = crystalEnergies[iCharge] / trkEClustLab[iCharge];
995 m_tree_E1E2 = crystalEnergies[iCharge] / crystalEnergies2[iCharge];
996 m_tree_E1p = crystalEnergies[iCharge] / trkpLab[iCharge];
997 m_tree_timetsPreviousTimeCalibs = times_noPreviousCalibrations[iCharge] - ts_prevCalib[iCharge] - tcrate_prevCalib[iCharge];
999 m_tree_t0_ECLclosestCDC = evt_t0_ECL_closestCDC;
1000 m_tree_t0_ECL_minChi2 = evt_t0_ECL_minChi2;
1001 m_tree_tClust = clusterTime[iCharge];
1003 m_massInvTracks = invMassTrk;
1006 m_dbgTree_allCuts->Fill();
1015 if (crystalCutsPassed[0] && crystalCutsPassed[1] &&
1016 numClustersPerTrack[0] == 1 && numClustersPerTrack[1] == 1) {
1017 m_tree_enNeg = trkEClustLab[0];
1018 m_tree_enPlus = trkEClustLab[1];
1019 m_tree_tClustNeg = clusterTime[0];
1020 m_tree_tClustPos = clusterTime[1];
1021 m_tree_maxEcrystPosClust = times_noPreviousCalibrations[0] - ts_prevCalib[0] - tcrate_prevCalib[0];
1022 m_tree_maxEcrystNegClust = times_noPreviousCalibrations[1] - ts_prevCalib[1] - tcrate_prevCalib[1];
1024 m_tree_t0_ECLclosestCDC = evt_t0_ECL_closestCDC;
1025 m_tree_t0_ECL_minChi2 = evt_t0_ECL_minChi2;
1029 m_dbgTree_evt_allCuts->Fill();
1035 B2DEBUG(26,
"m_tree_maxEcrystPosClust + evt_t0 = " << m_tree_maxEcrystPosClust + evt_t0);
1036 B2DEBUG(26,
"m_tree_maxEcrystNegClust + evt_t0 = " << m_tree_maxEcrystNegClust + evt_t0);
1037 B2DEBUG(26,
"CDC evt_t0 = " << evt_t0);
1038 B2DEBUG(26,
"ECL min chi2 even t0, m_tree_t0_ECL_minChi2 = " << m_tree_t0_ECL_minChi2);
1042 for (
long unsigned int digit_i = 0; digit_i < time_ECLCaldigits_bothClusters.size(); digit_i++) {
1044 m_runNum = evtMetaData->getRun();
1045 m_tree_evtNum = evtMetaData->getEvent();
1046 m_tree_ECLCalDigitTime = time_ECLCaldigits_bothClusters[digit_i];
1047 m_tree_ECLCalDigitE = E_ECLCaldigits_bothClusters[digit_i];
1048 m_tree_ECLDigitAmplitude = amp_ECLDigits_bothClusters[digit_i];
1050 m_tree_t0_ECLclosestCDC = evt_t0_ECL_closestCDC;
1051 m_tree_t0_ECL_minChi2 = evt_t0_ECL_minChi2;
1052 m_tree_timetsPreviousTimeCalibs = times_noPreviousCalibrations[chargeID_ECLCaldigits_bothClusters[digit_i]] -
1053 ts_prevCalib[chargeID_ECLCaldigits_bothClusters[digit_i]] -
1054 tcrate_prevCalib[chargeID_ECLCaldigits_bothClusters[digit_i]];
1055 m_tree_cid = cid_ECLCaldigits_bothClusters[digit_i];
1059 m_dbgTree_crys_allCuts->Fill();
1066 B2DEBUG(26,
"This was for event number = " << m_tree_evtNum);