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 use the standard particle lists (stdPhotons or stdPi0s) or run getBeamBackgroundProbability on a photon list.");
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 use the standard particle lists (stdPhotons or stdPi0s) or run getFakePhotonProbability on a photon list.");
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();
249 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster);
250 return sqrt(fabs(EPhiThetaCov[0][0]));
255 double eclClusterUncorrectedE(
const Particle* particle)
258 const ECLCluster* cluster = particle->getECLCluster();
260 return cluster->getEnergyRaw();
265 double eclClusterE(
const Particle* particle)
269 const ECLCluster* cluster = particle->getECLCluster();
272 ROOT::Math::PxPyPzEVector p4Cluster = clutls.GetCluster4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
274 return frame.getMomentum(p4Cluster).E();
279 double eclClusterHighestE(
const Particle* particle)
282 const ECLCluster* cluster = particle->getECLCluster();
284 return cluster->getEnergyHighestCrystal();
289 double eclClusterCellId(
const Particle* particle)
292 const ECLCluster* cluster = particle->getECLCluster();
294 return cluster->getMaxECellId();
300 const std::array<int, 69> lastCellIDperThetaID{48, 96, 160, 224, 288, 384, 480, 576, 672, 768, 864,
301 1008, 1152, 1296, 1440, 1584, 1728, 1872, 2016, 2160, 2304, 2448,
302 2592, 2736, 2880, 3024, 3168, 3312, 3456, 3600, 3744, 3888, 4032,
303 4176, 4320, 4464, 4608, 4752, 4896, 5040, 5184, 5328, 5472, 5616,
304 5760, 5904, 6048, 6192, 6336, 6480, 6624, 6768, 6912, 7056, 7200,
305 7344, 7488, 7632, 7776, 7920, 8064, 8160, 8256, 8352, 8448, 8544,
308 double eclClusterThetaId(
const Particle* particle)
311 const ECLCluster* cluster = particle->getECLCluster();
313 int cellID = cluster->getMaxECellId();
314 return std::distance(lastCellIDperThetaID.begin(), std::lower_bound(lastCellIDperThetaID.begin(), lastCellIDperThetaID.end(),
320 double eclClusterPhiId(
const Particle* particle)
323 const ECLCluster* cluster = particle->getECLCluster();
325 int cellID = cluster->getMaxECellId();
329 int closestinlist = lastCellIDperThetaID[std::distance(lastCellIDperThetaID.begin(), std::lower_bound(lastCellIDperThetaID.begin(),
330 lastCellIDperThetaID.end(), cellID)) - 1];
331 return cellID - closestinlist - 1;
337 double eclClusterTiming(
const Particle* particle)
340 const ECLCluster* cluster = particle->getECLCluster();
342 return cluster->getTime();
347 double eclClusterHasFailedTiming(
const Particle* particle)
349 const ECLCluster* cluster = particle->getECLCluster();
351 return cluster->hasFailedFitTime();
356 double eclClusterErrorTiming(
const Particle* particle)
359 const ECLCluster* cluster = particle->getECLCluster();
361 return cluster->getDeltaTime99();
366 double eclClusterHasFailedErrorTiming(
const Particle* particle)
368 const ECLCluster* cluster = particle->getECLCluster();
370 return cluster->hasFailedTimeResolution();
375 double eclClusterTheta(
const Particle* particle)
379 const ECLCluster* cluster = particle->getECLCluster();
382 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
384 return frame.getMomentum(p4Cluster).Theta();
389 double eclClusterErrorTheta(
const Particle* particle)
392 const ECLCluster* cluster = particle->getECLCluster();
395 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster);
396 return sqrt(fabs(EPhiThetaCov[2][2]));
401 double eclClusterErrorPhi(
const Particle* particle)
404 const ECLCluster* cluster = particle->getECLCluster();
407 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster);
408 return sqrt(fabs(EPhiThetaCov[1][1]));
413 double eclClusterPhi(
const Particle* particle)
417 const ECLCluster* cluster = particle->getECLCluster();
420 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
422 return frame.getMomentum(p4Cluster).Phi();
427 double eclClusterR(
const Particle* particle)
430 const ECLCluster* cluster = particle->getECLCluster();
432 return cluster->getR();
437 double eclClusterE1E9(
const Particle* particle)
440 const ECLCluster* cluster = particle->getECLCluster();
442 return cluster->getE1oE9();
447 double eclClusterE9E21(
const Particle* particle)
450 const ECLCluster* cluster = particle->getECLCluster();
452 return cluster->getE9oE21();
457 double eclClusterAbsZernikeMoment40(
const Particle* particle)
460 const ECLCluster* cluster = particle->getECLCluster();
462 return cluster->getAbsZernike40();
467 double eclClusterAbsZernikeMoment51(
const Particle* particle)
470 const ECLCluster* cluster = particle->getECLCluster();
472 return cluster->getAbsZernike51();
477 double eclClusterZernikeMVA(
const Particle* particle)
480 const ECLCluster* cluster = particle->getECLCluster();
482 return cluster->getZernikeMVA();
487 double eclClusterSecondMoment(
const Particle* particle)
490 const ECLCluster* cluster = particle->getECLCluster();
492 return cluster->getSecondMoment();
497 double eclClusterLAT(
const Particle* particle)
500 const ECLCluster* cluster = particle->getECLCluster();
502 return cluster->getLAT();
507 double eclClusterNHits(
const Particle* particle)
510 const ECLCluster* cluster = particle->getECLCluster();
512 return cluster->getNumberOfCrystals();
517 double eclClusterTrackMatched(
const Particle* particle)
520 const ECLCluster* cluster = particle->getECLCluster();
522 const Track* track = cluster->getRelatedFrom<Track>();
532 double nECLClusterTrackMatches(
const Particle* particle)
535 const ECLCluster* cluster = particle->getECLCluster();
540 size_t out = cluster->getRelationsFrom<Track>().size();
544 double eclClusterId(
const Particle* particle)
546 const ECLCluster* cluster = particle->getECLCluster();
548 return cluster->getClusterId();
553 double eclClusterHasNPhotonsHypothesis(
const Particle* particle)
555 const ECLCluster* cluster = particle->getECLCluster();
562 double eclClusterHasNeutralHadronHypothesis(
const Particle* particle)
564 const ECLCluster* cluster = particle->getECLCluster();
571 double eclClusterHasPulseShapeDiscrimination(
const Particle* particle)
573 const ECLCluster* cluster = particle->getECLCluster();
575 return cluster->hasPulseShapeDiscrimination();
580 double eclExtTheta(
const Particle* particle)
583 const Track* track = particle->getTrack();
586 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
589 return eclinfo->getExtTheta();
591 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
599 double eclExtPhi(
const Particle* particle)
602 const Track* track = particle->getTrack();
605 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
608 return eclinfo->getExtPhi();
610 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
618 double eclExtPhiId(
const Particle* particle)
620 const Track* track = particle->getTrack();
623 auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
626 return eclinfo->getExtPhiId();
628 B2WARNING(
"Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
636 double weightedAverageECLTime(
const Particle* particle)
638 int nDaughters = particle->getNDaughters();
639 if (nDaughters < 1) {
640 B2WARNING(
"The provided particle has no daughters!");
644 double numer = 0, denom = 0;
645 int numberOfClusterDaughters = 0;
647 auto weightedECLTimeAverage = [&numer, &denom, &numberOfClusterDaughters](
const Particle * p) {
648 const ECLCluster* cluster = p->getECLCluster();
649 if (cluster and not cluster->hasFailedFitTime()) {
650 numberOfClusterDaughters ++;
652 double time = cluster->getTime();
653 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
654 double deltatime = cluster->getDeltaTime99();
655 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
656 numer += time / pow(deltatime, 2);
657 B2DEBUG(11,
"numer[" << numberOfClusterDaughters <<
"] = " << numer);
658 denom += 1 / pow(deltatime, 2);
659 B2DEBUG(11,
"denom[" << numberOfClusterDaughters <<
"] = " << denom);
664 particle->forEachDaughter(weightedECLTimeAverage,
true,
true);
666 if (numberOfClusterDaughters < 1) {
667 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
672 B2WARNING(
"The denominator of the weighted mean is zero!");
675 B2DEBUG(10,
"numer/denom = " << numer / denom);
676 return numer / denom;
680 double maxWeightedDistanceFromAverageECLTime(
const Particle* particle)
682 int nDaughters = particle->getNDaughters();
683 if (nDaughters < 1) {
684 B2WARNING(
"The provided particle has no daughters!");
688 double maxTimeDiff = -DBL_MAX;
689 int numberOfClusterDaughters = 0;
691 double averageECLTime = weightedAverageECLTime(particle);
693 auto maxTimeDifference = [&maxTimeDiff, &numberOfClusterDaughters, &averageECLTime](
const Particle * p) {
695 const ECLCluster* cluster = p->getECLCluster();
697 numberOfClusterDaughters ++;
699 double time = cluster->getTime();
700 B2DEBUG(10,
"time[" << numberOfClusterDaughters <<
"] = " << time);
701 double deltatime = cluster->getDeltaTime99();
702 B2DEBUG(10,
"deltatime[" << numberOfClusterDaughters <<
"] = " << deltatime);
703 double maxTimeDiff_temp = fabs((time - averageECLTime) / deltatime);
704 B2DEBUG(11,
"maxTimeDiff_temp[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff_temp);
705 if (maxTimeDiff_temp > maxTimeDiff)
706 maxTimeDiff = maxTimeDiff_temp;
707 B2DEBUG(11,
"maxTimeDiff[" << numberOfClusterDaughters <<
"] = " << maxTimeDiff);
712 particle->forEachDaughter(maxTimeDifference,
true,
true);
714 if (numberOfClusterDaughters < 1) {
715 B2WARNING(
"There are no clusters or cluster matches amongst the daughters of the provided particle!");
719 if (maxTimeDiff < 0) {
720 B2WARNING(
"The max time difference is negative!");
723 B2DEBUG(10,
"maxTimeDiff = " << maxTimeDiff);
728 double eclClusterMdstIndex(
const Particle* particle)
730 const ECLCluster* cluster = particle->getECLCluster();
732 return cluster->getArrayIndex();
742 double nECLOutOfTimeCrystalsFWDEndcap(
const Particle*)
744 StoreObjPtr<EventLevelClusteringInfo> elci;
746 return (
double)elci->getNECLCalDigitsOutOfTimeFWD();
749 double nECLOutOfTimeCrystalsBarrel(
const Particle*)
751 StoreObjPtr<EventLevelClusteringInfo> elci;
753 return (
double)elci->getNECLCalDigitsOutOfTimeBarrel();
756 double nECLOutOfTimeCrystalsBWDEndcap(
const Particle*)
758 StoreObjPtr<EventLevelClusteringInfo> elci;
760 return (
double)elci->getNECLCalDigitsOutOfTimeBWD();
763 double nECLOutOfTimeCrystals(
const Particle*)
765 StoreObjPtr<EventLevelClusteringInfo> elci;
767 return (
double)elci->getNECLCalDigitsOutOfTime();
770 double nRejectedECLShowersFWDEndcap(
const Particle*)
772 StoreObjPtr<EventLevelClusteringInfo> elci;
774 return (
double)elci->getNECLShowersRejectedFWD();
777 double nRejectedECLShowersBarrel(
const Particle*)
779 StoreObjPtr<EventLevelClusteringInfo> elci;
781 return (
double)elci->getNECLShowersRejectedBarrel();
784 double nRejectedECLShowersBWDEndcap(
const Particle*)
786 StoreObjPtr<EventLevelClusteringInfo> elci;
788 return (
double)elci->getNECLShowersRejectedBWD();
791 double nRejectedECLShowers(
const Particle*)
793 StoreObjPtr<EventLevelClusteringInfo> elci;
795 return (
double) elci->getNECLShowersRejected();
798 double nKLMMultistripHitsFWDEndcap(
const Particle*)
800 StoreObjPtr<EventLevelClusteringInfo> elci;
802 return (
double) elci->getNKLMDigitsMultiStripFWD();
805 double nKLMMultistripHitsBarrel(
const Particle*)
807 StoreObjPtr<EventLevelClusteringInfo> elci;
809 return (
double) elci->getNKLMDigitsMultiStripBarrel();
812 double nKLMMultistripHitsBWDEndcap(
const Particle*)
814 StoreObjPtr<EventLevelClusteringInfo> elci;
816 return (
double) elci->getNKLMDigitsMultiStripBWD();
819 double nKLMMultistripHits(
const Particle*)
821 StoreObjPtr<EventLevelClusteringInfo> elci;
823 return (
double) elci->getNKLMDigitsMultiStrip();
826 double nECLShowersFWDEndcap(
const Particle*)
828 StoreObjPtr<EventLevelClusteringInfo> elci;
830 return (
double) elci->getNECLShowersFWD();
833 double nECLShowersBarrel(
const Particle*)
835 StoreObjPtr<EventLevelClusteringInfo> elci;
837 return (
double) elci->getNECLShowersBarrel();
840 double nECLShowersBWDEndcap(
const Particle*)
842 StoreObjPtr<EventLevelClusteringInfo> elci;
844 return (
double) elci->getNECLShowersBWD();
847 double nECLShowers(
const Particle*)
849 StoreObjPtr<EventLevelClusteringInfo> elci;
851 return (
double) elci->getNECLShowers();
854 double nECLLocalMaximumsFWDEndcap(
const Particle*)
856 StoreObjPtr<EventLevelClusteringInfo> elci;
858 return (
double) elci->getNECLLocalMaximumsFWD();
861 double nECLLocalMaximumsBarrel(
const Particle*)
863 StoreObjPtr<EventLevelClusteringInfo> elci;
865 return (
double) elci->getNECLLocalMaximumsBarrel();
868 double nECLLocalMaximumsBWDEndcap(
const Particle*)
870 StoreObjPtr<EventLevelClusteringInfo> elci;
872 return (
double) elci->getNECLLocalMaximumsBWD();
875 double nECLLocalMaximums(
const Particle*)
877 StoreObjPtr<EventLevelClusteringInfo> elci;
879 return (
double) elci->getNECLLocalMaximums();
882 double nECLTriggerCellsFWDEndcap(
const Particle*)
884 StoreObjPtr<EventLevelClusteringInfo> elci;
886 return (
double) elci->getNECLTriggerCellsFWD();
889 double nECLTriggerCellsBarrel(
const Particle*)
891 StoreObjPtr<EventLevelClusteringInfo> elci;
893 return (
double) elci->getNECLTriggerCellsBarrel();
896 double nECLTriggerCellsBWDEndcap(
const Particle*)
898 StoreObjPtr<EventLevelClusteringInfo> elci;
900 return (
double) elci->getNECLTriggerCellsBWD();
903 double nECLTriggerCells(
const Particle*)
905 StoreObjPtr<EventLevelClusteringInfo> elci;
907 return (
double) elci->getNECLTriggerCells();
910 double eclClusterEoP(
const Particle* part)
912 double E = eclClusterE(part);
913 if (part->hasExtraInfo(
"bremsCorrectedPhotonEnergy")) {
914 E += part->getExtraInfo(
"bremsCorrectedPhotonEnergy");
916 const double p = part->getMomentumMagnitude();
921 double eclClusterOnlyInvariantMass(
const Particle* part)
923 int nDaughters = part->getNDaughters();
924 ROOT::Math::PxPyPzEVector sum;
926 if (nDaughters < 1) {
927 return part->getMass();
929 int nClusterDaughters = 0;
930 std::stack<const Particle*> stacked;
932 while (!stacked.empty()) {
933 const Particle* current = stacked.top();
936 const ECLCluster* cluster = current->getECLCluster();
939 nClusterDaughters ++;
941 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterBit);
944 const std::vector<Particle*> daughters = current->getDaughters();
945 nDaughters = current->getNDaughters();
946 for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
947 stacked.push(daughters[iDaughter]);
952 if (nClusterDaughters < 1) {
953 B2WARNING(
"There are no clusters amongst the daughters of the provided particle!");
956 B2DEBUG(10,
"Number of daughters with cluster associated = " << nClusterDaughters);
963 std::string cutString =
"";
964 if (arguments.size() > 0) {
965 cutString = arguments[0];
969 std::string photonlistname =
"gamma:all";
970 if (arguments.size() > 1) {
971 photonlistname = arguments[1];
974 std::string tracklistname =
"e-:all";
975 if (arguments.size() > 2) {
976 tracklistname = arguments[2];
979 auto func = [cut, photonlistname, tracklistname](
const Particle * particle) ->
double {
983 B2WARNING(
"The variable photonHasOverlap is supposed to be calculated for photons. Returning NaN.");
987 StoreObjPtr<ParticleList> photonlist(photonlistname);
988 if (!(photonlist.isValid()))
990 B2WARNING(
"The provided particle list " << photonlistname <<
" does not exist."
991 " Therefore, the variable photonHasOverlap can not be calculated. Returning NaN.");
996 B2WARNING(
"The list " << photonlistname <<
" does not contain photons."
997 " Therefore, the variable photonHasOverlap can not be calculated reliably. Returning NaN.");
1001 StoreObjPtr<ParticleList> tracklist(tracklistname);
1002 if (!(tracklist.isValid()))
1004 B2WARNING(
"The provided particle list " << tracklistname <<
" does not exist."
1005 " Therefore, the variable photonHasOverlap can not be calculated. Returning NaN.");
1010 B2WARNING(
"The list " << tracklistname <<
" does not contain charged final state particles."
1011 " Therefore, the variable photonHasOverlap can not be calculated reliably. Returning NaN.");
1015 double connectedRegionID = eclClusterConnectedRegionID(particle);
1016 unsigned mdstArrayIndex = particle->getMdstArrayIndex();
1018 for (
unsigned int i = 0; i < photonlist->getListSize(); i++)
1020 const Particle* part = photonlist->getParticle(i);
1023 if (part->getMdstArrayIndex() == mdstArrayIndex) {
1028 if (!cut->check(part)) {
1032 if (connectedRegionID == eclClusterConnectedRegionID(part)) {
1037 for (
unsigned int i = 0; i < tracklist->getListSize(); i++)
1039 const Particle* part = tracklist->getParticle(i);
1042 if (!cut->check(part)) {
1046 if (connectedRegionID == eclClusterConnectedRegionID(part)) {
1056 VARIABLE_GROUP(
"ECL Cluster related");
1057 REGISTER_VARIABLE(
"clusterEoP", eclClusterEoP, R
"DOC(
1058Returns ratio of uncorrelated energy E over momentum p, a convenience
1059alias for (clusterE / p).
1061 REGISTER_VARIABLE("clusterReg", eclClusterDetectionRegion, R
"DOC(
1062Returns an integer code for the ECL region of a cluster.
1064- 1: forward, 2: barrel, 3: backward,
1065- 11: between FWD and barrel, 13: between BWD and barrel,
1068 REGISTER_VARIABLE("clusterDeltaLTemp", eclClusterDeltaL, R
"DOC(
1069| Returns DeltaL for the shower shape.
1070| A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1071 different orientations in space. A shower direction can be constructed by calculating the weighted
1072 average of these orientations using the corresponding energy depositions as weights. The intersection
1073 (more precisely the point of closest approach) of the vector with this direction originating from the
1074 cluster center and an extrapolated track can be used as reference for the calculation of the shower
1075 depth. It is defined as the distance between this intersection and the cluster center.
1078 This distance is calculated on the reconstructed level and is temporarily
1079 included to the ECL cluster MDST data format for studying purposes. If it is found
1080 that it is not crucial for physics analysis then this variable will be removed
1082 Therefore, keep in mind that this variable might be removed in the future!
1085 | Please read `this <importantNoteECL>` first.
1086 | Lower limit: :math:`-250.0`
1087 | Upper limit: :math:`250.0`
1088 | Precision: :math:`10` bit
1093 REGISTER_VARIABLE("minC2TDist", eclClusterIsolation, R"DOC(
1094Returns the distance between the ECL cluster and its nearest track.
1096For all tracks in the event, the distance between each of their extrapolated hits in the ECL and the ECL shower
1097position is calculated, and the overall smallest distance is returned. The track array index of the track that is
1098closest to the ECL cluster can be retrieved using `minC2TDistID`.
1100If the calculated distance is greater than :math:`250.0`, the returned distance will be capped at :math:`250.0`.
1101If there are no extrapolated hits found in the ECL for the event, NaN will be returned.
1104 This distance is calculated on the reconstructed level.
1107 | Please read `this <importantNoteECL>` first.
1108 | Lower limit: :math:`0.0`
1109 | Upper limit: :math:`250.0`
1110 | Precision: :math:`10` bit
1114 REGISTER_VARIABLE("minC2TDistID", eclClusterIsolationID, R"DOC(
1115Returns the track array index of the nearest track to the ECL cluster. The nearest track is calculated
1116using the `minC2TDist` variable.
1118 REGISTER_METAVARIABLE("minC2TDistVar(variable,particleList=pi-:all)", eclClusterIsolationVar, R
"DOC(
1119Returns the variable value of the nearest track to the given ECL cluster as calculated by `minC2TDist`. The
1120first argument is the variable name, e.g. `nCDCHits`, while the second (optional) argument is the particle list name which
1121will be used to pick up the nearest track in the calculation of `minC2TDist`. The default particle list used
1123)DOC", Manager::VariableDataType::c_double);
1124 REGISTER_VARIABLE("clusterE", eclClusterE, R
"DOC(
1125Returns ECL cluster's energy corrected for leakage and background.
1127The raw photon energy is given by the weighted sum of all ECL crystal energies within the ECL cluster.
1128The weights per crystals are :math:`\leq 1` after cluster energy splitting in the case of overlapping
1129clusters. The number of crystals that are included in the sum depends on a initial energy estimation
1130and local beam background levels at the highest energy crystal position. It is optimized to minimize
1131the core width (resolution) of true photons. Photon energy distributions always show a low energy tail
1132due to unavoidable longitudinal and transverse leakage that can be further modified by the clustering
1133algorithm and beam backgrounds.The peak position of the photon energy distributions are corrected to
1134match 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- Energy Bias Correction module, sub-percent correction, is NOT applied on clusterE, but on photon energy
1146 and momentum. Only applied to data.
1148It is important to note that after perfect leakage correction and cluster energy calibration,
1149the :math:`\pi^{0}` mass peak will be shifted slightly to smaller values than the PDG average
1150due to the low energy tails of photons. The :math:`\pi^{0}` mass peak must not be corrected
1151to the PDG value by adjusting the reconstructed photon energies. Selection criteria based on
1152the mass for :math:`\pi^{0}` candidates must be based on the biased value. Most analysis
1153will used mass constrained :math:`\pi^{0}` s anyhow.
1156 We only store clusters with :math:`E > 20\,` MeV.
1159 | Please read `this <importantNoteECL>` first.
1160 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1161 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1162 | Precision: :math:`18` bit
1163 | This value can be changed to a different reference frame with :b2:var:`useCMSFrame`.
1167 REGISTER_VARIABLE("clusterErrorE", eclClusterErrorE, R"DOC(
1168Returns ECL cluster's uncertainty on energy
1169(from background level and energy dependent tabulation).
1172 REGISTER_VARIABLE("clusterErrorPhi", eclClusterErrorPhi, R"DOC(
1173Returns ECL cluster's uncertainty on :math:`\phi`
1174(from background level and energy dependent tabulation).
1177 REGISTER_VARIABLE("clusterErrorTheta", eclClusterErrorTheta, R"DOC(
1178Returns ECL cluster's uncertainty on :math:`\theta`
1179(from background level and energy dependent tabulation).
1183 REGISTER_VARIABLE("clusterR", eclClusterR, R"DOC(
1184Returns ECL cluster's centroid distance from :math:`(0,0,0)`.
1187 REGISTER_VARIABLE("clusterPhi", eclClusterPhi, R"DOC(
1188Returns ECL cluster's azimuthal angle :math:`\phi`
1189(this is not generally equal to a photon azimuthal angle).
1191| The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1192 cluster centroid position in the ECL.
1193| The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1194 after cluster energy splitting in the case of overlapping clusters.
1195| The centroid position is the logarithmically weighted average of all crystals evaluated at
1196 the crystal centers. Cluster centroids are generally biased towards the centers of the
1197 highest energetic crystal. This effect is larger for low energetic photons.
1198| Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1201 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1203Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1204based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1205as function of true photon energy, true photon direction and beam background level.
1208 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1209 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1210 from :math:`(0,0,0)`) for particle kinematics.
1213 | Please read `this <importantNoteECL>` first.
1214 | Lower limit: :math:`-\pi`
1215 | Upper limit: :math:`\pi`
1216 | Precision: :math:`16` bit
1220 REGISTER_VARIABLE("clusterConnectedRegionID", eclClusterConnectedRegionID, R"DOC(
1221Returns ECL cluster's connected region ID.
1223 REGISTER_VARIABLE("clusterTheta", eclClusterTheta, R
"DOC(
1224Returns ECL cluster's polar angle :math:`\theta`
1225(this is not generally equal to a photon polar angle).
1227| The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1228 cluster centroid position in the ECL.
1229| The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1230 after cluster energy splitting in the case of overlapping clusters.
1231| The centroid position is the logarithmically weighted average of all crystals evaluated at
1232 the crystal centers. Cluster centroids are generally biased towards the centers of the
1233 highest energetic crystal. This effect is larger for low energetic photons.
1234| Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1237 Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1239Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1240based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1241as function of true photon energy, true photon direction and beam background level.
1244 Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1245 IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1246 from :math:`(0,0,0)`) for particle kinematics.
1249 | Please read `this <importantNoteECL>` first.
1250 | Lower limit: :math:`0.0`
1251 | Upper limit: :math:`\pi`
1252 | Precision: :math:`16` bit
1256 REGISTER_VARIABLE("clusterTiming", eclClusterTiming, R"DOC(
1258Returns the time of the ECL cluster. It is calculated as the Photon timing minus the Event t0.
1259Photon timing is given by the fitted time of the recorded waveform of the highest energy crystal in the
1260cluster. After all calibrations and corrections (including Time-Of-Flight), photons from the interaction
1261point (IP) should have a Photon timing that corresponds to the Event t0, :math:`t_{0}`. The Event t0 is the
1262time of the event and may be measured by a different sub-detector (see Event t0 documentation). For an ECL
1263cluster produced at the interaction point in time with the event, the cluster time should be consistent with zero
1264within the uncertainties. Special values are returned if the fit for the Photon timing fails (see
1265documentation for `clusterHasFailedTiming`). (For MC, the calibrations and corrections are not fully simulated).
1268 | Please read `this <importantNoteECL>` first.
1269 | Lower limit: :math:`-1000.0`
1270 | Upper limit: :math:`1000.0`
1271 | Precision: :math:`12` bit
1275Returns the trigger cell (TC) time of the ECL cluster (photon).
1276This information is available only in Belle data since experiment 31, and not available in Belle MC.
1277Clusters produced at the interaction point in time with the event, have TC time in the range of 9000-11000
1278Calculated based on the Appendix of Belle note 831.
1281 | In case this variable is obtained from Belle data that is stored in Belle II mdst/udst format, it will be truncated to:
1282 | Lower limit: :math:`-1000.0`
1283 | Upper limit: :math:`1000.0`
1284 | Precision: :math:`12` bit
1288 REGISTER_VARIABLE("clusterHasFailedTiming", eclClusterHasFailedTiming, R"DOC(
1289Status bit for if the ECL cluster's timing fit failed. Photon timing is given by the fitted time
1290of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1291this variable tells the user if that has happened.
1293 REGISTER_VARIABLE("clusterErrorTiming", eclClusterErrorTiming, R
"DOC(
1294Returns ECL cluster's timing uncertainty that contains :math:`99\%` of true photons (dt99).
1296The photon timing uncertainty is currently determined using MC. The resulting parametrization depends on
1297the true energy deposition in the highest energetic crystal and the local beam background level in that crystal.
1298The resulting timing distribution is non-Gaussian and for each photon the value dt99 is stored,
1299where :math:`|\text{timing}| / \text{dt99} < 1` is designed to give a :math:`99\%`
1300timing efficiency for true photons from the IP.
1301The resulting efficiency is approximately flat in energy and independent of beam background levels.
1303Very large values of dt99 are an indication of failed waveform fits in the ECL.
1304We remove such clusters in most physics photon lists.
1307 | Please read `this <importantNoteECL>` first.
1308 | Lower limit: :math:`0.0`
1309 | Upper limit: :math:`1000.0`
1310 | Precision: :math:`12` bit
1313 In real data there will be a sizeable number of high energetic Bhabha events
1314 (from previous or later bunch collisions) that can easily be rejected by timing cuts.
1315 However, these events create large ECL clusters that can overlap with other ECL clusters
1316 and it is not clear that a simple rejection is the correction strategy.
1320 REGISTER_VARIABLE("clusterHasFailedErrorTiming", eclClusterHasFailedErrorTiming, R"DOC(
1321Status bit for if the ECL cluster's timing uncertainty calculation failed. Photon timing is given by the fitted time
1322of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1323this variable tells the user if that has happened.
1325 REGISTER_VARIABLE("clusterHighestE", eclClusterHighestE, R
"DOC(
1326Returns energy of the highest energetic crystal in the ECL cluster after reweighting.
1329 This variable must be used carefully since it can bias shower selection
1330 towards photons that hit crystals in the center and hence have a large energy
1331 deposition in the highest energy crystal.
1334 | Please read `this <importantNoteECL>` first.
1335 | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1336 | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1337 | Precision: :math:`18` bit
1341 REGISTER_VARIABLE("clusterCellID", eclClusterCellId,
1342 "Returns cellId of the crystal with highest energy in the ECLCluster.");
1343 REGISTER_VARIABLE("clusterThetaID", eclClusterThetaId,
1344 "Returns thetaId of the crystal with highest energy in the ECLCluster.");
1345 REGISTER_VARIABLE("clusterPhiID", eclClusterPhiId,
1346 "Returns phiId of the crystal with highest energy in the ECLCluster.");
1347 REGISTER_VARIABLE("clusterE1E9", eclClusterE1E9, R"DOC(
1348Returns ratio of energies of the central crystal, E1, and 3x3 crystals, E9, around the central crystal.
1349Since :math:`E1 \leq E9`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1350and smaller values for hadrons.
1353 | Please read `this <importantNoteECL>` first.
1354 | Lower limit: :math:`0.0`
1355 | Upper limit: :math:`1.0`
1356 | Precision: :math:`10` bit
1358 REGISTER_VARIABLE("clusterE9E25", eclClusterE9E25, R
"DOC(
1359Deprecated - kept for backwards compatibility - returns clusterE9E21.
1361 REGISTER_VARIABLE("clusterE9E21", eclClusterE9E21, R
"DOC(
1362Returns ratio of energies in inner 3x3 crystals, E9, and 5x5 crystals around the central crystal without corners.
1363Since :math:`E9 \leq E21`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1364and smaller values for hadrons.
1367 | Please read `this <importantNoteECL>` first.
1368 | Lower limit: :math:`0.0`
1369 | Upper limit: :math:`1.0`
1370 | Precision: :math:`10` bit
1372 REGISTER_VARIABLE("clusterAbsZernikeMoment40", eclClusterAbsZernikeMoment40, R
"DOC(
1373Returns absolute value of Zernike moment 40 (:math:`|Z_{40}|`). (shower shape variable).
1376 | Please read `this <importantNoteECL>` first.
1377 | Lower limit: :math:`0.0`
1378 | Upper limit: :math:`1.7`
1379 | Precision: :math:`10` bit
1381 REGISTER_VARIABLE("clusterAbsZernikeMoment51", eclClusterAbsZernikeMoment51, R
"DOC(
1382Returns absolute value of Zernike moment 51 (:math:`|Z_{51}|`). (shower shape variable).
1385 | Please read `this <importantNoteECL>` first.
1386 | Lower limit: :math:`0.0`
1387 | Upper limit: :math:`1.2`
1388 | Precision: :math:`10` bit
1390 REGISTER_VARIABLE("clusterZernikeMVA", eclClusterZernikeMVA, R
"DOC(
1391Returns output of a MVA using eleven Zernike moments of the cluster. Zernike moments are calculated per
1392shower in a plane perpendicular to the shower direction via
1395 |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|
1397where n, m are the integers, :math:`i` runs over the crystals in the shower,
1398:math:`E_{i}` is the energy of the i-th crystal in the shower,
1399:math:`R_{nm}` is a polynomial of degree :math:`n`,
1400:math:`\rho_{i}` is the radial distance of the :math:`i`-th crystal in the perpendicular plane,
1401and :math:`\alpha_{i}` is the polar angle of the :math:`i`-th crystal in the perpendicular plane.
1402As a crystal can be related to more than one shower, :math:`w_{i}` is the fraction of the
1403energy of the :math:`i`-th crystal associated with the shower.
1405More details about the implementation can be found in `BELLE2-NOTE-TE-2017-001 <https://docs.belle2.org/record/454?ln=en>`_ .
1407More details about Zernike polynomials can be found in `Wikipedia <https://en.wikipedia.org/wiki/Zernike_polynomials>`_ .
1409| For cluster with hypothesisId==N1: raw MVA output.
1410| For cluster with hypothesisId==N2: 1 - prod{clusterZernikeMVA}, where the product is on all N1 showers
1411 belonging to the same connected region (shower shape variable).
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("clusterSecondMoment", eclClusterSecondMoment, R
"DOC(
1420Returns second moment :math:`S`. It is defined as:
1423 S = \frac{1}{S_{0}(\theta)}\frac{\sum_{i=0}^{n} w_{i} E_{i} r^2_{i}}{\sum_{i=0}^{n} w_{i} E_{i}}
1425where :math:`E_{i} = (E_0, E_1, ...)` are the single crystal energies sorted by energy, :math:`w_{i}` is
1426the crystal weight, and :math:`r_{i}` is the distance of the :math:`i`-th digit to the shower center projected
1427to a plane perpendicular to the shower axis. :math:`S_{0}(\theta)` normalizes :math:`S` to 1 for isolated photons.
1430 | Please read `this <importantNoteECL>` first.
1431 | Lower limit: :math:`0.0`
1432 | Upper limit: :math:`40.0`
1433 | Precision: :math:`10` bit
1436)DOC","dimensionless");
1437 REGISTER_VARIABLE("clusterLAT", eclClusterLAT, R"DOC(
1438Returns lateral energy distribution (shower variable). It is defined as following:
1441 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}}
1443where :math:`E_{i} = (E_{0}, E_{1}, ...)` are the single crystal energies sorted by energy
1444(:math:`E_{0}` is the highest energy and :math:`E_{1}` the second highest), :math:`w_{i}`
1445is the crystal weight, :math:`r_{i}` is the distance of the :math:`i`-th digit to the
1446shower center projected to a plane perpendicular to the shower axis,
1447and :math:`r_{0} \approx 5\,cm` is the distance between two crystals.
1449clusterLAT peaks around 0.3 for radially symmetrical electromagnetic showers and is larger
1450for hadronic events, and electrons with a close-by radiative or Bremsstrahlung photon.
1453 | Please read `this <importantNoteECL>` first.
1454 | Lower limit: :math:`0.0`
1455 | Upper limit: :math:`1.0`
1456 | Precision: :math:`10` bit
1458 REGISTER_VARIABLE("clusterNHits", eclClusterNHits, R
"DOC(
1459Returns sum of weights :math:`w_{i}` (:math:`w_{i} \leq 1`) of all crystals in an ECL cluster.
1460For non-overlapping clusters this is equal to the number of crystals in the cluster.
1461In case of energy splitting among nearby clusters, this can be a non-integer value.
1464 | Please read `this <importantNoteECL>` first.
1465 | Lower limit: :math:`0.0`
1466 | Upper limit: :math:`200.0`
1467 | Precision: :math:`10` bit
1468 | If fractional weights are not of interest, this value should be cast to the nearest integer.
1470 REGISTER_VARIABLE("clusterTrackMatch", eclClusterTrackMatched, R
"DOC(
1471Returns 1.0 if at least one reconstructed charged track is matched to the ECL cluster.
1473Every reconstructed charged track is extrapolated into the ECL.
1474Every ECL crystal that is crossed by the track extrapolation is marked.
1475Each ECL cluster that contains any marked crystal is matched to the track.
1476Multiple tracks can be matched to one cluster and multiple clusters can be matched to one track.
1477It is conceptually correct to have two tracks matched to the same cluster.
1479 REGISTER_VARIABLE("nECLClusterTrackMatches", nECLClusterTrackMatches, R
"DOC(
1480Returns number of charged tracks matched to this cluster.
1483 Sometimes (perfectly correctly) two tracks are extrapolated into the same cluster.
1485 - For charged particles, this should return at least 1 (but sometimes 2 or more).
1486 - For neutrals, this should always return 0.
1487 - Returns NaN if there is no cluster.
1489 REGISTER_VARIABLE("clusterHasPulseShapeDiscrimination", eclClusterHasPulseShapeDiscrimination, R
"DOC(
1490Status bit to indicate if cluster has digits with waveforms that passed energy and :math:`\chi^2`
1491thresholds for computing PSD variables.
1493 REGISTER_VARIABLE("beamBackgroundSuppression", beamBackgroundSuppression, R
"DOC(
1494Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from beam background clusters.
1495Class 1 is for true photon clusters while class 0 is for beam background clusters.
1497The MVA has been trained using MC and the features used are:
1500- `clusterPulseShapeDiscriminationMVA`
1503- `clusterZernikeMVA`
1505Both run-dependent and run-independent weights are available. For more information on this, and for usage recommendations, please see
1506the `Neutrals Performance XWiki Page <https://xwiki.desy.de/xwiki/rest/p/e23c8>`_.
1508 REGISTER_VARIABLE("fakePhotonSuppression", fakePhotonSuppression, R
"DOC(
1509Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from fake photon clusters (e.g. split-offs,
1510track-cluster matching failures etc.). Class 1 is for true photon clusters while class 0 is for fake photon clusters.
1512The MVA has been trained using MC and the features are:
1514- `clusterPulseShapeDiscriminationMVA`
1516- `clusterZernikeMVA`
1521This 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.
1523Both run-dependent and run-independent weights are available. For more information on this, and for usage recommendations, please see
1524the `Neutrals Performance XWiki Page <https://xwiki.desy.de/xwiki/rest/p/e23c8>`_.
1526 REGISTER_VARIABLE("hadronicSplitOffSuppression", hadronicSplitOffSuppression, R
"DOC(
1527Returns the output of an MVA classifier that uses shower-related variables to distinguish true photon clusters from hadronic splitoff clusters.
1530- 1 for true photon clusters
1531- 0 for hadronic splitoff clusters
1533The 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):
1535- `clusterPulseShapeDiscriminationMVA`
1537- `clusterZernikeMVA`
1541- `clusterSecondMoment`
1543 MAKE_DEPRECATED("hadronicSplitOffSuppression",
false,
"light-2302-genetta", R
"DOC(
1544 Use the variable `fakePhotonSuppression` instead which is maintained and uses the latest weight files.
1546 REGISTER_VARIABLE("clusterKlId", eclClusterKlId, R
"DOC(
1547Returns MVA classifier that uses ECL clusters variables to discriminate Klong clusters from em background.
1552 REGISTER_VARIABLE("clusterPulseShapeDiscriminationMVA", eclPulseShapeDiscriminationMVA, R
"DOC(
1553Returns MVA classifier that uses pulse shape discrimination to identify electromagnetic vs hadronic showers.
1555- 1 for electromagnetic showers
1556- 0 for hadronic showers
1558 REGISTER_VARIABLE("clusterNumberOfHadronDigits", eclClusterNumberOfHadronDigits, R
"DOC(
1559Returns ECL cluster's number of hadron digits in cluster (pulse shape discrimination variable).
1560Weighted sum of digits in cluster with significant scintillation emission (:math:`> 3\,` MeV)
1561in the hadronic scintillation component.
1562Computed only using cluster digits with energy :math:`> 50\,` MeV and good offline waveform fit :math:`\chi^2`.
1565 | Please read `this <importantNoteECL>` first.
1566 | Lower limit: :math:`0.0`
1567 | Upper limit: :math:`255.0`
1568 | Precision: :math:`18` bit
1570 REGISTER_VARIABLE("clusterClusterID", eclClusterId, R
"DOC(
1571Returns ECL cluster ID of this ECL cluster within the connected region (CR) to which it belongs to.
1573 REGISTER_VARIABLE("clusterHasNPhotons", eclClusterHasNPhotonsHypothesis, R
"DOC(
1574Returns 1.0 if cluster has the 'N photons' hypothesis (historically called 'N1'),
15750.0 if not, and NaN if no cluster is associated to the particle.
1577 REGISTER_VARIABLE("clusterHasNeutralHadron", eclClusterHasNeutralHadronHypothesis, R
"DOC(
1578Returns 1.0 if the cluster has the 'neutral hadrons' hypothesis (historically called 'N2'),
15790.0 if not, and NaN if no cluster is associated to the particle.
1581 REGISTER_VARIABLE("eclExtTheta", eclExtTheta, R
"DOC(
1582Returns extrapolated :math:`\theta` of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed.
1585 REGISTER_VARIABLE("eclExtPhi", eclExtPhi, R"DOC(
1586Returns extrapolated :math:`\phi` of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed..
1589 REGISTER_VARIABLE("eclExtPhiId", eclExtPhiId, R"DOC(
1590Returns extrapolated :math:`\phi` ID of particle track associated to the cluster (if any). Requires module ECLTrackCalDigitMatch to be executed..
1592 REGISTER_VARIABLE("weightedAverageECLTime", weightedAverageECLTime, R
"DOC(
1593Returns ECL weighted average time of all clusters (neutrals) and matched clusters (charged) of daughters
1594(of any generation) of the provided particle.
1597 REGISTER_VARIABLE(
"maxWeightedDistanceFromAverageECLTime", maxWeightedDistanceFromAverageECLTime, R
"DOC(
1598Returns maximum weighted distance between time of the cluster of a photon and the ECL average time, amongst
1599the clusters (neutrals) and matched clusters (charged) of daughters (of all generations) of the provided particle.
1602 REGISTER_VARIABLE(
"clusterMdstIndex", eclClusterMdstIndex, R
"DOC(
1603StoreArray index(0 - based) of the MDST ECLCluster (useful for track-based particles matched to a cluster).
1606 REGISTER_VARIABLE("nECLOutOfTimeCrystals", nECLOutOfTimeCrystals, R
"DOC(
1607[Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time.
1610 REGISTER_VARIABLE("nECLOutOfTimeCrystalsFWDEndcap", nECLOutOfTimeCrystalsFWDEndcap, R
"DOC(
1611[Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the forward endcap.
1614 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBarrel", nECLOutOfTimeCrystalsBarrel, R
"DOC(
1615[Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the barrel.
1618 REGISTER_VARIABLE("nECLOutOfTimeCrystalsBWDEndcap", nECLOutOfTimeCrystalsBWDEndcap, R
"DOC(
1619[Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the backward endcap.
1622 REGISTER_VARIABLE("nRejectedECLShowers", nRejectedECLShowers, R
"DOC(
1623[Eventbased] Returns the number of showers in the ECL that do not become clusters.
1626 REGISTER_VARIABLE("nRejectedECLShowersFWDEndcap", nRejectedECLShowersFWDEndcap, R
"DOC(
1627[Eventbased] Returns the number of showers in the ECL that do not become clusters, from the forward endcap.
1628If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1631 REGISTER_VARIABLE("nRejectedECLShowersBarrel", nRejectedECLShowersBarrel, R
"DOC(
1632[Eventbased] Returns the number of showers in the ECL that do not become clusters, from the barrel.
1633If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1636 REGISTER_VARIABLE("nRejectedECLShowersBWDEndcap", nRejectedECLShowersBWDEndcap, R
"DOC(
1637[Eventbased] Returns the number of showers in the ECL that do not become clusters, from the backward endcap.
1638If the number exceeds 255 (uint8_t maximum value) the variable is set to 255.
1641 REGISTER_VARIABLE("nKLMMultistripHitsFWDEndcap", nKLMMultistripHitsFWDEndcap, R
"DOC(
1642[Eventbased] Returns the number of multi-strip hits in the KLM forward endcap.
1645 REGISTER_VARIABLE("nKLMMultistripHitsBarrel", nKLMMultistripHitsBarrel, R
"DOC(
1646[Eventbased] Returns the number of multi-strip hits in the KLM barrel.
1649 REGISTER_VARIABLE("nKLMMultistripHitsBWDEndcap", nKLMMultistripHitsBWDEndcap, R
"DOC(
1650[Eventbased] Returns the number of multi-strip hits in the KLM backward endcap.
1653 REGISTER_VARIABLE("nKLMMultistripHits", nKLMMultistripHits, R
"DOC(
1654[Eventbased] Returns the number of multi-strip hits in the KLM.
1657 REGISTER_VARIABLE("nECLShowersFWDEndcap", nECLShowersFWDEndcap, R
"DOC(
1658[Eventbased] Returns the number of ECLShowers in the forward endcap.
1661 REGISTER_VARIABLE("nECLShowersBarrel", nECLShowersBarrel, R
"DOC(
1662[Eventbased] Returns the number of ECLShowers in the barrel.
1665 REGISTER_VARIABLE("nECLShowersBWDEndcap", nECLShowersBWDEndcap, R
"DOC(
1666[Eventbased] Returns the number of ECLShowers in the backward endcap.
1669 REGISTER_VARIABLE("nECLShowers", nECLShowers, R
"DOC(
1670[Eventbased] Returns the number of ECLShowers.
1673 REGISTER_VARIABLE("nECLLocalMaximumsFWDEndcap", nECLLocalMaximumsFWDEndcap, R
"DOC(
1674[Eventbased] Returns the number of LocalMaximums in the ECL forward endcap.
1677 REGISTER_VARIABLE("nECLLocalMaximumsBarrel", nECLLocalMaximumsBarrel, R
"DOC(
1678[Eventbased] Returns the number of LocalMaximums in the ECL barrel.
1681 REGISTER_VARIABLE("nECLLocalMaximumsBWDEndcap", nECLLocalMaximumsBWDEndcap, R
"DOC(
1682[Eventbased] Returns the number of LocalMaximums in the ECL backward endcap.
1685 REGISTER_VARIABLE("nECLLocalMaximums", nECLLocalMaximums, R
"DOC(
1686[Eventbased] Returns the number of LocalMaximums in the ECL.
1689 REGISTER_VARIABLE("nECLTriggerCellsFWDEndcap", nECLTriggerCellsFWDEndcap, R
"DOC(
1690[Eventbased] Returns the number of ECL trigger cells above 100 MeV in the forward endcap.
1693 REGISTER_VARIABLE("nECLTriggerCellsBarrel", nECLTriggerCellsBarrel, R
"DOC(
1694[Eventbased] Returns the number of ECL trigger cells above 100 MeV in the barrel.
1697 REGISTER_VARIABLE("nECLTriggerCellsBWDEndcap", nECLTriggerCellsBWDEndcap, R
"DOC(
1698[Eventbased] Returns the number of ECL trigger cells above 100 MeV in the backward endcap.
1701 REGISTER_VARIABLE("nECLTriggerCells", nECLTriggerCells, R
"DOC(
1702[Eventbased] Returns the number of ECL trigger cells above 100 MeV.
1705 REGISTER_VARIABLE("eclClusterOnlyInvariantMass", eclClusterOnlyInvariantMass, R
"DOC(
1706[Expert] The invariant mass calculated from all ECLCluster daughters (i.e. photons) and
1707cluster-matched tracks using the cluster 4-momenta.
1709Used for ECL-based dark sector physics and debugging track-cluster matching.
1711)DOC","GeV/:math:`\\text{c}^2`");
1713 REGISTER_METAVARIABLE("photonHasOverlap(cutString, photonlistname, tracklistname)", photonHasOverlap, R"DOC(
1714 Returns true if the connected ECL region of the particle's cluster is shared by another particle's cluster.
1715 Neutral and charged cluster are considered.
1716 A cut string can be provided to ignore cluster that do not satisfy the given criteria.
1717 By default, the ParticleList ``gamma:all`` is used for the check of neutral ECL cluster,
1718 and the ParticleList ``e-:all`` for the check of charged ECL cluster.
1719 However, one can customize the name of the ParticleLists via additional arguments.
1720 If no argument or only a cut string is provided and ``gamma:all`` or ``e-:all`` does not exist
1721 or if the variable is requested for a particle that is not a photon, NaN is returned.
1722 )DOC", Manager::VariableDataType::c_double);
1724 REGISTER_VARIABLE("clusterUncorrE", eclClusterUncorrectedE, R
"DOC(
1725[Expert] [Calibration] Returns ECL cluster's uncorrected energy. That is, before leakage corrections.
1726This variable should only be used for study of the ECL. Please see :b2:var:`clusterE`.
1730 REGISTER_VARIABLE("distanceToMcKl",distanceToMcKl,R"DOC(
1731Returns the distance to the nearest truth KL particle, extrapolated to the cluster radius. To use
1732this variable, it is required to run getNeutralHadronGeomMatches function. Optionally, it can return
1733negative values to indicate that the ECL cluster should be removed from the analysis to correct for data
1734to MC difference in KL efficiency.
1738 REGISTER_VARIABLE(
"distanceToMcNeutron",distanceToMcNeutron,R
"DOC(
1739Returns the distance to the nearest truth (anti)neutron, extrapolated to the cluster radius. To use
1740this variable, it is required to run getNeutralHadronGeomMatches function. Optionally, it can return
1741negative values to indicate that the ECL cluster should be removed from the analysis to correct for data
1742to MC difference in KL efficiency.
1746 REGISTER_VARIABLE(
"mdstIndexMcKl",mdstIndexMcKl,R
"DOC(
1747 Returns the mdst index of the nearest truth KL, extrapolated to the cluster radius, if it is
1748 within the matching cone. To use this variable, it is required to run getNeutralHadronGeomMatches function.
1751 REGISTER_VARIABLE("mdstIndexMcNeutron",mdstIndexMcNeutron,R
"DOC(
1752 Returns the mdst index of the nearest truth (anti)neutron, extrapolated to the cluster radius, if it is
1753 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.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.