10 #include <analysis/variables/ECLVariables.h>
13 #include <framework/logging/Logger.h>
16 #include <analysis/dataobjects/Particle.h>
17 #include <analysis/dataobjects/ParticleList.h>
18 #include <analysis/dataobjects/ECLEnergyCloseToTrack.h>
19 #include <analysis/utility/ReferenceFrame.h>
20 #include <analysis/ClusterUtility/ClusterUtils.h>
21 #include <analysis/VariableManager/Utility.h>
24 #include <mdst/dataobjects/KlId.h>
25 #include <mdst/dataobjects/ECLCluster.h>
26 #include <mdst/dataobjects/Track.h>
27 #include <mdst/dataobjects/EventLevelClusteringInfo.h>
29 #include <Math/Vector4D.h>
42 double distanceToMcKl(
const Particle* particle)
44 if (particle->hasExtraInfo(
"mcdistanceKL")) {
45 return particle->getExtraInfo(
"mcdistanceKL");
47 B2WARNING(
"The extraInfo mcdistanceKL is not registered! \n"
48 "This variable is only available for ECL based lists, and you have to run the function getNeutralHadronGeomMatches to use it");
53 double distanceToMcNeutron(
const Particle* particle)
55 if (particle->hasExtraInfo(
"mcdistanceNeutron")) {
56 return particle->getExtraInfo(
"mcdistanceNeutron");
58 B2WARNING(
"The extraInfo mcdistanceNeutron is not registered! \n"
59 "This variable is only available for ECL based lists, and you have to run the function getNeutralHadronGeomMatches to use it");
64 int mdstIndexMcKl(
const Particle* particle)
66 if (particle->hasExtraInfo(
"mdstIndexTruthKL")) {
67 return int(particle->getExtraInfo(
"mdstIndexTruthKL") + 0.1);
69 B2WARNING(
"The extraInfo mdstIndexTruthKL is not registered! \n"
70 "This variable is only available for ECL based lists, and you have to run the function getNeutralHadronGeomMatches to use it");
75 int mdstIndexMcNeutron(
const Particle* particle)
77 if (particle->hasExtraInfo(
"mdstIndexTruthNeutron")) {
78 return int(particle->getExtraInfo(
"mdstIndexTruthNeutron") + 0.1);
80 B2WARNING(
"The extraInfo mdstIndexTruthNeutron is not registered! \n"
81 "This variable is only available for ECL based lists, and you have to run the function getNeutralHadronGeomMatches to use it");
87 double beamBackgroundSuppression(
const Particle* particle)
89 if (particle->hasExtraInfo(
"beamBackgroundSuppression")) {
90 return particle->getExtraInfo(
"beamBackgroundSuppression");
92 B2WARNING(
"The extraInfo beamBackgroundSuppression is not registered! \n"
93 "This variable is only available for photons, and you either have to run the function getBeamBackgroundProbability or turn the argument loadPhotonBeamBackgroundMVA to True when using fillParticleList.");
98 double fakePhotonSuppression(
const Particle* particle)
100 if (particle->hasExtraInfo(
"fakePhotonSuppression")) {
101 return particle->getExtraInfo(
"fakePhotonSuppression");
103 B2WARNING(
"The extraInfo fakePhotonSuppression is not registered! \n"
104 "This variable is only available for photons, and you either have to run the function getFakePhotonProbability or turn the argument loadFakePhotonMVA to True when using fillParticleList.");
109 double hadronicSplitOffSuppression(
const Particle* particle)
111 B2WARNING(
"This variable has been deprecated since light-2302-genetta and is no longer maintained with up to date weights. Please use the variable fakePhotonSuppression instead.");
112 return fakePhotonSuppression(particle);
115 double eclClusterKlId(
const Particle* particle)
117 const ECLCluster* cluster = particle->getECLCluster();
121 const KlId* klid = cluster->getRelatedTo<KlId>();
125 return klid->getKlId();
129 double eclPulseShapeDiscriminationMVA(
const Particle* particle)
131 const ECLCluster* cluster = particle->getECLCluster();
133 if (eclClusterHasPulseShapeDiscrimination(particle)) {
134 return cluster->getPulseShapeDiscriminationMVA();
142 double eclClusterNumberOfHadronDigits(
const Particle* particle)
145 const ECLCluster* cluster = particle->getECLCluster();
147 if (eclClusterHasPulseShapeDiscrimination(particle)) {
148 return cluster->getNumberOfHadronDigits();
155 double eclClusterDetectionRegion(
const Particle* particle)
158 const ECLCluster* cluster = particle->getECLCluster();
160 return cluster->getDetectorRegion();
165 double eclClusterIsolation(
const Particle* particle)
168 const ECLCluster* cluster = particle->getECLCluster();
170 auto minDist = cluster->getMinTrkDistance();
177 double eclClusterIsolationID(
const Particle* particle)
180 const ECLCluster* cluster = particle->getECLCluster();
182 return cluster->getMinTrkDistanceID();
189 if (arguments.size() > 2 or arguments.size() == 0)
190 B2FATAL(
"Wrong number of arguments (2 required) for meta variable minC2TDistVar");
191 std::string listName =
"pi-:all";
192 std::string variableName = arguments[0];
193 if (arguments.size() == 2)
194 listName = arguments[1];
197 auto func = [listName, variableName](
const Particle * particle) ->
double {
198 StoreObjPtr<ParticleList> particleList(listName);
199 if (!(particleList.isValid()))
201 B2FATAL(
"Invalid Listname " << listName <<
" given to minC2TDistVar!");
204 const ECLCluster* cluster = particle->getECLCluster();
207 auto trackID = cluster->getMinTrkDistanceID();
210 for (
unsigned int i = 0; i < particleList->getListSize(); i++)
212 const Particle* listParticle = particleList->getParticle(i);
213 if (listParticle and listParticle->getTrack() and listParticle->getTrack()->getArrayIndex() == trackID) {
214 result = std::get<double>(var->function(listParticle));
223 double eclClusterConnectedRegionID(
const Particle* particle)
226 const ECLCluster* cluster = particle->getECLCluster();
228 return cluster->getConnectedRegionId();
233 double eclClusterDeltaL(
const Particle* particle)
236 const ECLCluster* cluster = particle->getECLCluster();
238 return cluster->getDeltaL();
243 double eclClusterErrorE(
const Particle* particle)
246 const ECLCluster* cluster = particle->getECLCluster();
248 return cluster->getUncertaintyEnergy();
253 double eclClusterUncorrectedE(
const Particle* particle)
256 const ECLCluster* cluster = particle->getECLCluster();
258 return cluster->getEnergyRaw();
263 double eclClusterE(
const Particle* particle)
267 const ECLCluster* cluster = particle->getECLCluster();
270 ROOT::Math::PxPyPzEVector p4Cluster = clutls.GetCluster4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
272 return frame.getMomentum(p4Cluster).E();
277 double eclClusterHighestE(
const Particle* particle)
280 const ECLCluster* cluster = particle->getECLCluster();
282 return cluster->getEnergyHighestCrystal();
287 double eclClusterCellId(
const Particle* particle)
290 const ECLCluster* cluster = particle->getECLCluster();
292 return cluster->getMaxECellId();
298 const std::array<int, 69> lastCellIDperThetaID{48, 96, 160, 224, 288, 384, 480, 576, 672, 768, 864,
299 1008, 1152, 1296, 1440, 1584, 1728, 1872, 2016, 2160, 2304, 2448,
300 2592, 2736, 2880, 3024, 3168, 3312, 3456, 3600, 3744, 3888, 4032,
301 4176, 4320, 4464, 4608, 4752, 4896, 5040, 5184, 5328, 5472, 5616,
302 5760, 5904, 6048, 6192, 6336, 6480, 6624, 6768, 6912, 7056, 7200,
303 7344, 7488, 7632, 7776, 7920, 8064, 8160, 8256, 8352, 8448, 8544,
306 double eclClusterThetaId(
const Particle* particle)
309 const ECLCluster* cluster = particle->getECLCluster();
311 int cellID = cluster->getMaxECellId();
312 return std::distance(lastCellIDperThetaID.begin(), std::lower_bound(lastCellIDperThetaID.begin(), lastCellIDperThetaID.end(),
318 double eclClusterPhiId(
const Particle* particle)
321 const ECLCluster* cluster = particle->getECLCluster();
323 int cellID = cluster->getMaxECellId();
327 int closestinlist = lastCellIDperThetaID[std::distance(lastCellIDperThetaID.begin(), std::lower_bound(lastCellIDperThetaID.begin(),
328 lastCellIDperThetaID.end(), cellID)) - 1];
329 return cellID - closestinlist - 1;
335 double eclClusterTiming(
const Particle* particle)
338 const ECLCluster* cluster = particle->getECLCluster();
340 return cluster->getTime();
345 double eclClusterHasFailedTiming(
const Particle* particle)
347 const ECLCluster* cluster = particle->getECLCluster();
349 return cluster->hasFailedFitTime();
354 double eclClusterErrorTiming(
const Particle* particle)
357 const ECLCluster* cluster = particle->getECLCluster();
359 return cluster->getDeltaTime99();
364 double eclClusterHasFailedErrorTiming(
const Particle* particle)
366 const ECLCluster* cluster = particle->getECLCluster();
368 return cluster->hasFailedTimeResolution();
373 double eclClusterTheta(
const Particle* particle)
377 const ECLCluster* cluster = particle->getECLCluster();
380 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
382 return frame.getMomentum(p4Cluster).Theta();
387 double eclClusterErrorTheta(
const Particle* particle)
390 const ECLCluster* cluster = particle->getECLCluster();
392 return cluster->getUncertaintyTheta();
397 double eclClusterErrorPhi(
const Particle* particle)
400 const ECLCluster* cluster = particle->getECLCluster();
402 return cluster->getUncertaintyPhi();
407 double eclClusterPhi(
const Particle* particle)
411 const ECLCluster* cluster = particle->getECLCluster();
414 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
416 return frame.getMomentum(p4Cluster).Phi();
421 double eclClusterR(
const Particle* particle)
424 const ECLCluster* cluster = particle->getECLCluster();
426 return cluster->getR();
431 double eclClusterE1E9(
const Particle* particle)
434 const ECLCluster* cluster = particle->getECLCluster();
436 return cluster->getE1oE9();
441 double eclClusterE9E21(
const Particle* particle)
444 const ECLCluster* cluster = particle->getECLCluster();
446 return cluster->getE9oE21();
451 double eclClusterAbsZernikeMoment40(
const Particle* particle)
454 const ECLCluster* cluster = particle->getECLCluster();
456 return cluster->getAbsZernike40();
461 double eclClusterAbsZernikeMoment51(
const Particle* particle)
464 const ECLCluster* cluster = particle->getECLCluster();
466 return cluster->getAbsZernike51();
471 double eclClusterZernikeMVA(
const Particle* particle)
474 const ECLCluster* cluster = particle->getECLCluster();
476 return cluster->getZernikeMVA();
481 double eclClusterSecondMoment(
const Particle* particle)
484 const ECLCluster* cluster = particle->getECLCluster();
486 return cluster->getSecondMoment();
491 double eclClusterLAT(
const Particle* particle)
494 const ECLCluster* cluster = particle->getECLCluster();
496 return cluster->getLAT();
501 double eclClusterNHits(
const Particle* particle)
504 const ECLCluster* cluster = particle->getECLCluster();
506 return cluster->getNumberOfCrystals();
511 double eclClusterTrackMatched(
const Particle* particle)
514 const ECLCluster* cluster = particle->getECLCluster();
516 const Track* track = cluster->getRelatedFrom<Track>();
526 double nECLClusterTrackMatches(
const Particle* particle)
529 const ECLCluster* cluster = particle->getECLCluster();
534 size_t out = cluster->getRelationsFrom<Track>().size();
538 double eclClusterConnectedRegionId(
const Particle* particle)
540 const ECLCluster* cluster = particle->getECLCluster();
542 return cluster->getConnectedRegionId();
547 double eclClusterId(
const Particle* particle)
549 const ECLCluster* cluster = particle->getECLCluster();
551 return cluster->getClusterId();
556 double eclClusterHasNPhotonsHypothesis(
const Particle* particle)
558 const ECLCluster* cluster = particle->getECLCluster();
565 double eclClusterHasNeutralHadronHypothesis(
const Particle* particle)
567 const ECLCluster* cluster = particle->getECLCluster();
574 double eclClusterHasPulseShapeDiscrimination(
const Particle* particle)
576 const ECLCluster* cluster = particle->getECLCluster();
578 return cluster->hasPulseShapeDiscrimination();
583 double eclExtTheta(
const Particle* particle)
586 const Track* track = particle->getTrack();
589 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
592 return eclinfo->getExtTheta();
594 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
602 double eclExtPhi(
const Particle* particle)
605 const Track* track = particle->getTrack();
608 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
611 return eclinfo->getExtPhi();
613 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
621 double eclExtPhiId(
const Particle* particle)
623 const Track* track = particle->getTrack();
626 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
629 return eclinfo->getExtPhiId();
631 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
639 double weightedAverageECLTime(
const Particle* particle)
641 int nDaughters = particle->getNDaughters();
642 if (nDaughters < 1) {
643 B2WARNING(
"The provided particle has no daughters!");
647 double numer = 0, denom = 0;
648 int numberOfClusterDaughters = 0;
650 auto weightedECLTimeAverage = [&numer, &denom, &numberOfClusterDaughters](
const Particle * p) {
651 const ECLCluster* cluster = p->getECLCluster();
652 if (cluster and not cluster->hasFailedFitTime()) {
653 numberOfClusterDaughters ++;
655 double time = cluster->getTime();
656 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
657 double deltatime = cluster->getDeltaTime99();
658 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
659 numer += time / pow(deltatime, 2);
660 B2DEBUG(11,
"numer[" << numberOfClusterDaughters <<
"] = " << numer);
661 denom += 1 / pow(deltatime, 2);
662 B2DEBUG(11,
"denom[" << numberOfClusterDaughters <<
"] = " << denom);
667 particle->forEachDaughter(weightedECLTimeAverage,
true,
true);
669 if (numberOfClusterDaughters < 1) {
670 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
675 B2WARNING(
"The denominator of the weighted mean is zero!");
678 B2DEBUG(10,
"numer/denom = " << numer / denom);
679 return numer / denom;
683 double maxWeightedDistanceFromAverageECLTime(
const Particle* particle)
685 int nDaughters = particle->getNDaughters();
686 if (nDaughters < 1) {
687 B2WARNING(
"The provided particle has no daughters!");
691 double maxTimeDiff = -DBL_MAX;
692 int numberOfClusterDaughters = 0;
694 double averageECLTime = weightedAverageECLTime(particle);
696 auto maxTimeDifference = [&maxTimeDiff, &numberOfClusterDaughters, &averageECLTime](
const Particle * p) {
698 const ECLCluster* cluster = p->getECLCluster();
700 numberOfClusterDaughters ++;
702 double time = cluster->getTime();
703 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
704 double deltatime = cluster->getDeltaTime99();
705 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
706 double maxTimeDiff_temp = fabs((time - averageECLTime) / deltatime);
707 B2DEBUG(11,
"maxTimeDiff_temp[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff_temp);
708 if (maxTimeDiff_temp > maxTimeDiff)
709 maxTimeDiff = maxTimeDiff_temp;
710 B2DEBUG(11,
"maxTimeDiff[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff);
715 particle->forEachDaughter(maxTimeDifference,
true,
true);
717 if (numberOfClusterDaughters < 1) {
718 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
722 if (maxTimeDiff < 0) {
723 B2WARNING(
"The max time difference is negative!");
726 B2DEBUG(10,
"maxTimeDiff = " << maxTimeDiff);
731 double eclClusterMdstIndex(
const Particle* particle)
733 const ECLCluster* cluster = particle->getECLCluster();
735 return cluster->getArrayIndex();
745 double nECLOutOfTimeCrystalsFWDEndcap(
const Particle*)
747 StoreObjPtr<EventLevelClusteringInfo> elci;
749 return (
double)elci->getNECLCalDigitsOutOfTimeFWD();
752 double nECLOutOfTimeCrystalsBarrel(
const Particle*)
754 StoreObjPtr<EventLevelClusteringInfo> elci;
756 return (
double)elci->getNECLCalDigitsOutOfTimeBarrel();
759 double nECLOutOfTimeCrystalsBWDEndcap(
const Particle*)
761 StoreObjPtr<EventLevelClusteringInfo> elci;
763 return (
double)elci->getNECLCalDigitsOutOfTimeBWD();
766 double nECLOutOfTimeCrystals(
const Particle*)
768 StoreObjPtr<EventLevelClusteringInfo> elci;
770 return (
double)elci->getNECLCalDigitsOutOfTime();
773 double nRejectedECLShowersFWDEndcap(
const Particle*)
775 StoreObjPtr<EventLevelClusteringInfo> elci;
777 return (
double)elci->getNECLShowersRejectedFWD();
780 double nRejectedECLShowersBarrel(
const Particle*)
782 StoreObjPtr<EventLevelClusteringInfo> elci;
784 return (
double)elci->getNECLShowersRejectedBarrel();
787 double nRejectedECLShowersBWDEndcap(
const Particle*)
789 StoreObjPtr<EventLevelClusteringInfo> elci;
791 return (
double)elci->getNECLShowersRejectedBWD();
794 double nRejectedECLShowers(
const Particle*)
796 StoreObjPtr<EventLevelClusteringInfo> elci;
798 return (
double) elci->getNECLShowersRejected();
801 double nKLMMultistripHitsFWDEndcap(
const Particle*)
803 StoreObjPtr<EventLevelClusteringInfo> elci;
805 return (
double) elci->getNKLMDigitsMultiStripFWD();
808 double nKLMMultistripHitsBarrel(
const Particle*)
810 StoreObjPtr<EventLevelClusteringInfo> elci;
812 return (
double) elci->getNKLMDigitsMultiStripBarrel();
815 double nKLMMultistripHitsBWDEndcap(
const Particle*)
817 StoreObjPtr<EventLevelClusteringInfo> elci;
819 return (
double) elci->getNKLMDigitsMultiStripBWD();
822 double nKLMMultistripHits(
const Particle*)
824 StoreObjPtr<EventLevelClusteringInfo> elci;
826 return (
double) elci->getNKLMDigitsMultiStrip();
829 double nECLShowersFWDEndcap(
const Particle*)
831 StoreObjPtr<EventLevelClusteringInfo> elci;
833 return (
double) elci->getNECLShowersFWD();
836 double nECLShowersBarrel(
const Particle*)
838 StoreObjPtr<EventLevelClusteringInfo> elci;
840 return (
double) elci->getNECLShowersBarrel();
843 double nECLShowersBWDEndcap(
const Particle*)
845 StoreObjPtr<EventLevelClusteringInfo> elci;
847 return (
double) elci->getNECLShowersBWD();
850 double nECLShowers(
const Particle*)
852 StoreObjPtr<EventLevelClusteringInfo> elci;
854 return (
double) elci->getNECLShowers();
857 double nECLLocalMaximumsFWDEndcap(
const Particle*)
859 StoreObjPtr<EventLevelClusteringInfo> elci;
861 return (
double) elci->getNECLLocalMaximumsFWD();
864 double nECLLocalMaximumsBarrel(
const Particle*)
866 StoreObjPtr<EventLevelClusteringInfo> elci;
868 return (
double) elci->getNECLLocalMaximumsBarrel();
871 double nECLLocalMaximumsBWDEndcap(
const Particle*)
873 StoreObjPtr<EventLevelClusteringInfo> elci;
875 return (
double) elci->getNECLLocalMaximumsBWD();
878 double nECLLocalMaximums(
const Particle*)
880 StoreObjPtr<EventLevelClusteringInfo> elci;
882 return (
double) elci->getNECLLocalMaximums();
885 double nECLTriggerCellsFWDEndcap(
const Particle*)
887 StoreObjPtr<EventLevelClusteringInfo> elci;
889 return (
double) elci->getNECLTriggerCellsFWD();
892 double nECLTriggerCellsBarrel(
const Particle*)
894 StoreObjPtr<EventLevelClusteringInfo> elci;
896 return (
double) elci->getNECLTriggerCellsBarrel();
899 double nECLTriggerCellsBWDEndcap(
const Particle*)
901 StoreObjPtr<EventLevelClusteringInfo> elci;
903 return (
double) elci->getNECLTriggerCellsBWD();
906 double nECLTriggerCells(
const Particle*)
908 StoreObjPtr<EventLevelClusteringInfo> elci;
910 return (
double) elci->getNECLTriggerCells();
913 double eclClusterEoP(
const Particle* part)
915 double E = eclClusterE(part);
916 if (part->hasExtraInfo(
"bremsCorrectedPhotonEnergy")) {
917 E += part->getExtraInfo(
"bremsCorrectedPhotonEnergy");
919 const double p = part->getMomentumMagnitude();
924 double eclClusterOnlyInvariantMass(
const Particle* part)
926 int nDaughters = part->getNDaughters();
927 ROOT::Math::PxPyPzEVector sum;
929 if (nDaughters < 1) {
930 return part->getMass();
932 int nClusterDaughters = 0;
933 std::stack<const Particle*> stacked;
935 while (!stacked.empty()) {
936 const Particle* current = stacked.top();
939 const ECLCluster* cluster = current->getECLCluster();
942 nClusterDaughters ++;
944 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterBit);
947 const std::vector<Particle*> daughters = current->getDaughters();
948 nDaughters = current->getNDaughters();
949 for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
950 stacked.push(daughters[iDaughter]);
955 if (nClusterDaughters < 1) {
956 B2WARNING(
"There are no clusters amongst the daughters of the provided particle!");
959 B2DEBUG(10,
"Number of daughters with cluster associated = " << nClusterDaughters);
966 std::string cutString =
"";
967 if (arguments.size() > 0) {
968 cutString = arguments[0];
972 std::string photonlistname =
"gamma:all";
973 if (arguments.size() > 1) {
974 photonlistname = arguments[1];
977 std::string tracklistname =
"e-:all";
978 if (arguments.size() > 2) {
979 tracklistname = arguments[2];
982 auto func = [cut, photonlistname, tracklistname](
const Particle * particle) ->
double {
986 B2WARNING(
"The variable photonHasOverlap is supposed to be calculated for photons. Returning NaN.");
990 StoreObjPtr<ParticleList> photonlist(photonlistname);
991 if (!(photonlist.isValid()))
993 B2WARNING(
"The provided particle list " << photonlistname <<
" does not exist."
994 " Therefore, the variable photonHasOverlap can not be calculated. Returning NaN.");
999 B2WARNING(
"The list " << photonlistname <<
" does not contain photons."
1000 " Therefore, the variable photonHasOverlap can not be calculated reliably. Returning NaN.");
1004 StoreObjPtr<ParticleList> tracklist(tracklistname);
1005 if (!(tracklist.isValid()))
1007 B2WARNING(
"The provided particle list " << tracklistname <<
" does not exist."
1008 " Therefore, the variable photonHasOverlap can not be calculated. Returning NaN.");
1013 B2WARNING(
"The list " << tracklistname <<
" does not contain charged final state particles."
1014 " Therefore, the variable photonHasOverlap can not be calculated reliably. Returning NaN.");
1018 double connectedRegionID = eclClusterConnectedRegionID(particle);
1019 unsigned mdstArrayIndex = particle->getMdstArrayIndex();
1021 for (
unsigned int i = 0; i < photonlist->getListSize(); i++)
1023 const Particle* part = photonlist->getParticle(i);
1026 if (part->getMdstArrayIndex() == mdstArrayIndex) {
1031 if (!cut->check(part)) {
1035 if (connectedRegionID == eclClusterConnectedRegionID(part)) {
1040 for (
unsigned int i = 0; i < tracklist->getListSize(); i++)
1042 const Particle* part = tracklist->getParticle(i);
1045 if (!cut->check(part)) {
1049 if (connectedRegionID == eclClusterConnectedRegionID(part)) {
1059 VARIABLE_GROUP(
"ECL Cluster related");
1060 REGISTER_VARIABLE(
"clusterEoP", eclClusterEoP, R
"DOC(
1061 Returns ratio of uncorrelated energy E over momentum p, a convenience
1062 alias for (clusterE / p).
1064 REGISTER_VARIABLE("clusterReg", eclClusterDetectionRegion, R
"DOC(
1065 Returns an integer code for the ECL region of a cluster.
1067 - 1: forward, 2: barrel, 3: backward,
1068 - 11: between FWD and barrel, 13: between BWD and barrel,
1071 REGISTER_VARIABLE("clusterDeltaLTemp", eclClusterDeltaL, R
"DOC(
1072 | Returns DeltaL for the shower shape.
1073 | A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1074 different orientations in space. A shower direction can be constructed by calculating the weighted
1075 average of these orientations using the corresponding energy depositions as weights. The intersection
1076 (more precisely the point of closest approach) of the vector with this direction originating from the
1077 cluster center and an extrapolated track can be used as reference for the calculation of the shower
1078 depth. It is defined as the distance between this intersection and the cluster center.
1081 This distance is calculated on the reconstructed level and is temporarily
1082 included to the ECL cluster MDST data format for studying purposes. If it is found
1083 that it is not crucial for physics analysis then this variable will be removed
1085 Therefore, keep in mind that this variable might be removed in the future!
1088 | Please read `this <importantNoteECL>` first.
1089 | Lower limit: :math:`-250.0`
1090 | Upper limit: :math:`250.0`
1091 | Precision: :math:`10` bit
1096 REGISTER_VARIABLE("minC2TDist", eclClusterIsolation, R"DOC(
1097 Returns the distance between the ECL cluster and its nearest track.
1099 For all tracks in the event, the distance between each of their extrapolated hits in the ECL and the ECL shower
1100 position is calculated, and the overall smallest distance is returned. The track array index of the track that is
1101 closest to the ECL cluster can be retrieved using `minC2TDistID`.
1103 If the calculated distance is greater than :math:`250.0`, the returned distance will be capped at :math:`250.0`.
1104 If there are no extrapolated hits found in the ECL for the event, NaN will be returned.
1107 This distance is calculated on the reconstructed level.
1110 | Please read `this <importantNoteECL>` first.
1111 | Lower limit: :math:`0.0`
1112 | Upper limit: :math:`250.0`
1113 | Precision: :math:`10` bit
1117 REGISTER_VARIABLE("minC2TDistID", eclClusterIsolationID, R"DOC(
1118 Returns the track array index of the nearest track to the ECL cluster. The nearest track is calculcated
1119 using the `minC2TDist` variable.
1121 REGISTER_METAVARIABLE("minC2TDistVar(variable,particleList=pi-:all)", eclClusterIsolationVar, R
"DOC(
1122 Returns the variable value of the nearest track to the given ECL cluster as calculated by `minC2TDist`. The
1123 first argument is the variable name, e.g. `nCDCHits`, while the second (optional) argument is the particle list name which
1124 will be used to pick up the nearest track in the calculation of `minC2TDist`. The default particle list used
1126 )DOC", Manager::VariableDataType::c_double);
1127 REGISTER_VARIABLE("clusterE", eclClusterE, R
"DOC(
1128 Returns ECL cluster's energy corrected for leakage and background.
1130 The raw photon energy is given by the weighted sum of all ECL crystal energies within the ECL cluster.
1131 The weights per crystals are :math:`\leq 1` after cluster energy splitting in the case of overlapping
1132 clusters. The number of crystals that are included in the sum depends on a initial energy estimation
1133 and local beam background levels at the highest energy crystal position. It is optimized to minimize
1134 the core width (resolution) of true photons. Photon energy distributions always show a low energy tail
1135 due to unavoidable longitudinal and transverse leakage that can be further modified by the clustering
1136 algorithm and beam backgrounds.The peak position of the photon energy distributions are corrected to
1137 match the true photon energy in MC:
1139 - Leakage correction: Using large MC samples of mono-energetic single photons, a correction factor
1140 :math:`f` as function of reconstructed detector position, reconstructed photon energy and beam backgrounds
1141 is determined via :math:`f = \frac{\text{peak_reconstructed}}{\text{energy_true}}`.
1143 - Cluster energy calibration (data only): To reach the target precision of :math:`< 1.8\%` energy
1144 resolution for high energetic photons, the remaining difference between MC and data must be calibrated
1145 using kinematically fit muon pairs. This calibration is only applied to data and not to MC and will
1146 take time to develop.
1148 - Energy Bias Correction module, sub-percent correction, is NOT applied on clusterE, but on photon energy
1149 and momentum. Only applied to data.
1151 It is important to note that after perfect leakage correction and cluster energy calibration,
1152 the :math:`\pi^{0}` mass peak will be shifted slightly to smaller values than the PDG average
1153 due to the low energy tails of photons. The :math:`\pi^{0}` mass peak must not be corrected
1154 to the PDG value by adjusting the reconstructed photon energies. Selection criteria based on
1155 the mass for :math:`\pi^{0}` candidates must be based on the biased value. Most analysis
1156 will used mass constrained :math:`\pi^{0}` s anyhow.
1159 We only store clusters with :math:`E > 20\,` MeV.
1162 | Please read `this <importantNoteECL>` first.
1163 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1164 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1165 | Precision: :math:`18` bit
1166 | This value can be changed to a different reference frame with :b2:var:`useCMSFrame`.
1170 REGISTER_VARIABLE("clusterErrorE", eclClusterErrorE, R"DOC(
1171 Returns ECL cluster's uncertainty on energy
1172 (from background level and energy dependent tabulation).
1175 REGISTER_VARIABLE("clusterErrorPhi", eclClusterErrorPhi, R"DOC(
1176 Returns ECL cluster's uncertainty on :math:`\phi`
1177 (from background level and energy dependent tabulation).
1180 REGISTER_VARIABLE("clusterErrorTheta", eclClusterErrorTheta, R"DOC(
1181 Returns ECL cluster's uncertainty on :math:`\theta`
1182 (from background level and energy dependent tabulation).
1186 REGISTER_VARIABLE("clusterR", eclClusterR, R"DOC(
1187 Returns ECL cluster's centroid distance from :math:`(0,0,0)`.
1190 REGISTER_VARIABLE("clusterPhi", eclClusterPhi, R"DOC(
1191 Returns ECL cluster's azimuthal angle :math:`\phi`
1192 (this is not generally equal to a photon azimuthal angle).
1194 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1195 cluster centroid position in the ECL.
1196 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1197 after cluster energy splitting in the case of overlapping clusters.
1198 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1199 the crystal centers. Cluster centroids are generally biased towards the centers of the
1200 highest energetic crystal. This effect is larger for low energetic photons.
1201 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1204 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1206 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1207 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1208 as function of true photon energy, true photon direction and beam background level.
1211 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1212 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1213 from :math:`(0,0,0)`) for particle kinematics.
1216 | Please read `this <importantNoteECL>` first.
1217 | Lower limit: :math:`-\pi`
1218 | Upper limit: :math:`\pi`
1219 | Precision: :math:`16` bit
1223 REGISTER_VARIABLE("clusterConnectedRegionID", eclClusterConnectedRegionID, R"DOC(
1224 Returns ECL cluster's connected region ID.
1226 REGISTER_VARIABLE("clusterTheta", eclClusterTheta, R
"DOC(
1227 Returns ECL cluster's polar angle :math:`\theta`
1228 (this is not generally equal to a photon polar angle).
1230 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1231 cluster centroid position in the ECL.
1232 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1233 after cluster energy splitting in the case of overlapping clusters.
1234 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1235 the crystal centers. Cluster centroids are generally biased towards the centers of the
1236 highest energetic crystal. This effect is larger for low energetic photons.
1237 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1240 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1242 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1243 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1244 as function of true photon energy, true photon direction and beam background level.
1247 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1248 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1249 from :math:`(0,0,0)`) for particle kinematics.
1252 | Please read `this <importantNoteECL>` first.
1253 | Lower limit: :math:`0.0`
1254 | Upper limit: :math:`\pi`
1255 | Precision: :math:`16` bit
1259 REGISTER_VARIABLE("clusterTiming", eclClusterTiming, R"DOC(
1261 Returns the time of the ECL cluster. It is calculated as the Photon timing minus the Event t0.
1262 Photon timing is given by the fitted time of the recorded waveform of the highest energy crystal in the
1263 cluster. After all calibrations and corrections (including Time-Of-Flight), photons from the interaction
1264 point (IP) should have a Photon timing that corresponds to the Event t0, :math:`t_{0}`. The Event t0 is the
1265 time of the event and may be measured by a different sub-detector (see Event t0 documentation). For an ECL
1266 cluster produced at the interaction point in time with the event, the cluster time should be consistent with zero
1267 within the uncertainties. Special values are returned if the fit for the Photon timing fails (see
1268 documentation for `clusterHasFailedTiming`). (For MC, the calibrations and corrections are not fully simulated).
1271 | Please read `this <importantNoteECL>` first.
1272 | Lower limit: :math:`-1000.0`
1273 | Upper limit: :math:`1000.0`
1274 | Precision: :math:`12` bit
1278 Returns the trigger cell (TC) time of the ECL cluster (photon).
1279 This information is available only in Belle data since experiment 31, and not available in Belle MC.
1280 Clusters produced at the interaction point in time with the event, have TC time in the range of 9000-11000
1281 Calculated based on the Appendix of Belle note 831.
1284 | In case this variable is obtained from Belle data that is stored in Belle II mdst/udst format, it will be truncated to:
1285 | Lower limit: :math:`-1000.0`
1286 | Upper limit: :math:`1000.0`
1287 | Precision: :math:`12` bit
1291 REGISTER_VARIABLE("clusterHasFailedTiming", eclClusterHasFailedTiming, R"DOC(
1292 Status bit for if the ECL cluster's timing fit failed. Photon timing is given by the fitted time
1293 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1294 this variable tells the user if that has happened.
1296 REGISTER_VARIABLE("clusterErrorTiming", eclClusterErrorTiming, R
"DOC(
1297 Returns ECL cluster's timing uncertainty that contains :math:`99\%` of true photons (dt99).
1299 The photon timing uncertainty is currently determined using MC. The resulting parametrization depends on
1300 the true energy deposition in the highest energetic crystal and the local beam background level in that crystal.
1301 The resulting timing distribution is non-Gaussian and for each photon the value dt99 is stored,
1302 where :math:`|\text{timing}| / \text{dt99} < 1` is designed to give a :math:`99\%`
1303 timing efficiency for true photons from the IP.
1304 The resulting efficiency is approximately flat in energy and independent of beam background levels.
1306 Very large values of dt99 are an indication of failed waveform fits in the ECL.
1307 We remove such clusters in most physics photon lists.
1310 | Please read `this <importantNoteECL>` first.
1311 | Lower limit: :math:`0.0`
1312 | Upper limit: :math:`1000.0`
1313 | Precision: :math:`12` bit
1316 In real data there will be a sizeable number of high energetic Bhabha events
1317 (from previous or later bunch collisions) that can easily be rejected by timing cuts.
1318 However, these events create large ECL clusters that can overlap with other ECL clusters
1319 and it is not clear that a simple rejection is the correction strategy.
1323 REGISTER_VARIABLE("clusterHasFailedErrorTiming", eclClusterHasFailedErrorTiming, R"DOC(
1324 Status bit for if the ECL cluster's timing uncertainty calculation failed. Photon timing is given by the fitted time
1325 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1326 this variable tells the user if that has happened.
1328 REGISTER_VARIABLE("clusterHighestE", eclClusterHighestE, R
"DOC(
1329 Returns energy of the highest energetic crystal in the ECL cluster after reweighting.
1332 This variable must be used carefully since it can bias shower selection
1333 towards photons that hit crystals in the center and hence have a large energy
1334 deposition in the highest energy crystal.
1337 | Please read `this <importantNoteECL>` first.
1338 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1339 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1340 | Precision: :math:`18` bit
1344 REGISTER_VARIABLE("clusterCellID", eclClusterCellId,
1345 "Returns cellId of the crystal with highest energy in the ECLCluster.");
1346 REGISTER_VARIABLE("clusterThetaID", eclClusterThetaId,
1347 "Returns thetaId of the crystal with highest energy in the ECLCluster.");
1348 REGISTER_VARIABLE("clusterPhiID", eclClusterPhiId,
1349 "Returns phiId of the crystal with highest energy in the ECLCluster.");
1350 REGISTER_VARIABLE("clusterE1E9", eclClusterE1E9, R"DOC(
1351 Returns ratio of energies of the central crystal, E1, and 3x3 crystals, E9, around the central crystal.
1352 Since :math:`E1 \leq E9`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1353 and smaller values for hadrons.
1356 | Please read `this <importantNoteECL>` first.
1357 | Lower limit: :math:`0.0`
1358 | Upper limit: :math:`1.0`
1359 | Precision: :math:`10` bit
1361 REGISTER_VARIABLE("clusterE9E25", eclClusterE9E25, R
"DOC(
1362 Deprecated - kept for backwards compatibility - returns clusterE9E21.
1364 REGISTER_VARIABLE("clusterE9E21", eclClusterE9E21, R
"DOC(
1365 Returns ratio of energies in inner 3x3 crystals, E9, and 5x5 crystals around the central crystal without corners.
1366 Since :math:`E9 \leq E21`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1367 and smaller values for hadrons.
1370 | Please read `this <importantNoteECL>` first.
1371 | Lower limit: :math:`0.0`
1372 | Upper limit: :math:`1.0`
1373 | Precision: :math:`10` bit
1375 REGISTER_VARIABLE("clusterAbsZernikeMoment40", eclClusterAbsZernikeMoment40, R
"DOC(
1376 Returns absolute value of Zernike moment 40 (:math:`|Z_{40}|`). (shower shape variable).
1379 | Please read `this <importantNoteECL>` first.
1380 | Lower limit: :math:`0.0`
1381 | Upper limit: :math:`1.7`
1382 | Precision: :math:`10` bit
1384 REGISTER_VARIABLE("clusterAbsZernikeMoment51", eclClusterAbsZernikeMoment51, R
"DOC(
1385 Returns absolute value of Zernike moment 51 (:math:`|Z_{51}|`). (shower shape variable).
1388 | Please read `this <importantNoteECL>` first.
1389 | Lower limit: :math:`0.0`
1390 | Upper limit: :math:`1.2`
1391 | Precision: :math:`10` bit
1393 REGISTER_VARIABLE("clusterZernikeMVA", eclClusterZernikeMVA, R
"DOC(
1394 Returns output of a MVA using eleven Zernike moments of the cluster. Zernike moments are calculated per
1395 shower in a plane perpendicular to the shower direction via
1398 |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|
1400 where n, m are the integers, :math:`i` runs over the crystals in the shower,
1401 :math:`E_{i}` is the energy of the i-th crystal in the shower,
1402 :math:`R_{nm}` is a polynomial of degree :math:`n`,
1403 :math:`\rho_{i}` is the radial distance of the :math:`i`-th crystal in the perpendicular plane,
1404 and :math:`\alpha_{i}` is the polar angle of the :math:`i`-th crystal in the perpendicular plane.
1405 As a crystal can be related to more than one shower, :math:`w_{i}` is the fraction of the
1406 energy of the :math:`i`-th crystal associated with the shower.
1408 More details about the implementation can be found in `BELLE2-NOTE-TE-2017-001 <https://docs.belle2.org/record/454?ln=en>`_ .
1410 More details about Zernike polynomials can be found in `Wikipedia <https://en.wikipedia.org/wiki/Zernike_polynomials>`_ .
1412 | For cluster with hypothesisId==N1: raw MVA output.
1413 | For cluster with hypothesisId==N2: 1 - prod{clusterZernikeMVA}, where the product is on all N1 showers
1414 belonging to the same connected region (shower shape variable).
1417 | Please read `this <importantNoteECL>` first.
1418 | Lower limit: :math:`0.0`
1419 | Upper limit: :math:`1.0`
1420 | Precision: :math:`10` bit
1422 REGISTER_VARIABLE("clusterSecondMoment", eclClusterSecondMoment, R
"DOC(
1423 Returns second moment :math:`S`. It is defined as:
1426 S = \frac{\sum_{i=0}^{n} w_{i} E_{i} r^2_{i}}{\sum_{i=0}^{n} w_{i} E_{i}}
1428 where :math:`E_{i} = (E_0, E_1, ...)` are the single crystal energies sorted by energy, :math:`w_{i}` is
1429 the crystal weight, and :math:`r_{i}` is the distance of the :math:`i`-th digit to the shower center projected
1430 to a plane perpendicular to the shower axis.
1433 | Please read `this <importantNoteECL>` first.
1434 | Lower limit: :math:`0.0`
1435 | Upper limit: :math:`40.0`
1436 | Precision: :math:`10` bit
1439 )DOC",":math:`\\text{cm}^2`");
1440 REGISTER_VARIABLE("clusterLAT", eclClusterLAT, R"DOC(
1441 Returns lateral energy distribution (shower variable). It is defined as following:
1444 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}}
1446 where :math:`E_{i} = (E_{0}, E_{1}, ...)` are the single crystal energies sorted by energy
1447 (:math:`E_{0}` is the highest energy and :math:`E_{1}` the second highest), :math:`w_{i}`
1448 is the crystal weight, :math:`r_{i}` is the distance of the :math:`i`-th digit to the
1449 shower center projected to a plane perpendicular to the shower axis,
1450 and :math:`r_{0} \approx 5\,cm` is the distance between two crystals.
1452 clusterLAT peaks around 0.3 for radially symmetrical electromagnetic showers and is larger
1453 for hadronic events, and electrons with a close-by radiative or Bremsstrahlung photon.
1456 | Please read `this <importantNoteECL>` first.
1457 | Lower limit: :math:`0.0`
1458 | Upper limit: :math:`1.0`
1459 | Precision: :math:`10` bit
1461 REGISTER_VARIABLE("clusterNHits", eclClusterNHits, R
"DOC(
1462 Returns sum of weights :math:`w_{i}` (:math:`w_{i} \leq 1`) of all crystals in an ECL cluster.
1463 For non-overlapping clusters this is equal to the number of crystals in the cluster.
1464 In case of energy splitting among nearby clusters, this can be a non-integer value.
1467 | Please read `this <importantNoteECL>` first.
1468 | Lower limit: :math:`0.0`
1469 | Upper limit: :math:`200.0`
1470 | Precision: :math:`10` bit
1471 | If fractional weights are not of interest, this value should be cast to the nearest integer.
1473 REGISTER_VARIABLE("clusterTrackMatch", eclClusterTrackMatched, R
"DOC(
1474 Returns 1.0 if at least one reconstructed charged track is matched to the ECL cluster.
1476 Every reconstructed charged track is extrapolated into the ECL.
1477 Every ECL crystal that is crossed by the track extrapolation is marked.
1478 Each ECL cluster that contains any marked crystal is matched to the track.
1479 Multiple tracks can be matched to one cluster and multiple clusters can be matched to one track.
1480 It is conceptually correct to have two tracks matched to the same cluster.
1482 REGISTER_VARIABLE("nECLClusterTrackMatches", nECLClusterTrackMatches, R
"DOC(
1483 Returns number of charged tracks matched to this cluster.
1486 Sometimes (perfectly correctly) two tracks are extrapolated into the same cluster.
1488 - For charged particles, this should return at least 1 (but sometimes 2 or more).
1489 - For neutrals, this should always return 0.
1490 - Returns NaN if there is no cluster.
1492 REGISTER_VARIABLE("clusterHasPulseShapeDiscrimination", eclClusterHasPulseShapeDiscrimination, R
"DOC(
1493 Status bit to indicate if cluster has digits with waveforms that passed energy and :math:`\chi^2`
1494 thresholds for computing PSD variables.
1496 REGISTER_VARIABLE("beamBackgroundSuppression", beamBackgroundSuppression, R
"DOC(
1497 Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from beam background clusters.
1498 Class 1 is for true photon clusters while class 0 is for beam background clusters.
1500 The MVA has been trained using MC and the features used are:
1503 - `clusterPulseShapeDiscriminationMVA`
1506 - `clusterZernikeMVA`
1508 Both run-dependent and run-independent weights are available. For more information on this, and for usage recommendations, please see
1509 the `Neutrals Performance Confluence Page <https://confluence.desy.de/display/BI/Neutrals+Performance>`_.
1511 REGISTER_VARIABLE("fakePhotonSuppression", fakePhotonSuppression, R
"DOC(
1512 Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from fake photon clusters (e.g. split-offs,
1513 track-cluster matching failures etc.). Class 1 is for true photon clusters while class 0 is for fake photon clusters.
1515 The MVA has been trained using MC and the features are:
1517 - `clusterPulseShapeDiscriminationMVA`
1519 - `clusterZernikeMVA`
1524 This MVA is the same as the one used for `hadronicSplitOffSuppression` but that variable should not be used as it is deprecated and does not use the new weights.
1526 Both run-dependent and run-independent weights are available. For more information on this, and for usage recommendations, please see
1527 the `Neutrals Performance Confluence Page <https://confluence.desy.de/display/BI/Neutrals+Performance>`_.
1529 REGISTER_VARIABLE("hadronicSplitOffSuppression", hadronicSplitOffSuppression, R
"DOC(
1530 Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from hadronic splitoff clusters.
1533 - 1 for true photon clusters
1534 - 0 for hadronic splitoff clusters
1536 The MVA has been trained using samples of signal photons and hadronic splitoff photons coming from MC. The features used are (in decreasing order of significance):
1538 - `clusterPulseShapeDiscriminationMVA`
1540 - `clusterZernikeMVA`
1544 - `clusterSecondMoment`
1546 MAKE_DEPRECATED("hadronicSplitOffSuppression",
false,
"light-2302-genetta", R
"DOC(
1547 Use the variable `fakePhotonSuppression` instead which is maintained and uses the latest weight files.
1549 REGISTER_VARIABLE("clusterKlId", eclClusterKlId, R
"DOC(
1550 Returns MVA classifier that uses ECL clusters variables to discriminate Klong clusters from em background.
1555 REGISTER_VARIABLE("clusterPulseShapeDiscriminationMVA", eclPulseShapeDiscriminationMVA, R
"DOC(
1556 Returns MVA classifier that uses pulse shape discrimination to identify electromagnetic vs hadronic showers.
1558 - 1 for electromagnetic showers
1559 - 0 for hadronic showers
1561 REGISTER_VARIABLE("clusterNumberOfHadronDigits", eclClusterNumberOfHadronDigits, R
"DOC(
1562 Returns ECL cluster's number of hadron digits in cluster (pulse shape discrimination variable).
1563 Weighted sum of digits in cluster with significant scintillation emission (:math:`> 3\,` MeV)
1564 in the hadronic scintillation component.
1565 Computed only using cluster digits with energy :math:`> 50\,` MeV and good offline waveform fit :math:`\chi^2`.
1568 | Please read `this <importantNoteECL>` first.
1569 | Lower limit: :math:`0.0`
1570 | Upper limit: :math:`255.0`
1571 | Precision: :math:`18` bit
1573 REGISTER_VARIABLE("clusterClusterID", eclClusterId, R
"DOC(
1574 Returns ECL cluster ID of this ECL cluster within the connected region (CR) to which it belongs to.
1576 REGISTER_VARIABLE("clusterHasNPhotons", eclClusterHasNPhotonsHypothesis, R
"DOC(
1577 Returns 1.0 if cluster has the 'N photons' hypothesis (historically called 'N1'),
1578 0.0 if not, and NaN if no cluster is associated to the particle.
1580 REGISTER_VARIABLE("clusterHasNeutralHadron", eclClusterHasNeutralHadronHypothesis, R
"DOC(
1581 Returns 1.0 if the cluster has the 'neutral hadrons' hypothesis (historically called 'N2'),
1582 0.0 if not, and NaN if no cluster is associated to the particle.
1584 REGISTER_VARIABLE("eclExtTheta", eclExtTheta, R
"DOC(
1585 Returns extrapolated :math:`\theta` of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed.
1588 REGISTER_VARIABLE("eclExtPhi", eclExtPhi, R"DOC(
1589 Returns extrapolated :math:`\phi` of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed..
1592 REGISTER_VARIABLE("eclExtPhiId", eclExtPhiId, R"DOC(
1593 Returns extrapolated :math:`\phi` ID of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed..
1595 REGISTER_VARIABLE("weightedAverageECLTime", weightedAverageECLTime, R
"DOC(
1596 Returns ECL weighted average time of all clusters (neutrals) and matched clusters (charged) of daughters
1597 (of any generation) of the provided particle.
1600 REGISTER_VARIABLE(
"maxWeightedDistanceFromAverageECLTime", maxWeightedDistanceFromAverageECLTime, R
"DOC(
1601 Returns maximum weighted distance between time of the cluster of a photon and the ECL average time, amongst
1602 the clusters (neutrals) and matched clusters (charged) of daughters (of all generations) of the provided particle.
1605 REGISTER_VARIABLE(
"clusterMdstIndex", eclClusterMdstIndex, R
"DOC(
1606 StoreArray index(0 - based) of the MDST ECLCluster (useful for track-based particles matched to a cluster).
1609 REGISTER_VARIABLE("nECLOutOfTimeCrystals", nECLOutOfTimeCrystals, R
"DOC(
1610 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time.
1613 REGISTER_VARIABLE("nECLOutOfTimeCrystalsFWDEndcap", nECLOutOfTimeCrystalsFWDEndcap, R
"DOC(
1614 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the forward endcap.
1617 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBarrel", nECLOutOfTimeCrystalsBarrel, R
"DOC(
1618 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the barrel.
1621 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBWDEndcap", nECLOutOfTimeCrystalsBWDEndcap, R
"DOC(
1622 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the backward endcap.
1625 REGISTER_VARIABLE("nRejectedECLShowers", nRejectedECLShowers, R
"DOC(
1626 [Eventbased] Returns the number of showers in the ECL that do not become clusters.
1629 REGISTER_VARIABLE("nRejectedECLShowersFWDEndcap", nRejectedECLShowersFWDEndcap, R
"DOC(
1630 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the forward endcap.
1631 If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1634 REGISTER_VARIABLE("nRejectedECLShowersBarrel", nRejectedECLShowersBarrel, R
"DOC(
1635 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the barrel.
1636 If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1639 REGISTER_VARIABLE("nRejectedECLShowersBWDEndcap", nRejectedECLShowersBWDEndcap, R
"DOC(
1640 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the backward endcap.
1641 If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1644 REGISTER_VARIABLE("nKLMMultistripHitsFWDEndcap", nKLMMultistripHitsFWDEndcap, R
"DOC(
1645 [Eventbased] Returns the number of multi-strip hits in the KLM forward endcap.
1648 REGISTER_VARIABLE("nKLMMultistripHitsBarrel", nKLMMultistripHitsBarrel, R
"DOC(
1649 [Eventbased] Returns the number of multi-strip hits in the KLM barrel.
1652 REGISTER_VARIABLE("nKLMMultistripHitsBWDEndcap", nKLMMultistripHitsBWDEndcap, R
"DOC(
1653 [Eventbased] Returns the number of multi-strip hits in the KLM backward endcap.
1656 REGISTER_VARIABLE("nKLMMultistripHits", nKLMMultistripHits, R
"DOC(
1657 [Eventbased] Returns the number of multi-strip hits in the KLM.
1660 REGISTER_VARIABLE("nECLShowersFWDEndcap", nECLShowersFWDEndcap, R
"DOC(
1661 [Eventbased] Returns the number of ECLShowers in the forward endcap.
1664 REGISTER_VARIABLE("nECLShowersBarrel", nECLShowersBarrel, R
"DOC(
1665 [Eventbased] Returns the number of ECLShowers in the barrel.
1668 REGISTER_VARIABLE("nECLShowersBWDEndcap", nECLShowersBWDEndcap, R
"DOC(
1669 [Eventbased] Returns the number of ECLShowers in the backward endcap.
1672 REGISTER_VARIABLE("nECLShowers", nECLShowers, R
"DOC(
1673 [Eventbased] Returns the number of ECLShowers.
1676 REGISTER_VARIABLE("nECLLocalMaximumsFWDEndcap", nECLLocalMaximumsFWDEndcap, R
"DOC(
1677 [Eventbased] Returns the number of LocalMaximums in the ECL forward endcap.
1680 REGISTER_VARIABLE("nECLLocalMaximumsBarrel", nECLLocalMaximumsBarrel, R
"DOC(
1681 [Eventbased] Returns the number of LocalMaximums in the ECL barrel.
1684 REGISTER_VARIABLE("nECLLocalMaximumsBWDEndcap", nECLLocalMaximumsBWDEndcap, R
"DOC(
1685 [Eventbased] Returns the number of LocalMaximums in the ECL backward endcap.
1688 REGISTER_VARIABLE("nECLLocalMaximums", nECLLocalMaximums, R
"DOC(
1689 [Eventbased] Returns the number of LocalMaximums in the ECL.
1692 REGISTER_VARIABLE("nECLTriggerCellsFWDEndcap", nECLTriggerCellsFWDEndcap, R
"DOC(
1693 [Eventbased] Returns the number of ECL trigger cells above 100 MeV in the forward endcap.
1696 REGISTER_VARIABLE("nECLTriggerCellsBarrel", nECLTriggerCellsBarrel, R
"DOC(
1697 [Eventbased] Returns the number of ECL trigger cells above 100 MeV in the barrel.
1700 REGISTER_VARIABLE("nECLTriggerCellsBWDEndcap", nECLTriggerCellsBWDEndcap, R
"DOC(
1701 [Eventbased] Returns the number of ECL trigger cells above 100 MeV in the backward endcap.
1704 REGISTER_VARIABLE("nECLTriggerCells", nECLTriggerCells, R
"DOC(
1705 [Eventbased] Returns the number of ECL trigger cells above 100 MeV.
1708 REGISTER_VARIABLE("eclClusterOnlyInvariantMass", eclClusterOnlyInvariantMass, R
"DOC(
1709 [Expert] The invariant mass calculated from all ECLCluster daughters (i.e. photons) and
1710 cluster-matched tracks using the cluster 4-momenta.
1712 Used for ECL-based dark sector physics and debugging track-cluster matching.
1714 )DOC","GeV/:math:`\\text{c}^2`");
1716 REGISTER_METAVARIABLE("photonHasOverlap(cutString, photonlistname, tracklistname)", photonHasOverlap, R"DOC(
1717 Returns true if the connected ECL region of the particle's cluster is shared by another particle's cluster.
1718 Neutral and charged cluster are considered.
1719 A cut string can be provided to ignore cluster that do not satisfy the given criteria.
1720 By default, the ParticleList ``gamma:all`` is used for the check of neutral ECL cluster,
1721 and the ParticleList ``e-:all`` for the check of charged ECL cluster.
1722 However, one can customize the name of the ParticleLists via additional arguments.
1723 If no argument or only a cut string is provided and ``gamma:all`` or ``e-:all`` does not exist
1724 or if the variable is requested for a particle that is not a photon, NaN is returned.
1725 )DOC", Manager::VariableDataType::c_double);
1727 REGISTER_VARIABLE("clusterUncorrE", eclClusterUncorrectedE, R
"DOC(
1728 [Expert] [Calibration] Returns ECL cluster's uncorrected energy. That is, before leakage corrections.
1729 This variable should only be used for study of the ECL. Please see :b2:var:`clusterE`.
1733 REGISTER_VARIABLE("distanceToMcKl",distanceToMcKl,R"DOC(
1734 Returns the distance to the nearest truth KL particle, extrapolated to the cluster radius. To use
1735 this variable, it is required to run getNeutralHadronGeomMatches function. Optionally, it can return
1736 negative values to indicate that the ECL cluster should be removed from the analysis to correct for data
1737 to MC difference in KL efficiency.
1741 REGISTER_VARIABLE(
"distanceToMcNeutron",distanceToMcNeutron,R
"DOC(
1742 Returns the distance to the nearest truth (anti)neutron, extrapolated to the cluster radius. To use
1743 this variable, it is required to run getNeutralHadronGeomMatches function. Optionally, it can return
1744 negative values to indicate that the ECL cluster should be removed from the analysis to correct for data
1745 to MC difference in KL efficiency.
1749 REGISTER_VARIABLE(
"mdstIndexMcKl",mdstIndexMcKl,R
"DOC(
1750 Returns the mdst index of the nearest truth KL, extrapolated to the cluster radius, if it is
1751 within the matching cone. To use this variable, it is required to run getNeutralHadronGeomMatches function.
1754 REGISTER_VARIABLE("mdstIndexMcNeutron",mdstIndexMcNeutron,R
"DOC(
1755 Returns the mdst index of the nearest truth (anti)neutron, extrapolated to the cluster radius, if it is
1756 within the matching cone. To use this variable, it is required to run getNeutralHadronGeomMatches function.
int getPDGCode() const
PDG code.
static const ParticleSet chargedStableSet
set of charged stable particles
static const double doubleNaN
quiet_NaN
static const ParticleType photon
photon particle
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
@ c_nPhotons
CR is split into n photons (N1)
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
static const ReferenceFrame & GetCurrent()
Get current rest frame.
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
#define MAKE_DEPRECATED(name, make_fatal, version, description)
Registers a variable as deprecated.
Abstract base class for different kinds of events.