10 #include <ecl/variables/ECLCalibrationVariables.h>
13 #include <analysis/dataobjects/Particle.h>
14 #include <analysis/dataobjects/ParticleList.h>
15 #include <analysis/dataobjects/ECLEnergyCloseToTrack.h>
16 #include <analysis/dataobjects/ECLTRGInformation.h>
17 #include <analysis/dataobjects/ECLTriggerCell.h>
18 #include <analysis/utility/ReferenceFrame.h>
19 #include <analysis/ClusterUtility/ClusterUtils.h>
20 #include <analysis/VariableManager/Utility.h>
23 #include <framework/core/Module.h>
24 #include <framework/logging/Logger.h>
25 #include <framework/datastore/StoreArray.h>
28 #include <mdst/dataobjects/ECLCluster.h>
29 #include <mdst/dataobjects/Track.h>
41 double eclEnergy3FWDBarrel(
const Particle* particle)
44 const Track* track = particle->getTrack();
47 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
50 return eclinfo->getEnergy3FWDBarrel();
52 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
53 return std::numeric_limits<float>::quiet_NaN();
57 return std::numeric_limits<float>::quiet_NaN();
60 double eclEnergy3FWDEndcap(
const Particle* particle)
63 const Track* track = particle->getTrack();
66 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
69 return eclinfo->getEnergy3FWDEndcap();
71 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
72 return std::numeric_limits<float>::quiet_NaN();
76 return std::numeric_limits<float>::quiet_NaN();
79 double eclEnergy3BWDBarrel(
const Particle* particle)
82 const Track* track = particle->getTrack();
85 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
88 return eclinfo->getEnergy3BWDBarrel();
90 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
91 return std::numeric_limits<float>::quiet_NaN();
95 return std::numeric_limits<float>::quiet_NaN();
98 double eclEnergy3BWDEndcap(
const Particle* particle)
100 const Track* track = particle->getTrack();
103 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
106 return eclinfo->getEnergy3BWDEndcap();
108 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
109 return std::numeric_limits<float>::quiet_NaN();
113 return std::numeric_limits<float>::quiet_NaN();
116 double eclNumberOfTCsForCluster(
const Particle* particle,
const std::vector<double>& vars)
118 if (vars.size() != 4) {
119 B2FATAL(
"Need exactly four parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
123 StoreArray<ECLTriggerCell> ecltc;
124 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
127 const int minTheta = int(std::lround(vars[0]));
128 const int maxTheta = int(std::lround(vars[1]));
129 if (maxTheta < minTheta) {
130 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
131 return std::numeric_limits<double>::quiet_NaN();
134 const int minHitWin = int(std::lround(vars[2]));
135 const int maxHitWin = int(std::lround(vars[3]));
136 if (maxHitWin < minHitWin) {
137 B2WARNING(
"minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
138 return std::numeric_limits<double>::quiet_NaN();
142 const ECLCluster* cluster = particle->getECLCluster();
146 auto relationsTCs = cluster->getRelationsWith<ECLTriggerCell>();
147 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
148 const auto tc = relationsTCs.object(idxTC);
149 if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
150 and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += 1.0;
156 double eclTCFADCForCluster(
const Particle* particle,
const std::vector<double>& vars)
158 if (vars.size() != 4) {
159 B2FATAL(
"Need exactly four parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
163 StoreArray<ECLTriggerCell> ecltc;
164 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
167 const int minTheta = int(std::lround(vars[0]));
168 const int maxTheta = int(std::lround(vars[1]));
169 if (maxTheta < minTheta) {
170 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
171 return std::numeric_limits<double>::quiet_NaN();
175 const int minHitWin = int(std::lround(vars[2]));
176 const int maxHitWin = int(std::lround(vars[3]));
177 if (maxHitWin < minHitWin) {
178 B2WARNING(
"minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
179 return std::numeric_limits<double>::quiet_NaN();
183 const ECLCluster* cluster = particle->getECLCluster();
187 auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
188 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
189 const auto tc = relationsTCs.object(idxTC);
190 if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
191 and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += tc->getFADC();
197 double eclTCIsMaximumForCluster(
const Particle* particle)
201 StoreArray<ECLTriggerCell> ecltc;
202 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
205 const ECLCluster* cluster = particle->getECLCluster();
209 auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
210 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
211 const auto tc = relationsTCs.object(idxTC);
212 if (tc->isHighestFADC()) result = 1.0;
218 double eclClusterTrigger(
const Particle* particle)
220 const ECLCluster* cluster = particle->getECLCluster();
222 const bool matcher = cluster->hasTriggerClusterMatching();
225 return cluster->isTriggerCluster();
227 B2WARNING(
"Particle has an associated ECLCluster but the ECLTriggerClusterMatcher module has not been run!");
228 return std::numeric_limits<float>::quiet_NaN();
231 return std::numeric_limits<float>::quiet_NaN();
234 double getEnergyTC(
const Particle*,
const std::vector<double>& vars)
236 if (vars.size() != 1) {
237 B2FATAL(
"Need exactly one parameter (tcid).");
240 StoreObjPtr<ECLTRGInformation> tce;
241 const int tcid = int(std::lround(vars[0]));
243 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
244 return tce->getEnergyTC(tcid);
247 double getEnergyTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
249 if (vars.size() != 1) {
250 B2FATAL(
"Need exactly one parameter (tcid).");
253 StoreObjPtr<ECLTRGInformation> tce;
254 const int tcid = int(std::lround(vars[0]));
256 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
257 return tce->getEnergyTCECLCalDigit(tcid);
260 double getTimingTC(
const Particle*,
const std::vector<double>& vars)
262 if (vars.size() != 1) {
263 B2FATAL(
"Need exactly one parameter (tcid).");
266 StoreObjPtr<ECLTRGInformation> tce;
267 const int tcid = int(std::lround(vars[0]));
269 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
270 return tce->getTimingTC(tcid);
273 double eclHitWindowTC(
const Particle*,
const std::vector<double>& vars)
275 if (vars.size() != 1) {
276 B2FATAL(
"Need exactly one parameter (tcid).");
279 StoreObjPtr<ECLTRGInformation> tce;
280 const int tcid = int(std::lround(vars[0]));
282 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
283 return tce->getHitWinTC(tcid);
286 double getEvtTimingTC(
const Particle*)
288 StoreObjPtr<ECLTRGInformation> tce;
289 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
290 return tce->getEvtTiming();
293 double getMaximumTCId(
const Particle*)
295 StoreObjPtr<ECLTRGInformation> tce;
296 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
297 return tce->getMaximumTCId();
300 double getTimingTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
302 if (vars.size() != 1) {
303 B2FATAL(
"Need exactly one parameter (tcid).");
306 StoreObjPtr<ECLTRGInformation> tce;
307 const int tcid = int(std::lround(vars[0]));
309 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
310 return tce->getTimingTCECLCalDigit(tcid);
313 double getNumberOfTCs(
const Particle*,
const std::vector<double>& vars)
315 if (vars.size() != 3) {
316 B2FATAL(
"Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
319 StoreArray<ECLTriggerCell> ecltcs;
320 const int fadccut = int(std::lround(vars[0]));
322 if (!ecltcs)
return std::numeric_limits<double>::quiet_NaN();
323 if (fadccut == 0)
return ecltcs.getEntries();
325 int minTheta = int(std::lround(vars[1]));
326 int maxTheta = int(std::lround(vars[2]));
329 for (
const auto& tc : ecltcs) {
330 if (tc.getFADC() >= fadccut and
331 tc.getThetaId() >= minTheta and
332 tc.getThetaId() <= maxTheta) nTCs++;
339 double eclEnergySumTC(
const Particle*,
const std::vector<double>& vars)
341 if (vars.size() != 3) {
342 B2FATAL(
"Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
345 StoreObjPtr<ECLTRGInformation> tce;
346 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
348 const int fadccut = int(std::lround(vars[0]));
349 const int minTheta = int(std::lround(vars[1]));
350 const int maxTheta = int(std::lround(vars[2]));
352 if (maxTheta < minTheta) {
353 B2WARNING(
"minTheta i (vars[1]) must be equal or less than maxTheta j (vars[2]).");
354 return std::numeric_limits<double>::quiet_NaN();
357 double energySum = 0.;
358 for (
unsigned idx = 1; idx <= 576; idx++) {
359 if (tce->getThetaIdTC(idx) >= minTheta and tce->getThetaIdTC(idx) <= maxTheta and tce->getEnergyTC(idx) >= fadccut) {
360 energySum += tce->getEnergyTC(idx);
367 double eclEnergySumTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
369 if (vars.size() != 3) {
370 B2FATAL(
"Need exactly three parameters (minthetaid, maxthetaid, option).");
373 StoreObjPtr<ECLTRGInformation> tce;
374 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
376 int minTheta = int(std::lround(vars[0]));
377 int maxTheta = int(std::lround(vars[1]));
378 int option = int(std::lround(vars[2]));
379 double par = vars[3];
381 if (maxTheta < minTheta) {
382 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
383 return std::numeric_limits<double>::quiet_NaN();
385 if (option < 0 or option > 2) {
386 B2WARNING(
"Third parameters k (vars[2]) must be >=0 and <=2.");
387 return std::numeric_limits<double>::quiet_NaN();
390 double energySum = 0.;
391 for (
unsigned idx = 1; idx <= 576; idx++) {
392 if (tce->getThetaIdTC(idx) >= minTheta and
393 tce->getThetaIdTC(idx) <= maxTheta) {
396 energySum += tce->getEnergyTCECLCalDigit(idx);
397 }
else if (option == 1 and tce->getEnergyTC(idx)) {
398 energySum += tce->getEnergyTCECLCalDigit(idx);
399 }
else if (option == 2 and tce->getEnergyTCECLCalDigit(idx) > par) {
400 energySum += tce->getEnergyTCECLCalDigit(idx);
408 double eclEnergySumTCECLCalDigitInECLCluster(
const Particle*)
410 StoreObjPtr<ECLTRGInformation> tce;
411 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
412 return tce->getSumEnergyTCECLCalDigitInECLCluster();
415 double eclEnergySumECLCalDigitInECLCluster(
const Particle*)
417 StoreObjPtr<ECLTRGInformation> tce;
418 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
419 return tce->getSumEnergyECLCalDigitInECLCluster();
422 double eclEnergySumTCECLCalDigitInECLClusterThreshold(
const Particle*)
424 StoreObjPtr<ECLTRGInformation> tce;
425 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
426 return tce->getClusterEnergyThreshold();
430 VARIABLE_GROUP(
"ECL calibration");
432 REGISTER_VARIABLE(
"eclEnergy3FWDBarrel", eclEnergy3FWDBarrel, R
"DOC(
433 [Calibration] Returns energy sum of three crystals in forward barrel.
436 REGISTER_VARIABLE("eclEnergy3FWDEndcap", eclEnergy3FWDEndcap, R
"DOC(
437 [Calibration] Returns energy sum of three crystals in forward endcap.
440 REGISTER_VARIABLE("eclEnergy3BWDBarrel", eclEnergy3BWDBarrel, R
"DOC(
441 [Calibration] Returns energy sum of three crystals in backward barrel.
444 REGISTER_VARIABLE("eclEnergy3BWDEndcap", eclEnergy3BWDEndcap, R
"DOC(
445 [Calibration] Returns energy sum of three crystals in backward endcap.
449 VARIABLE_GROUP(
"ECL trigger calibration");
451 REGISTER_VARIABLE(
"clusterNumberOfTCs(i, j, k, l)", eclNumberOfTCsForCluster, R
"DOC(
452 [Calibration] Returns the number of TCs for this ECL cluster for a given TC theta ID range
453 :math:`(i, j)` and hit window :math:`(k, l)`.
455 REGISTER_VARIABLE("clusterTCFADC(i, j, k, l)", eclTCFADCForCluster, R
"DOC(
456 [Calibration] Returns the total FADC sum related to this ECL cluster for a given TC theta ID
457 range :math:`(i, j)` and hit window :math:`(k, l)`.
459 REGISTER_VARIABLE("clusterTCIsMaximum", eclTCIsMaximumForCluster, R
"DOC(
460 [Calibration] Returns True if cluster is related to maximum TC.
462 REGISTER_VARIABLE("clusterTrigger", eclClusterTrigger, R
"DOC(
463 [Calibration] Returns 1.0 if ECL cluster is matched to a trigger cluster (requires to run eclTriggerClusterMatcher
464 (which requires TRGECLClusters in the input file)) and 0 otherwise. Returns -1 if the matching code was not run.
467 REGISTER_VARIABLE("eclEnergyTC(i)", getEnergyTC, R
"DOC(
468 [Eventbased][Calibration] Returns the energy (in FADC counts) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
470 REGISTER_VARIABLE("eclEnergyTCECLCalDigit(i)", getEnergyTCECLCalDigit, R
"DOC(
471 [Eventbased][Calibration] Returns the energy (in GeV) for the :math:`i`-th trigger cell (TC)
472 based on ECLCalDigits, 1 based (1..576).
474 REGISTER_VARIABLE("eclTimingTC(i)", getTimingTC, R
"DOC(
475 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
477 REGISTER_VARIABLE("eclHitWindowTC(i)", eclHitWindowTC, R
"DOC(
478 [Eventbased][Calibration] Returns the hit window for the :math:`i`-th trigger cell (TC), 1 based (1..576).
480 REGISTER_VARIABLE("eclEventTimingTC", getEvtTimingTC, R
"DOC(
481 [Eventbased][Calibration] Returns the ECL TC event time (in ns).
483 REGISTER_VARIABLE("eclMaximumTCId", getMaximumTCId, R
"DOC(
484 [Eventbased][Calibration] Returns the TC ID with maximum FADC value.
487 REGISTER_VARIABLE("eclTimingTCECLCalDigit(i)", getTimingTCECLCalDigit, R
"DOC(
488 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC) based
489 on ECLCalDigits, 1 based (1..576)
492 REGISTER_VARIABLE("eclNumberOfTCs(i, j, k)", getNumberOfTCs, R
"DOC(
493 [Eventbased][Calibration] Returns the number of TCs above threshold (i=FADC counts) for this event
494 for a given theta range (j-k)
496 REGISTER_VARIABLE("eclEnergySumTC(i, j)", eclEnergySumTC, R
"DOC(
497 [Eventbased][Calibration] Returns energy sum (in FADC counts) of all TC cells between two
498 theta ids i<=thetaid<=j, 1 based (1..17)
500 REGISTER_VARIABLE("eclEnergySumTCECLCalDigit(i, j, k, l)", eclEnergySumTCECLCalDigit, R
"DOC(
501 [Eventbased][Calibration] Returns energy sum (in GeV) of all TC cells between two theta ids i<=thetaid<=j,
502 1 based (1..17). k is the sum option: 0 (all), 1 (those with actual TC entries), 2 (sum of ECLCalDigit energy
503 in this TC above threshold). l is the threshold parameter for the option k 2.
505 REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLCluster", eclEnergySumTCECLCalDigitInECLCluster, R
"DOC(
506 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits if TC is above threshold
507 that are part of an ECLCluster above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
509 REGISTER_VARIABLE("eclEnergySumECLCalDigitInECLCluster", eclEnergySumECLCalDigitInECLCluster, R
"DOC(
510 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits that are part of an ECL cluster
511 above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
513 REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLClusterThreshold", eclEnergySumTCECLCalDigitInECLClusterThreshold, R
"DOC(
514 [Eventbased][Calibration] Returns threshold used to calculate eclEnergySumTCECLCalDigitInECLCluster.
Abstract base class for different kinds of events.