13 #include <analysis/variables/ECLVariables.h>
16 #include <framework/logging/Logger.h>
17 #include <framework/datastore/StoreArray.h>
20 #include <analysis/VariableManager/Manager.h>
21 #include <analysis/dataobjects/Particle.h>
22 #include <analysis/dataobjects/ECLEnergyCloseToTrack.h>
23 #include <analysis/dataobjects/ECLTRGInformation.h>
24 #include <analysis/dataobjects/ECLTriggerCell.h>
25 #include <analysis/utility/ReferenceFrame.h>
26 #include <analysis/ClusterUtility/ClusterUtils.h>
29 #include <mdst/dataobjects/ECLCluster.h>
30 #include <mdst/dataobjects/Track.h>
31 #include <mdst/dataobjects/EventLevelClusteringInfo.h>
43 double eclPulseShapeDiscriminationMVA(
const Particle* particle)
45 const ECLCluster* cluster = particle->getECLCluster();
47 if (eclClusterHasPulseShapeDiscrimination(particle)) {
48 return cluster->getPulseShapeDiscriminationMVA();
53 return std::numeric_limits<float>::quiet_NaN();
56 double eclClusterNumberOfHadronDigits(
const Particle* particle)
59 const ECLCluster* cluster = particle->getECLCluster();
61 if (eclClusterHasPulseShapeDiscrimination(particle)) {
62 return cluster->getNumberOfHadronDigits();
66 return std::numeric_limits<float>::quiet_NaN();
69 double eclClusterDetectionRegion(
const Particle* particle)
72 const ECLCluster* cluster = particle->getECLCluster();
74 return cluster->getDetectorRegion();
76 return std::numeric_limits<float>::quiet_NaN();
79 double eclClusterIsolation(
const Particle* particle)
82 const ECLCluster* cluster = particle->getECLCluster();
84 return cluster->getMinTrkDistance();
86 return std::numeric_limits<float>::quiet_NaN();
89 double eclClusterConnectedRegionID(
const Particle* particle)
92 const ECLCluster* cluster = particle->getECLCluster();
94 return cluster->getConnectedRegionId();
96 return std::numeric_limits<float>::quiet_NaN();
99 double eclClusterDeltaL(
const Particle* particle)
102 const ECLCluster* cluster = particle->getECLCluster();
104 return cluster->getDeltaL();
106 return std::numeric_limits<float>::quiet_NaN();
110 double eclClusterErrorE(
const Particle* particle)
113 const ECLCluster* cluster = particle->getECLCluster();
115 return cluster->getUncertaintyEnergy();
117 return std::numeric_limits<float>::quiet_NaN();
120 double eclClusterUncorrectedE(
const Particle* particle)
123 const ECLCluster* cluster = particle->getECLCluster();
125 return cluster->getEnergyRaw();
127 return std::numeric_limits<float>::quiet_NaN();
130 double eclClusterE(
const Particle* particle)
134 const ECLCluster* cluster = particle->getECLCluster();
137 TLorentzVector p4Cluster = clutls.GetCluster4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
139 return frame.getMomentum(p4Cluster).E();
141 return std::numeric_limits<float>::quiet_NaN();
144 double eclClusterHighestE(
const Particle* particle)
147 const ECLCluster* cluster = particle->getECLCluster();
149 return cluster->getEnergyHighestCrystal();
151 return std::numeric_limits<float>::quiet_NaN();
154 double eclClusterCellId(
const Particle* particle)
157 const ECLCluster* cluster = particle->getECLCluster();
159 return cluster->getMaxECellId();
161 return std::numeric_limits<float>::quiet_NaN();
164 double eclClusterTiming(
const Particle* particle)
167 const ECLCluster* cluster = particle->getECLCluster();
169 return cluster->getTime();
171 return std::numeric_limits<float>::quiet_NaN();
174 double eclClusterHasFailedTiming(
const Particle* particle)
176 const ECLCluster* cluster = particle->getECLCluster();
178 return cluster->hasFailedFitTime();
180 return std::numeric_limits<float>::quiet_NaN();
183 double eclClusterErrorTiming(
const Particle* particle)
186 const ECLCluster* cluster = particle->getECLCluster();
188 return cluster->getDeltaTime99();
190 return std::numeric_limits<float>::quiet_NaN();
193 double eclClusterHasFailedErrorTiming(
const Particle* particle)
195 const ECLCluster* cluster = particle->getECLCluster();
197 return cluster->hasFailedTimeResolution();
199 return std::numeric_limits<float>::quiet_NaN();
202 double eclClusterTheta(
const Particle* particle)
206 const ECLCluster* cluster = particle->getECLCluster();
209 TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
211 return frame.getMomentum(p4Cluster).Theta();
213 return std::numeric_limits<float>::quiet_NaN();
216 double eclClusterErrorTheta(
const Particle* particle)
219 const ECLCluster* cluster = particle->getECLCluster();
221 return cluster->getUncertaintyTheta();
223 return std::numeric_limits<float>::quiet_NaN();
226 double eclClusterErrorPhi(
const Particle* particle)
229 const ECLCluster* cluster = particle->getECLCluster();
231 return cluster->getUncertaintyPhi();
233 return std::numeric_limits<float>::quiet_NaN();
236 double eclClusterPhi(
const Particle* particle)
240 const ECLCluster* cluster = particle->getECLCluster();
243 TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
245 return frame.getMomentum(p4Cluster).Phi();
247 return std::numeric_limits<float>::quiet_NaN();
250 double eclClusterR(
const Particle* particle)
253 const ECLCluster* cluster = particle->getECLCluster();
255 return cluster->getR();
257 return std::numeric_limits<float>::quiet_NaN();
260 double eclClusterE1E9(
const Particle* particle)
263 const ECLCluster* cluster = particle->getECLCluster();
265 return cluster->getE1oE9();
267 return std::numeric_limits<float>::quiet_NaN();
270 double eclClusterE9E21(
const Particle* particle)
273 const ECLCluster* cluster = particle->getECLCluster();
275 return cluster->getE9oE21();
277 return std::numeric_limits<float>::quiet_NaN();
280 double eclClusterAbsZernikeMoment40(
const Particle* particle)
283 const ECLCluster* cluster = particle->getECLCluster();
285 return cluster->getAbsZernike40();
287 return std::numeric_limits<float>::quiet_NaN();
290 double eclClusterAbsZernikeMoment51(
const Particle* particle)
293 const ECLCluster* cluster = particle->getECLCluster();
295 return cluster->getAbsZernike51();
297 return std::numeric_limits<float>::quiet_NaN();
300 double eclClusterZernikeMVA(
const Particle* particle)
303 const ECLCluster* cluster = particle->getECLCluster();
305 return cluster->getZernikeMVA();
307 return std::numeric_limits<float>::quiet_NaN();
310 double eclClusterSecondMoment(
const Particle* particle)
313 const ECLCluster* cluster = particle->getECLCluster();
315 return cluster->getSecondMoment();
317 return std::numeric_limits<float>::quiet_NaN();
320 double eclClusterLAT(
const Particle* particle)
323 const ECLCluster* cluster = particle->getECLCluster();
325 return cluster->getLAT();
327 return std::numeric_limits<float>::quiet_NaN();
330 double eclClusterNHits(
const Particle* particle)
333 const ECLCluster* cluster = particle->getECLCluster();
335 return cluster->getNumberOfCrystals();
337 return std::numeric_limits<float>::quiet_NaN();
340 double eclClusterTrackMatched(
const Particle* particle)
343 const ECLCluster* cluster = particle->getECLCluster();
345 const Track* track = cluster->getRelatedFrom<Track>();
352 return std::numeric_limits<float>::quiet_NaN();
355 double nECLClusterTrackMatches(
const Particle* particle)
358 const ECLCluster* cluster = particle->getECLCluster();
360 return std::numeric_limits<double>::quiet_NaN();
363 size_t out = cluster->getRelationsFrom<Track>().size();
367 double eclClusterConnectedRegionId(
const Particle* particle)
369 const ECLCluster* cluster = particle->getECLCluster();
371 return cluster->getConnectedRegionId();
373 return std::numeric_limits<float>::quiet_NaN();
376 double eclClusterId(
const Particle* particle)
378 const ECLCluster* cluster = particle->getECLCluster();
380 return cluster->getClusterId();
382 return std::numeric_limits<float>::quiet_NaN();
385 double eclClusterHasNPhotonsHypothesis(
const Particle* particle)
387 const ECLCluster* cluster = particle->getECLCluster();
391 return std::numeric_limits<float>::quiet_NaN();
394 double eclClusterHasNeutralHadronHypothesis(
const Particle* particle)
396 const ECLCluster* cluster = particle->getECLCluster();
400 return std::numeric_limits<float>::quiet_NaN();
403 double eclClusterHasPulseShapeDiscrimination(
const Particle* particle)
405 const ECLCluster* cluster = particle->getECLCluster();
407 return cluster->hasPulseShapeDiscrimination();
409 return std::numeric_limits<float>::quiet_NaN();
412 double eclClusterTrigger(
const Particle* particle)
414 const ECLCluster* cluster = particle->getECLCluster();
416 const bool matcher = cluster->hasTriggerClusterMatching();
419 return cluster->isTriggerCluster();
421 B2WARNING(
"Particle has an associated ECLCluster but the ECLTriggerClusterMatcher module has not been run!");
425 return std::numeric_limits<float>::quiet_NaN();
428 double eclExtTheta(
const Particle* particle)
431 const Track* track = particle->getTrack();
434 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
437 return eclinfo->getExtTheta();
439 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
440 return std::numeric_limits<float>::quiet_NaN();
444 return std::numeric_limits<float>::quiet_NaN();
447 double eclExtPhi(
const Particle* particle)
450 const Track* track = particle->getTrack();
453 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
456 return eclinfo->getExtPhi();
458 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
459 return std::numeric_limits<float>::quiet_NaN();
463 return std::numeric_limits<float>::quiet_NaN();
466 double eclExtPhiId(
const Particle* particle)
468 const Track* track = particle->getTrack();
471 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
474 return eclinfo->getExtPhiId();
476 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
477 return std::numeric_limits<float>::quiet_NaN();
481 return std::numeric_limits<float>::quiet_NaN();
484 double eclEnergy3FWDBarrel(
const Particle* particle)
487 const Track* track = particle->getTrack();
490 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
493 return eclinfo->getEnergy3FWDBarrel();
495 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
496 return std::numeric_limits<float>::quiet_NaN();
500 return std::numeric_limits<float>::quiet_NaN();
503 double eclEnergy3FWDEndcap(
const Particle* particle)
506 const Track* track = particle->getTrack();
509 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
512 return eclinfo->getEnergy3FWDEndcap();
514 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
515 return std::numeric_limits<float>::quiet_NaN();
519 return std::numeric_limits<float>::quiet_NaN();
522 double eclEnergy3BWDEndcap(
const Particle* particle)
524 const Track* track = particle->getTrack();
527 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
530 return eclinfo->getEnergy3BWDEndcap();
532 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
533 return std::numeric_limits<float>::quiet_NaN();
537 return std::numeric_limits<float>::quiet_NaN();
540 double eclEnergy3BWDBarrel(
const Particle* particle)
543 const Track* track = particle->getTrack();
546 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
549 return eclinfo->getEnergy3BWDBarrel();
551 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
552 return std::numeric_limits<float>::quiet_NaN();
556 return std::numeric_limits<float>::quiet_NaN();
559 double weightedAverageECLTime(
const Particle* particle)
561 int nDaughters = particle->getNDaughters();
562 if (nDaughters < 1) {
563 B2WARNING(
"The provided particle has no daughters!");
564 return std::numeric_limits<float>::quiet_NaN();
567 double numer = 0, denom = 0;
568 int numberOfClusterDaughters = 0;
570 auto weightedECLTimeAverage = [&numer, &denom, &numberOfClusterDaughters](
const Particle * p) {
571 const ECLCluster* cluster = p->getECLCluster();
572 if (cluster and not cluster->hasFailedFitTime()) {
573 numberOfClusterDaughters ++;
575 double time = cluster->getTime();
576 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
577 double deltatime = cluster->getDeltaTime99();
578 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
579 numer += time / pow(deltatime, 2);
580 B2DEBUG(11,
"numer[" << numberOfClusterDaughters <<
"] = " << numer);
581 denom += 1 / pow(deltatime, 2);
582 B2DEBUG(11,
"denom[" << numberOfClusterDaughters <<
"] = " << denom);
587 particle->forEachDaughter(weightedECLTimeAverage,
true,
true);
589 if (numberOfClusterDaughters < 1) {
590 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
591 return std::numeric_limits<float>::quiet_NaN();
595 B2WARNING(
"The denominator of the weighted mean is zero!");
596 return std::numeric_limits<float>::quiet_NaN();
598 B2DEBUG(10,
"numer/denom = " << numer / denom);
599 return numer / denom;
603 double maxWeightedDistanceFromAverageECLTime(
const Particle* particle)
605 int nDaughters = particle->getNDaughters();
606 if (nDaughters < 1) {
607 B2WARNING(
"The provided particle has no daughters!");
608 return std::numeric_limits<float>::quiet_NaN();
611 double maxTimeDiff = -DBL_MAX;
612 int numberOfClusterDaughters = 0;
614 double averageECLTime = weightedAverageECLTime(particle);
616 auto maxTimeDifference = [&maxTimeDiff, &numberOfClusterDaughters, &averageECLTime](
const Particle * p) {
618 const ECLCluster* cluster = p->getECLCluster();
620 numberOfClusterDaughters ++;
622 double time = cluster->getTime();
623 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
624 double deltatime = cluster->getDeltaTime99();
625 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
626 double maxTimeDiff_temp = fabs((time - averageECLTime) / deltatime);
627 B2DEBUG(11,
"maxTimeDiff_temp[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff_temp);
628 if (maxTimeDiff_temp > maxTimeDiff)
629 maxTimeDiff = maxTimeDiff_temp;
630 B2DEBUG(11,
"maxTimeDiff[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff);
635 particle->forEachDaughter(maxTimeDifference,
true,
true);
637 if (numberOfClusterDaughters < 1) {
638 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
639 return std::numeric_limits<float>::quiet_NaN();
642 if (maxTimeDiff < 0) {
643 B2WARNING(
"The max time difference is negative!");
644 return std::numeric_limits<float>::quiet_NaN();
646 B2DEBUG(10,
"maxTimeDiff = " << maxTimeDiff);
651 double eclClusterMdstIndex(
const Particle* particle)
653 const ECLCluster* cluster = particle->getECLCluster();
655 return cluster->getArrayIndex();
656 }
else return std::numeric_limits<double>::quiet_NaN();
658 return std::numeric_limits<double>::quiet_NaN();
665 double nECLOutOfTimeCrystalsFWDEndcap(
const Particle*)
667 StoreObjPtr<EventLevelClusteringInfo> elci;
668 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
669 return (
double)elci->getNECLCalDigitsOutOfTimeFWD();
672 double nECLOutOfTimeCrystalsBarrel(
const Particle*)
674 StoreObjPtr<EventLevelClusteringInfo> elci;
675 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
676 return (
double)elci->getNECLCalDigitsOutOfTimeBarrel();
679 double nECLOutOfTimeCrystalsBWDEndcap(
const Particle*)
681 StoreObjPtr<EventLevelClusteringInfo> elci;
682 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
683 return (
double)elci->getNECLCalDigitsOutOfTimeBWD();
686 double nECLOutOfTimeCrystals(
const Particle*)
688 StoreObjPtr<EventLevelClusteringInfo> elci;
689 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
690 return (
double)elci->getNECLCalDigitsOutOfTime();
693 double nRejectedECLShowersFWDEndcap(
const Particle*)
695 StoreObjPtr<EventLevelClusteringInfo> elci;
696 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
697 return (
double)elci->getNECLShowersRejectedFWD();
700 double nRejectedECLShowersBarrel(
const Particle*)
702 StoreObjPtr<EventLevelClusteringInfo> elci;
703 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
704 return (
double)elci->getNECLShowersRejectedBarrel();
707 double nRejectedECLShowersBWDEndcap(
const Particle*)
709 StoreObjPtr<EventLevelClusteringInfo> elci;
710 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
711 return (
double)elci->getNECLShowersRejectedBWD();
714 double nRejectedECLShowers(
const Particle*)
716 StoreObjPtr<EventLevelClusteringInfo> elci;
717 if (!elci)
return std::numeric_limits<double>::quiet_NaN();
718 return (
double) elci->getNECLShowersRejected();
721 double eclClusterEoP(
const Particle* part)
723 double E = eclClusterE(part);
724 if (part->hasExtraInfo(
"bremsCorrectedPhotonEnergy")) {
725 E += part->getExtraInfo(
"bremsCorrectedPhotonEnergy");
727 const double p = part->getMomentumMagnitude();
728 if (0 == p) {
return std::numeric_limits<float>::quiet_NaN();}
732 double getEnergyTC(
const Particle*,
const std::vector<double>& vars)
734 if (vars.size() != 1) {
735 B2FATAL(
"Need exactly one parameters (tcid).");
738 StoreObjPtr<ECLTRGInformation> tce;
739 const int tcid = int(std::lround(vars[0]));
741 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
742 return tce->getEnergyTC(tcid);
745 double getTimingTC(
const Particle*,
const std::vector<double>& vars)
747 if (vars.size() != 1) {
748 B2FATAL(
"Need exactly one parameters (tcid).");
751 StoreObjPtr<ECLTRGInformation> tce;
752 const int tcid = int(std::lround(vars[0]));
754 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
755 return tce->getTimingTC(tcid);
758 double eclHitWindowTC(
const Particle*,
const std::vector<double>& vars)
760 if (vars.size() != 1) {
761 B2FATAL(
"Need exactly one parameters (tcid).");
764 StoreObjPtr<ECLTRGInformation> tce;
765 const int tcid = int(std::lround(vars[0]));
767 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
768 return tce->getHitWinTC(tcid);
771 double getEvtTimingTC(
const Particle*)
773 StoreObjPtr<ECLTRGInformation> tce;
774 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
775 return tce->getEvtTiming();
778 double getMaximumTCId(
const Particle*)
780 StoreObjPtr<ECLTRGInformation> tce;
781 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
782 return tce->getMaximumTCId();
786 double getNumberOfTCs(
const Particle*,
const std::vector<double>& vars)
788 if (vars.size() != 3) {
789 B2FATAL(
"Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
792 StoreArray<ECLTriggerCell> ecltcs;
793 const int fadccut = int(std::lround(vars[0]));
795 if (!ecltcs)
return std::numeric_limits<double>::quiet_NaN();
796 if (fadccut == 0)
return ecltcs.getEntries();
798 int minTheta = int(std::lround(vars[1]));
799 int maxTheta = int(std::lround(vars[2]));
802 for (
const auto& tc : ecltcs) {
803 if (tc.getFADC() >= fadccut and
804 tc.getThetaId() >= minTheta and
805 tc.getThetaId() <= maxTheta) nTCs++;
812 double getEnergyTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
814 if (vars.size() != 1) {
815 B2FATAL(
"Need exactly one parameter (tcid).");
818 StoreObjPtr<ECLTRGInformation> tce;
819 const int tcid = int(std::lround(vars[0]));
821 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
822 return tce->getEnergyTCECLCalDigit(tcid);
825 double getTimingTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
827 if (vars.size() != 1) {
828 B2FATAL(
"Need exactly one parameter (tcid).");
831 StoreObjPtr<ECLTRGInformation> tce;
832 const int tcid = int(std::lround(vars[0]));
834 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
835 return tce->getTimingTCECLCalDigit(tcid);
838 double eclEnergySumTC(
const Particle*,
const std::vector<double>& vars)
840 if (vars.size() != 3) {
841 B2FATAL(
"Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
844 StoreObjPtr<ECLTRGInformation> tce;
845 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
847 const int fadccut = int(std::lround(vars[0]));
848 const int minTheta = int(std::lround(vars[1]));
849 const int maxTheta = int(std::lround(vars[2]));
851 if (maxTheta < minTheta) {
852 B2WARNING(
"minTheta i (vars[1]) must be equal or less than maxTheta j (vars[2]).");
853 return std::numeric_limits<double>::quiet_NaN();
856 double energySum = 0.;
857 for (
unsigned idx = 1; idx <= 576; idx++) {
858 if (tce->getThetaIdTC(idx) >= minTheta and tce->getThetaIdTC(idx) <= maxTheta and tce->getEnergyTC(idx) >= fadccut) {
859 energySum += tce->getEnergyTC(idx);
866 double eclEnergySumTCECLCalDigit(
const Particle*,
const std::vector<double>& vars)
868 if (vars.size() != 3) {
869 B2FATAL(
"Need exactly three parameters (minthetaid, maxthetaid, option).");
872 StoreObjPtr<ECLTRGInformation> tce;
873 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
875 int minTheta = int(std::lround(vars[0]));
876 int maxTheta = int(std::lround(vars[1]));
877 int option = int(std::lround(vars[2]));
878 double par = vars[3];
880 if (maxTheta < minTheta) {
881 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
882 return std::numeric_limits<double>::quiet_NaN();
884 if (option < 0 or option > 2) {
885 B2WARNING(
"Third parameters k (vars[2]) must be >=0 and <=2.");
886 return std::numeric_limits<double>::quiet_NaN();
889 double energySum = 0.;
890 for (
unsigned idx = 1; idx <= 576; idx++) {
891 if (tce->getThetaIdTC(idx) >= minTheta and
892 tce->getThetaIdTC(idx) <= maxTheta) {
895 energySum += tce->getEnergyTCECLCalDigit(idx);
896 }
else if (option == 1 and tce->getEnergyTC(idx)) {
897 energySum += tce->getEnergyTCECLCalDigit(idx);
898 }
else if (option == 2 and tce->getEnergyTCECLCalDigit(idx) > par) {
899 energySum += tce->getEnergyTCECLCalDigit(idx);
907 double eclEnergySumTCECLCalDigitInECLCluster(
const Particle*)
909 StoreObjPtr<ECLTRGInformation> tce;
910 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
911 return tce->getSumEnergyTCECLCalDigitInECLCluster();
914 double eclEnergySumECLCalDigitInECLCluster(
const Particle*)
916 StoreObjPtr<ECLTRGInformation> tce;
917 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
918 return tce->getSumEnergyECLCalDigitInECLCluster();
921 double eclEnergySumTCECLCalDigitInECLClusterThreshold(
const Particle*)
923 StoreObjPtr<ECLTRGInformation> tce;
924 if (!tce)
return std::numeric_limits<double>::quiet_NaN();
925 return tce->getClusterEnergyThreshold();
928 double eclNumberOfTCsForCluster(
const Particle* particle,
const std::vector<double>& vars)
930 if (vars.size() != 4) {
931 B2FATAL(
"Need exactly two parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
935 StoreArray<ECLTriggerCell> ecltc;
936 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
939 const int minTheta = int(std::lround(vars[0]));
940 const int maxTheta = int(std::lround(vars[1]));
941 if (maxTheta < minTheta) {
942 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
943 return std::numeric_limits<double>::quiet_NaN();
946 const int minHitWin = int(std::lround(vars[2]));
947 const int maxHitWin = int(std::lround(vars[3]));
948 if (maxHitWin < minHitWin) {
949 B2WARNING(
"minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
950 return std::numeric_limits<double>::quiet_NaN();
954 const ECLCluster* cluster = particle->getECLCluster();
958 auto relationsTCs = cluster->getRelationsWith<ECLTriggerCell>();
959 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
960 const auto tc = relationsTCs.object(idxTC);
961 if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
962 and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += 1.0;
968 double eclTCFADCForCluster(
const Particle* particle,
const std::vector<double>& vars)
970 if (vars.size() != 4) {
971 B2FATAL(
"Need exactly four parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
975 StoreArray<ECLTriggerCell> ecltc;
976 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
979 const int minTheta = int(std::lround(vars[0]));
980 const int maxTheta = int(std::lround(vars[1]));
981 if (maxTheta < minTheta) {
982 B2WARNING(
"minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
983 return std::numeric_limits<double>::quiet_NaN();
987 const int minHitWin = int(std::lround(vars[2]));
988 const int maxHitWin = int(std::lround(vars[3]));
989 if (maxHitWin < minHitWin) {
990 B2WARNING(
"minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
991 return std::numeric_limits<double>::quiet_NaN();
995 const ECLCluster* cluster = particle->getECLCluster();
999 auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
1000 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
1001 const auto tc = relationsTCs.object(idxTC);
1002 if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
1003 and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += tc->getFADC();
1009 double eclTCIsMaximumForCluster(
const Particle* particle)
1013 StoreArray<ECLTriggerCell> ecltc;
1014 if (!ecltc)
return std::numeric_limits<double>::quiet_NaN();
1017 const ECLCluster* cluster = particle->getECLCluster();
1021 auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
1022 for (
unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
1023 const auto tc = relationsTCs.object(idxTC);
1024 if (tc->isHighestFADC()) result = 1.0;
1030 double eclClusterOnlyInvariantMass(
const Particle* part)
1032 int nDaughters = part->getNDaughters();
1035 if (nDaughters < 1) {
1036 return part->getMass();
1038 int nClusterDaughters = 0;
1039 std::stack<const Particle*> stacked;
1041 while (!stacked.empty()) {
1042 const Particle* current = stacked.top();
1045 const ECLCluster* cluster = current->getECLCluster();
1048 nClusterDaughters ++;
1049 ClusterUtils clutls;
1050 TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterBit);
1053 const std::vector<Particle*> daughters = current->getDaughters();
1054 nDaughters = current->getNDaughters();
1055 for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
1056 stacked.push(daughters[iDaughter]);
1061 if (nClusterDaughters < 1) {
1062 B2WARNING(
"There are no clusters amongst the daughters of the provided particle!");
1063 return std::numeric_limits<double>::quiet_NaN();
1065 B2DEBUG(10,
"Number of daughters with cluster associated = " << nClusterDaughters);
1071 VARIABLE_GROUP(
"ECL Cluster related");
1072 REGISTER_VARIABLE(
"clusterEoP", eclClusterEoP, R
"DOC(
1073 Returns ratio of uncorrelated energy E over momentum p, a convenience
1074 alias for (clusterE / p).
1076 REGISTER_VARIABLE("clusterReg", eclClusterDetectionRegion, R
"DOC(
1077 Returns an integer code for the ECL region of a cluster.
1079 - 1: forward, 2: barrel, 3: backward,
1080 - 11: between FWD and barrel, 13: between BWD and barrel,
1083 REGISTER_VARIABLE("clusterDeltaLTemp", eclClusterDeltaL, R
"DOC(
1084 | Returns DeltaL for the shower shape.
1085 | A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1086 different orientations in space. A shower direction can be constructed by calculating the weighted
1087 average of these orientations using the corresponding energy depositions as weights. The intersection
1088 (more precisely the point of closest approach) of the vector with this direction originating from the
1089 cluster center and an extrapolated track can be used as reference for the calculation of the shower
1090 depth. It is defined as the distance between this intersection and the cluster center.
1093 This distance is calculated on the reconstructed level and is temporarily
1094 included to the ECL cluster MDST data format for studying purposes. If it is found
1095 that it is not crucial for physics analysis then this variable will be removed
1097 Therefore, keep in mind that this variable might be removed in the future!
1100 | Please read `this <importantNoteECL>` first.
1101 | Lower limit: :math:`-250.0`
1102 | Upper limit: :math:`250.0`
1103 | Precision: :math:`10` bit
1105 REGISTER_VARIABLE("minC2TDist", eclClusterIsolation, R
"DOC(
1106 Returns distance between ECL cluster and nearest track hitting the ECL.
1108 A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1109 different orientations in space. A shower direction can be constructed by calculating the weighted
1110 average of these orientations using the corresponding energy depositions as weights. The intersection
1111 (more precisely the point of closest approach) of the vector with this direction originating from the
1112 cluster center and an extrapolated track can be used as reference for the calculation of the track depth.
1113 It is defined as the distance between this intersection and the track hit position on the front face of the ECL.
1116 This distance is calculated on the reconstructed level.
1119 | Please read `this <importantNoteECL>` first.
1120 | Lower limit: :math:`0.0`
1121 | Upper limit: :math:`250.0`
1122 | Precision: :math:`10` bit
1124 REGISTER_VARIABLE("clusterE", eclClusterE, R
"DOC(
1125 Returns ECL cluster's energy corrected for leakage and background.
1127 The raw photon energy is given by the weighted sum of all ECL crystal energies within the ECL cluster.
1128 The weights per crystals are :math:`\leq 1` after cluster energy splitting in the case of overlapping
1129 clusters. The number of crystals that are included in the sum depends on a initial energy estimation
1130 and local beam background levels at the highest energy crystal position. It is optimized to minimize
1131 the core width (resolution) of true photons. Photon energy distributions always show a low energy tail
1132 due to unavoidable longitudinal and transverse leakage that can be further modified by the clustering
1133 algorithm and beam backgrounds.The peak position of the photon energy distributions are corrected to
1134 match the true photon energy in MC:
1136 - Leakage correction: Using large MC samples of mono-energetic single photons, a correction factor
1137 :math:`f` as function of reconstructed detector position, reconstructed photon energy and beam backgrounds
1138 is determined via :math:`f = \frac{\text{peak_reconstructed}}{\text{energy_true}}`.
1140 - Cluster energy calibration (data only): To reach the target precision of :math:`< 1.8\%` energy
1141 resolution for high energetic photons, the remaining difference between MC and data must be calibrated
1142 using kinematically fit muon pairs. This calibration is only applied to data and not to MC and will
1143 take time to develop.
1145 It is important to note that after perfect leakage correction and cluster energy calibration,
1146 the :math:`\pi^{0}` mass peak will be shifted slightly to smaller values than the PDG average
1147 due to the low energy tails of photons. The :math:`\pi^{0}` mass peak must not be corrected
1148 to the PDG value by adjusting the reconstructed photon energies. Selection criteria based on
1149 the mass for :math:`\pi^{0}` candidates must be based on the biased value. Most analysis
1150 will used mass constrained :math:`\pi^{0}` s anyhow.
1153 We only store clusters with :math:`E > 20\,` MeV.
1156 | Please read `this <importantNoteECL>` first.
1157 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1158 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1159 | Precision: :math:`18` bit
1160 | This value can be changed to a different reference frame with :b2:var:`useCMSFrame`.
1162 REGISTER_VARIABLE("clusterErrorE", eclClusterErrorE, R
"DOC(
1163 Returns ECL cluster's uncertainty on energy
1164 (from background level and energy dependent tabulation).
1166 REGISTER_VARIABLE("clusterErrorPhi", eclClusterErrorPhi, R
"DOC(
1167 Returns ECL cluster's uncertainty on :math:`\phi`
1168 (from background level and energy dependent tabulation).
1170 REGISTER_VARIABLE("clusterErrorTheta", eclClusterErrorTheta, R
"DOC(
1171 Returns ECL cluster's uncertainty on :math:`\theta`
1172 (from background level and energy dependent tabulation).
1175 REGISTER_VARIABLE("clusterR", eclClusterR, R
"DOC(
1176 Returns ECL cluster's centroid distance from :math:`(0,0,0)`.
1178 REGISTER_VARIABLE("clusterPhi", eclClusterPhi, R
"DOC(
1179 Returns ECL cluster's azimuthal angle :math:`\phi`
1180 (this is not generally equal to a photon azimuthal angle).
1182 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1183 cluster centroid position in the ECL.
1184 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1185 after cluster energy splitting in the case of overlapping clusters.
1186 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1187 the crystal centers. Cluster centroids are generally biased towards the centers of the
1188 highest energetic crystal. This effect is larger for low energetic photons.
1189 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1192 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1194 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1195 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1196 as function of true photon energy, true photon direction and beam background level.
1199 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1200 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1201 from :math:`(0,0,0)`) for particle kinematics.
1204 | Please read `this <importantNoteECL>` first.
1205 | Lower limit: :math:`-\pi`
1206 | Upper limit: :math:`\pi`
1207 | Precision: :math:`16` bit
1209 REGISTER_VARIABLE("clusterConnectedRegionID", eclClusterConnectedRegionID, R
"DOC(
1210 Returns ECL cluster's connected region ID.
1212 REGISTER_VARIABLE("clusterTheta", eclClusterTheta, R
"DOC(
1213 Returns ECL cluster's polar angle :math:`\theta`
1214 (this is not generally equal to a photon polar angle).
1216 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1217 cluster centroid position in the ECL.
1218 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1219 after cluster energy splitting in the case of overlapping clusters.
1220 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1221 the crystal centers. Cluster centroids are generally biased towards the centers of the
1222 highest energetic crystal. This effect is larger for low energetic photons.
1223 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1226 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1228 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1229 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1230 as function of true photon energy, true photon direction and beam background level.
1233 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1234 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1235 from :math:`(0,0,0)`) for particle kinematics.
1238 | Please read `this <importantNoteECL>` first.
1239 | Lower limit: :math:`0.0`
1240 | Upper limit: :math:`\pi`
1241 | Precision: :math:`16` bit
1243 REGISTER_VARIABLE("clusterTiming", eclClusterTiming, R
"DOC(
1244 Returns the time of the ECL cluster. It is calculated as the Photon timing minus the Event t0.
1245 Photon timing is given by the fitted time of the recorded waveform of the highest energy crystal in the
1246 cluster. After all calibrations and corrections (including Time-Of-Flight), photons from the interaction
1247 point (IP) should have a Photon timing that corresponds to the Event t0, :math:`t_{0}`. The Event t0 is the
1248 time of the event and may be measured by a different sub-detector (see Event t0 documentation). For an ECL
1249 cluster produced at the interation point in time with the event, the cluster time should be consistent with zero
1250 within the uncertainties. Special values are returned if the fit for the Photon timing fails (see
1251 documentation for `clusterHasFailedTiming`). (For MC, the calibrations and corrections are not fully simulated).
1254 | Please read `this <importantNoteECL>` first.
1255 | Lower limit: :math:`-1000.0`
1256 | Upper limit: :math:`1000.0`
1257 | Precision: :math:`12` bit
1259 REGISTER_VARIABLE("clusterHasFailedTiming", eclClusterHasFailedTiming, R
"DOC(
1260 Status bit for if the ECL cluster's timing fit failed. Photon timing is given by the fitted time
1261 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1262 this variable tells the user if that has happened.
1264 REGISTER_VARIABLE("clusterErrorTiming", eclClusterErrorTiming, R
"DOC(
1265 Returns ECL cluster's timing uncertainty that contains :math:`99\%` of true photons (dt99).
1267 The photon timing uncertainty is currently determined using MC. The resulting parametrization depends on
1268 the true energy deposition in the highest energetic crystal and the local beam background level in that crystal.
1269 The resulting timing distribution is non-Gaussian and for each photon the value dt99 is stored,
1270 where :math:`|\text{timing}| / \text{dt99} < 1` is designed to give a :math:`99\%`
1271 timing efficiency for true photons from the IP.
1272 The resulting efficiency is approximately flat in energy and independent of beam background levels.
1274 Very large values of dt99 are an indication of failed waveform fits in the ECL.
1275 We remove such clusters in most physics photon lists.
1278 | Please read `this <importantNoteECL>` first.
1279 | Lower limit: :math:`0.0`
1280 | Upper limit: :math:`1000.0`
1281 | Precision: :math:`12` bit
1284 In real data there will be a sizeable number of high energetic Bhabha events
1285 (from previous or later bunch collisions) that can easily be rejected by timing cuts.
1286 However, these events create large ECL clusters that can overlap with other ECL clusters
1287 and it is not clear that a simple rejection is the correction strategy.
1289 REGISTER_VARIABLE("clusterHasFailedErrorTiming", eclClusterHasFailedErrorTiming, R
"DOC(
1290 Status bit for if the ECL cluster's timing uncertainty calculation failed. Photon timing is given by the fitted time
1291 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1292 this variable tells the user if that has happened.
1294 REGISTER_VARIABLE("clusterHighestE", eclClusterHighestE, R
"DOC(
1295 Returns energy of the highest energetic crystal in the ECL cluster after reweighting.
1298 This variable must be used carefully since it can bias shower selection
1299 towards photons that hit crystals in the center and hence have a large energy
1300 deposition in the highest energy crystal.
1303 | Please read `this <importantNoteECL>` first.
1304 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1305 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1306 | Precision: :math:`18` bit
1308 REGISTER_VARIABLE("clusterCellID", eclClusterCellId,
1309 "Returns cellId of the crystal with highest energy in the ECLCluster.");
1310 REGISTER_VARIABLE(
"clusterE1E9", eclClusterE1E9, R
"DOC(
1311 Returns ratio of energies of the central crystal, E1, and 3x3 crystals, E9, around the central crystal.
1312 Since :math:`E1 \leq E9`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1313 and smaller values for hadrons.
1316 | Please read `this <importantNoteECL>` first.
1317 | Lower limit: :math:`0.0`
1318 | Upper limit: :math:`1.0`
1319 | Precision: :math:`10` bit
1321 REGISTER_VARIABLE("clusterE9E25", eclClusterE9E25, R
"DOC(
1322 Deprecated - kept for backwards compatibility - returns clusterE9E21.
1324 REGISTER_VARIABLE("clusterE9E21", eclClusterE9E21, R
"DOC(
1325 Returns ratio of energies in inner 3x3 crystals, E9, and 5x5 crystals around the central crystal without corners.
1326 Since :math:`E9 \leq E21`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1327 and smaller values for hadrons.
1330 | Please read `this <importantNoteECL>` first.
1331 | Lower limit: :math:`0.0`
1332 | Upper limit: :math:`1.0`
1333 | Precision: :math:`10` bit
1335 REGISTER_VARIABLE("clusterAbsZernikeMoment40", eclClusterAbsZernikeMoment40, R
"DOC(
1336 Returns absolute value of Zernike moment 40 (:math:`|Z_{40}|`). (shower shape variable).
1339 | Please read `this <importantNoteECL>` first.
1340 | Lower limit: :math:`0.0`
1341 | Upper limit: :math:`1.7`
1342 | Precision: :math:`10` bit
1344 REGISTER_VARIABLE("clusterAbsZernikeMoment51", eclClusterAbsZernikeMoment51, R
"DOC(
1345 Returns absolute value of Zernike moment 51 (:math:`|Z_{51}|`). (shower shape variable).
1348 | Please read `this <importantNoteECL>` first.
1349 | Lower limit: :math:`0.0`
1350 | Upper limit: :math:`1.2`
1351 | Precision: :math:`10` bit
1353 REGISTER_VARIABLE("clusterZernikeMVA", eclClusterZernikeMVA, R
"DOC(
1354 Returns output of a MVA using eleven Zernike moments of the cluster. Zernike moments are calculated per
1355 shower in a plane perpendicular to the shower direction via
1358 |Z_{nm}| = \frac{n+1}{\pi} \frac{1}{\sum_{i} w_{i} E_{i}} \left|\sum_{i} R_{nm}(\rho_{i}) e^{-im\alpha_{i}} w_{i} E_{i} \right|
1360 where n, m are the integers, :math:`i` runs over the crystals in the shower,
1361 :math:`E_{i}` is the energy of the i-th crystal in the shower,
1362 :math:`R_{nm}` is a polynomial of degree :math:`n`,
1363 :math:`\rho_{i}` is the radial distance of the :math:`i`-th crystal in the perpendicular plane,
1364 and :math:`\alpha_{i}` is the polar angle of the :math:`i`-th crystal in the perpendicular plane.
1365 As a crystal can be related to more than one shower, :math:`w_{i}` is the fraction of the
1366 energy of the :math:`i`-th crystal associated with the shower.
1368 More details about the implementation can be found in `BELLE2-NOTE-TE-2017-001 <https://docs.belle2.org/record/454?ln=en>`_ .
1370 More details about Zernike polynomials can be found in `Wikipedia <https://en.wikipedia.org/wiki/Zernike_polynomials>`_ .
1372 | For cluster with hypothesisId==N1: raw MVA output.
1373 | For cluster with hypothesisId==N2: 1 - prod{clusterZernikeMVA}, where the product is on all N1 showers
1374 belonging to the same connected region (shower shape variable).
1377 | Please read `this <importantNoteECL>` first.
1378 | Lower limit: :math:`0.0`
1379 | Upper limit: :math:`1.0`
1380 | Precision: :math:`10` bit
1382 REGISTER_VARIABLE("clusterSecondMoment", eclClusterSecondMoment, R
"DOC(
1383 Returns second moment :math:`S`. It is defined as:
1386 S = \frac{\sum_{i=0}^{n} w_{i} E_{i} r^2_{i}}{\sum_{i=0}^{n} w_{i} E_{i}}
1388 where :math:`E_{i} = (E_0, E_1, ...)` are the single crystal energies sorted by energy, :math:`w_{i}` is
1389 the crystal weight, and :math:`r_{i}` is the distance of the :math:`i`-th digit to the shower center projected
1390 to a plane perpendicular to the shower axis.
1393 | Please read `this <importantNoteECL>` first.
1394 | Lower limit: :math:`0.0`
1395 | Upper limit: :math:`40.0`
1396 | Precision: :math:`10` bit
1398 REGISTER_VARIABLE("clusterLAT", eclClusterLAT, R
"DOC(
1399 Returns lateral energy distribution (shower variable). It is defined as following:
1402 S = \frac{\sum_{i=2}^{n} w_{i} E_{i} r^2_{i}}{(w_{0} E_{0} + w_{1} E_{1}) r^2_{0} + \sum_{i=2}^{n} w_{i} E_{i} r^2_{i}}
1404 where :math:`E_{i} = (E_{0}, E_{1}, ...)` are the single crystal energies sorted by energy
1405 (:math:`E_{0}` is the highest energy and :math:`E_{1}` the second highest), :math:`w_{i}`
1406 is the crystal weight, :math:`r_{i}` is the distance of the :math:`i`-th digit to the
1407 shower center projected to a plane perpendicular to the shower axis,
1408 and :math:`r_{0} \approx 5\,cm` is the distance between two crystals.
1410 clusterLAT peaks around 0.3 for radially symmetrical electromagnetic showers and is larger
1411 for hadronic events, and electrons with a close-by radiative or Bremsstrahlung photon.
1414 | Please read `this <importantNoteECL>` first.
1415 | Lower limit: :math:`0.0`
1416 | Upper limit: :math:`1.0`
1417 | Precision: :math:`10` bit
1419 REGISTER_VARIABLE("clusterNHits", eclClusterNHits, R
"DOC(
1420 Returns sum of weights :math:`w_{i}` (:math:`w_{i} \leq 1`) of all crystals in an ECL cluster.
1421 For non-overlapping clusters this is equal to the number of crystals in the cluster.
1422 In case of energy splitting among nearby clusters, this can be a non-integer value.
1425 | Please read `this <importantNoteECL>` first.
1426 | Lower limit: :math:`0.0`
1427 | Upper limit: :math:`200.0`
1428 | Precision: :math:`10` bit
1429 | If fractional weights are not of interest, this value should be cast to the nearest integer.
1431 REGISTER_VARIABLE("clusterTrackMatch", eclClusterTrackMatched, R
"DOC(
1432 Returns 1.0 if at least one reconstructed charged track is matched to the ECL cluster.
1434 Every reconstructed charged track is extrapolated into the ECL.
1435 Every ECL crystal that is crossed by the track extrapolation is marked.
1436 Each ECL cluster that contains any marked crystal is matched to the track.
1437 Multiple tracks can be matched to one cluster and multiple clusters can be matched to one track.
1438 It is conceptually correct to have two tracks matched to the same cluster.
1440 REGISTER_VARIABLE("nECLClusterTrackMatches", nECLClusterTrackMatches, R
"DOC(
1441 Returns number of charged tracks matched to this cluster.
1444 Sometimes (perfectly correctly) two tracks are extrapolated into the same cluster.
1446 - For charged particles, this should return at least 1 (but sometimes 2 or more).
1447 - For neutrals, this should always return 0.
1448 - Returns NaN if there is no cluster.
1450 REGISTER_VARIABLE("clusterHasPulseShapeDiscrimination", eclClusterHasPulseShapeDiscrimination, R
"DOC(
1451 Status bit to indicate if cluster has digits with waveforms that passed energy and :math:`\chi^2`
1452 thresholds for computing PSD variables.
1454 REGISTER_VARIABLE("clusterPulseShapeDiscriminationMVA", eclPulseShapeDiscriminationMVA, R
"DOC(
1455 Returns MVA classifier that uses pulse shape discrimination to identify electromagnetic vs hadronic showers.
1457 - 1 for electromagnetic showers
1458 - 0 for hadronic showers
1460 REGISTER_VARIABLE("clusterNumberOfHadronDigits", eclClusterNumberOfHadronDigits, R
"DOC(
1461 Returns ECL cluster's number of hadron digits in cluster (pulse shape discrimination variable).
1462 Weighted sum of digits in cluster with significant scintillation emission (:math:`> 3\,` MeV)
1463 in the hadronic scintillation component.
1464 Computed only using cluster digits with energy :math:`> 50\,` MeV and good offline waveform fit :math:`\chi^2`.
1467 | Please read `this <importantNoteECL>` first.
1468 | Lower limit: :math:`0.0`
1469 | Upper limit: :math:`255.0`
1470 | Precision: :math:`18` bit
1472 REGISTER_VARIABLE("clusterClusterID", eclClusterId, R
"DOC(
1473 Returns ECL cluster ID of this ECL cluster within the connected region (CR) to which it belongs to.
1475 REGISTER_VARIABLE("clusterHasNPhotons", eclClusterHasNPhotonsHypothesis, R
"DOC(
1476 Returns 1.0 if cluster has the 'N photons' hypothesis (historically called 'N1'),
1477 0.0 if not, and NaN if no cluster is associated to the particle.
1479 REGISTER_VARIABLE("clusterHasNeutralHadron", eclClusterHasNeutralHadronHypothesis, R
"DOC(
1480 Returns 1.0 if the cluster has the 'neutral hadrons' hypothesis (historically called 'N2'),
1481 0.0 if not, and NaN if no cluster is associated to the particle.
1483 REGISTER_VARIABLE("eclExtTheta", eclExtTheta, R
"DOC(
1484 Returns extrapolated :math:`\theta`.
1486 REGISTER_VARIABLE("eclExtPhi", eclExtPhi, R
"DOC(
1487 Returns extrapolated :math:`\phi`.
1489 REGISTER_VARIABLE("eclExtPhiId", eclExtPhiId, R
"DOC(
1490 Returns extrapolated :math:`\phi` ID.
1492 REGISTER_VARIABLE("weightedAverageECLTime", weightedAverageECLTime, R
"DOC(
1493 Returns ECL weighted average time of all clusters (neutrals) and matched clusters (charged) of daughters
1494 (of any generation) of the provided particle.
1496 REGISTER_VARIABLE("maxWeightedDistanceFromAverageECLTime", maxWeightedDistanceFromAverageECLTime, R
"DOC(
1497 Returns maximum weighted distance between time of the cluster of a photon and the ECL average time, amongst
1498 the clusters (neutrals) and matched clusters (charged) of daughters (of all generations) of the provided particle.
1500 REGISTER_VARIABLE("clusterMdstIndex", eclClusterMdstIndex, R
"DOC(
1501 StoreArray index(0 - based) of the MDST ECLCluster (useful for track-based particles matched to a cluster).
1504 REGISTER_VARIABLE("nECLOutOfTimeCrystals", nECLOutOfTimeCrystals, R
"DOC(
1505 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time.
1508 REGISTER_VARIABLE("nECLOutOfTimeCrystalsFWDEndcap", nECLOutOfTimeCrystalsFWDEndcap, R
"DOC(
1509 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the forward endcap.
1512 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBarrel", nECLOutOfTimeCrystalsBarrel, R
"DOC(
1513 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the barrel.
1516 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBWDEndcap", nECLOutOfTimeCrystalsBWDEndcap, R
"DOC(
1517 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the backward endcap.
1520 REGISTER_VARIABLE("nRejectedECLShowers", nRejectedECLShowers, R
"DOC(
1521 [Eventbased] Returns the number of showers in the ECL that do not become clusters.
1524 REGISTER_VARIABLE("nRejectedECLShowersFWDEndcap", nRejectedECLShowersFWDEndcap, R
"DOC(
1525 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the forward endcap.
1528 REGISTER_VARIABLE("nRejectedECLShowersBarrel", nRejectedECLShowersBarrel, R
"DOC(
1529 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the barrel.
1532 REGISTER_VARIABLE("nRejectedECLShowersBWDEndcap", nRejectedECLShowersBWDEndcap, R
"DOC(
1533 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the backward endcap.
1536 REGISTER_VARIABLE("eclClusterOnlyInvariantMass", eclClusterOnlyInvariantMass, R
"DOC(
1537 [Expert] The invariant mass calculated from all ECLCluster daughters (i.e. photons) and
1538 cluster-matched tracks using the cluster 4-momenta.
1540 Used for ECL-based dark sector physics and debugging track-cluster matching.
1545 VARIABLE_GROUP(
"ECL calibration");
1547 REGISTER_VARIABLE(
"clusterUncorrE", eclClusterUncorrectedE, R
"DOC(
1548 [Expert] [Calibration] Returns ECL cluster's uncorrected energy. That is, before leakage corrections.
1549 This variable should only be used for study of the ECL. Please see :b2:var:`clusterE`.
1552 REGISTER_VARIABLE("eclEnergy3FWDBarrel", eclEnergy3FWDBarrel, R
"DOC(
1553 [Calibration] Returns energy sum of three crystals in forward barrel.
1556 REGISTER_VARIABLE("eclEnergy3FWDEndcap", eclEnergy3FWDEndcap, R
"DOC(
1557 [Calibration] Returns energy sum of three crystals in forward endcap.
1560 REGISTER_VARIABLE("eclEnergy3BWDBarrel", eclEnergy3BWDBarrel, R
"DOC(
1561 [Calibration] Returns energy sum of three crystals in backward barrel.
1564 REGISTER_VARIABLE("eclEnergy3BWDEndcap", eclEnergy3BWDEndcap, R
"DOC(
1565 [Calibration] Returns energy sum of three crystals in backward endcap.
1569 VARIABLE_GROUP(
"ECL trigger calibration");
1570 REGISTER_VARIABLE(
"clusterNumberOfTCs(i, j, k, l)", eclNumberOfTCsForCluster, R
"DOC(
1571 [Calibration] Returns the number of TCs for this ECL cluster for a given TC theta ID range
1572 :math:`(i, j)` and hit window :math:`(k, l)`.
1574 REGISTER_VARIABLE("clusterTCFADC(i, j, k, l)", eclTCFADCForCluster, R
"DOC(
1575 [Calibration] Returns the total FADC sum related to this ECL cluster for a given TC theta ID
1576 range :math:`(i, j)` and hit window :math:`(k, l)`.
1578 REGISTER_VARIABLE("clusterTCIsMaximum", eclTCIsMaximumForCluster, R
"DOC(
1579 [Calibration] Returns True if cluster is related to maximum TC.
1581 REGISTER_VARIABLE("clusterTrigger", eclClusterTrigger, R
"DOC(
1582 [Calibration] Returns 1.0 if ECL cluster is matched to a trigger cluster (requires to run eclTriggerClusterMatcher
1583 (which requires TRGECLClusters in the input file)) and 0 otherwise. Returns -1 if the matching code was not run.
1584 NOT FOR PHASE2 DATA!
1586 REGISTER_VARIABLE("eclEnergyTC(i)", getEnergyTC, R
"DOC(
1587 [Eventbased][Calibration] Returns the energy (in FADC counts) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1589 REGISTER_VARIABLE("eclEnergyTCECLCalDigit(i)", getEnergyTCECLCalDigit, R
"DOC(
1590 [Eventbased][Calibration] Returns the energy (in GeV) for the :math:`i`-th trigger cell (TC)
1591 based on ECLCalDigits, 1 based (1..576).
1593 REGISTER_VARIABLE("eclTimingTC(i)", getTimingTC, R
"DOC(
1594 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1596 REGISTER_VARIABLE("eclHitWindowTC(i)", eclHitWindowTC, R
"DOC(
1597 [Eventbased][Calibration] Returns the hit window for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1599 REGISTER_VARIABLE("eclEventTimingTC", getEvtTimingTC, R
"DOC(
1600 [Eventbased][Calibration] Returns the ECL TC event time (in ns).
1602 REGISTER_VARIABLE("eclMaximumTCId", getMaximumTCId, R
"DOC(
1603 [Eventbased][Calibration] Returns the TC ID with maximum FADC value.
1607 REGISTER_VARIABLE("eclTimingTCECLCalDigit(i)", getTimingTCECLCalDigit, R
"DOC(
1608 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC) based
1609 on ECLCalDigits, 1 based (1..576)
1612 REGISTER_VARIABLE("eclNumberOfTCs(i, j, k)", getNumberOfTCs, R
"DOC(
1613 [Eventbased][Calibration] Returns the number of TCs above threshold (i=FADC counts) for this event
1614 for a given theta range (j-k)
1616 REGISTER_VARIABLE("eclEnergySumTC(i, j)", eclEnergySumTC, R
"DOC(
1617 [Eventbased][Calibration] Returns energy sum (in FADC counts) of all TC cells between two
1618 theta ids i<=thetaid<=j, 1 based (1..17)
1620 REGISTER_VARIABLE("eclEnergySumTCECLCalDigit(i, j, k, l)", eclEnergySumTCECLCalDigit, R
"DOC(
1621 [Eventbased][Calibration] Returns energy sum (in GeV) of all TC cells between two theta ids i<=thetaid<=j,
1622 1 based (1..17). k is the sum option: 0 (all), 1 (those with actual TC entries), 2 (sum of ECLCalDigit energy
1623 in this TC above threshold). l is the threshold parameter for the option k 2.
1625 REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLCluster", eclEnergySumTCECLCalDigitInECLCluster, R
"DOC(
1626 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits if TC is above threshold
1627 that are part of an ECLCluster above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
1629 REGISTER_VARIABLE("eclEnergySumECLCalDigitInECLCluster", eclEnergySumECLCalDigitInECLCluster, R
"DOC(
1630 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits that are part of an ECL cluster
1631 above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
1633 REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLClusterThreshold", eclEnergySumTCECLCalDigitInECLClusterThreshold, R
"DOC(
1634 [Eventbased][Calibration] Returns threshold used to calculate eclEnergySumTCECLCalDigitInECLCluster.