11 #include <analysis/variables/MCTruthVariables.h>
12 #include <analysis/VariableManager/Manager.h>
13 #include <analysis/dataobjects/Particle.h>
14 #include <analysis/dataobjects/TauPairDecay.h>
15 #include <analysis/utility/MCMatching.h>
16 #include <analysis/utility/ReferenceFrame.h>
18 #include <mdst/dataobjects/MCParticle.h>
19 #include <mdst/dataobjects/ECLCluster.h>
21 #include <framework/datastore/StoreArray.h>
22 #include <framework/datastore/StoreObjPtr.h>
23 #include <framework/dataobjects/EventMetaData.h>
24 #include <framework/gearbox/Const.h>
25 #include <framework/logging/Logger.h>
26 #include <framework/core/Environment.h>
27 #include <framework/database/DBObjPtr.h>
28 #include <framework/dbobjects/BeamParameters.h>
39 double isSignal(
const Particle* part)
41 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
42 if (mcparticle ==
nullptr)
43 return std::numeric_limits<double>::quiet_NaN();
50 double isSignalAcceptWrongFSPs(
const Particle* part)
52 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
53 if (mcparticle ==
nullptr)
54 return std::numeric_limits<double>::quiet_NaN();
58 status &= (~MCMatching::c_MisID);
59 status &= (~MCMatching::c_AddedWrongParticle);
64 double isPrimarySignal(
const Particle* part)
66 if (isSignal(part) > 0.5 and particleMCPrimaryParticle(part) > 0.5)
72 double isMisidentified(
const Particle* part)
74 const MCParticle* mcp = part->getRelatedTo<MCParticle>();
75 if (!mcp)
return std::numeric_limits<double>::quiet_NaN();
80 double isWrongCharge(
const Particle* part)
82 const MCParticle* mcp = part->getRelatedTo<MCParticle>();
83 if (!mcp)
return std::numeric_limits<double>::quiet_NaN();
84 int pch = part->getCharge(),
85 mch = mcp->getCharge();
86 return double((pch != mch));
89 double isCloneTrack(
const Particle* particle)
93 return std::numeric_limits<double>::quiet_NaN();
95 auto mcpww = particle->getRelatedToWithWeight<MCParticle>();
96 if (!mcpww.first)
return std::numeric_limits<double>::quiet_NaN();
97 return double(mcpww.second < 0);
100 double isOrHasCloneTrack(
const Particle* particle)
103 std::queue<const Particle*> qq;
105 while (!qq.empty()) {
108 if (isCloneTrack(d) == 1.0)
return 1.0;
109 size_t nDau = d->getNDaughters();
110 for (
size_t iDau = 0; iDau < nDau; iDau++)
111 qq.push(d->getDaughter(iDau));
116 double genNthMotherPDG(
const Particle* part,
const std::vector<double>& args)
118 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
119 if (mcparticle ==
nullptr)
122 unsigned int nLevels;
128 const MCParticle* curMCParticle = mcparticle;
129 for (
unsigned int i = 0; i <= nLevels; i++) {
130 const MCParticle* curMCMother = curMCParticle->getMother();
131 if (curMCMother ==
nullptr)
133 curMCParticle = curMCMother;
135 int m_pdg = curMCParticle->getPDG();
139 double genNthMotherIndex(
const Particle* part,
const std::vector<double>& args)
141 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
142 if (mcparticle ==
nullptr)
145 unsigned int nLevels;
151 const MCParticle* curMCParticle = mcparticle;
152 for (
unsigned int i = 0; i <= nLevels; i++) {
153 const MCParticle* curMCMother = curMCParticle->getMother();
154 if (curMCMother ==
nullptr)
156 curMCParticle = curMCMother;
162 double genMotherPDG(
const Particle* part)
164 const std::vector<double> args = {};
165 return genNthMotherPDG(part, args);
168 double genMotherP(
const Particle* part)
170 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
171 if (mcparticle ==
nullptr)
172 return std::numeric_limits<double>::quiet_NaN();
174 const MCParticle* mcmother = mcparticle->getMother();
175 if (mcmother ==
nullptr)
176 return std::numeric_limits<double>::quiet_NaN();
178 double p = mcmother->getMomentum().Mag();
182 double genMotherIndex(
const Particle* part)
184 const std::vector<double> args = {};
185 return genNthMotherIndex(part, args);
188 double genParticleIndex(
const Particle* part)
190 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
198 double isSignalAcceptMissingNeutrino(
const Particle* part)
200 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
201 if (mcparticle ==
nullptr)
202 return std::numeric_limits<double>::quiet_NaN();
206 status &= (~MCMatching::c_MissNeutrino);
211 double isSignalAcceptMissingMassive(
const Particle* part)
213 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
214 if (mcparticle ==
nullptr)
215 return std::numeric_limits<double>::quiet_NaN();
219 status &= (~MCMatching::c_MissMassiveParticle);
220 status &= (~MCMatching::c_MissKlong);
225 double isSignalAcceptMissingGamma(
const Particle* part)
227 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
228 if (mcparticle ==
nullptr)
229 return std::numeric_limits<double>::quiet_NaN();
233 status &= (~MCMatching::c_MissGamma);
238 double isSignalAcceptMissing(
const Particle* part)
240 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
241 if (mcparticle ==
nullptr)
242 return std::numeric_limits<double>::quiet_NaN();
246 status &= (~MCMatching::c_MissGamma);
247 status &= (~MCMatching::c_MissMassiveParticle);
248 status &= (~MCMatching::c_MissKlong);
249 status &= (~MCMatching::c_MissNeutrino);
254 double isSignalAcceptBremsPhotons(
const Particle* part)
256 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
257 if (mcparticle ==
nullptr)
262 status &= (~MCMatching::c_AddedRecoBremsPhoton);
267 double particleMCMatchPDGCode(
const Particle* part)
269 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
270 if (mcparticle ==
nullptr)
271 return std::numeric_limits<double>::quiet_NaN();
273 return mcparticle->getPDG();
276 double particleMCErrors(
const Particle* part)
281 double particleNumberOfMCMatch(
const Particle* particle)
283 RelationVector<MCParticle> mcRelations =
284 particle->getRelationsTo<MCParticle>();
285 return double(mcRelations.size());
288 double particleMCMatchWeight(
const Particle* particle)
290 auto relWithWeight = particle->getRelatedToWithWeight<MCParticle>();
292 if (relWithWeight.first) {
293 return relWithWeight.second;
295 return std::numeric_limits<double>::quiet_NaN();
299 double particleMCMatchDecayTime(
const Particle* part)
301 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
302 if (mcparticle ==
nullptr)
303 return std::numeric_limits<double>::quiet_NaN();
305 return mcparticle->getDecayTime();
308 double particleMCMatchLifeTime(
const Particle* part)
310 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
311 if (mcparticle ==
nullptr)
312 return std::numeric_limits<double>::quiet_NaN();
314 return mcparticle->getLifetime();
317 double particleMCMatchPX(
const Particle* part)
319 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
320 if (mcparticle ==
nullptr)
321 return std::numeric_limits<double>::quiet_NaN();
324 TLorentzVector mcpP4 = mcparticle->get4Vector();
325 return frame.getMomentum(mcpP4).Px();
328 double particleMCMatchPY(
const Particle* part)
330 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
331 if (mcparticle ==
nullptr)
332 return std::numeric_limits<double>::quiet_NaN();
335 TLorentzVector mcpP4 = mcparticle->get4Vector();
336 return frame.getMomentum(mcpP4).Py();
339 double particleMCMatchPZ(
const Particle* part)
341 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
342 if (mcparticle ==
nullptr)
343 return std::numeric_limits<double>::quiet_NaN();
346 TLorentzVector mcpP4 = mcparticle->get4Vector();
347 return frame.getMomentum(mcpP4).Pz();
350 double particleMCMatchPT(
const Particle* part)
352 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
353 if (mcparticle ==
nullptr)
354 return std::numeric_limits<double>::quiet_NaN();
357 TLorentzVector mcpP4 = mcparticle->get4Vector();
358 return frame.getMomentum(mcpP4).Pt();
361 double particleMCMatchE(
const Particle* part)
363 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
364 if (mcparticle ==
nullptr)
365 return std::numeric_limits<double>::quiet_NaN();
368 TLorentzVector mcpP4 = mcparticle->get4Vector();
369 return frame.getMomentum(mcpP4).E();
372 double particleMCMatchP(
const Particle* part)
374 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
375 if (mcparticle ==
nullptr)
376 return std::numeric_limits<double>::quiet_NaN();
379 TLorentzVector mcpP4 = mcparticle->get4Vector();
380 return frame.getMomentum(mcpP4).P();
383 double particleMCMatchTheta(
const Particle* part)
385 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
386 if (mcparticle ==
nullptr)
387 return std::numeric_limits<double>::quiet_NaN();
390 TLorentzVector mcpP4 = mcparticle->get4Vector();
391 return frame.getMomentum(mcpP4).Theta();
394 double particleMCMatchPhi(
const Particle* part)
396 const MCParticle* mcparticle = part->getRelatedTo<MCParticle>();
397 if (mcparticle ==
nullptr)
398 return std::numeric_limits<double>::quiet_NaN();
401 TLorentzVector mcpP4 = mcparticle->get4Vector();
402 return frame.getMomentum(mcpP4).Phi();
405 double particleMCRecoilMass(
const Particle* part)
407 StoreArray<MCParticle> mcparticles;
408 if (mcparticles.getEntries() < 1)
409 return std::numeric_limits<double>::quiet_NaN();
411 TLorentzVector pInitial = mcparticles[0]->get4Vector();
412 TLorentzVector pDaughters;
413 const std::vector<Particle*> daughters = part->getDaughters();
414 for (
auto daughter : daughters) {
415 const MCParticle* mcD = daughter->getRelatedTo<MCParticle>();
417 return std::numeric_limits<double>::quiet_NaN();
419 pDaughters += mcD->get4Vector();
422 return (pInitial - pDaughters).M();
425 double mcParticleSecondaryPhysicsProcess(
const Particle* p)
427 const MCParticle* mcp = p->getMCParticle();
429 return mcp->getSecondaryPhysicsProcess();
431 return std::numeric_limits<double>::quiet_NaN();
435 double mcParticleStatus(
const Particle* p)
437 const MCParticle* mcp = p->getMCParticle();
439 return mcp->getStatus();
441 return std::numeric_limits<double>::quiet_NaN();
445 double particleMCPrimaryParticle(
const Particle* p)
447 const MCParticle* mcp = p->getMCParticle();
450 if (mcp->hasStatus(bitmask))
455 return std::numeric_limits<double>::quiet_NaN();
459 double particleMCVirtualParticle(
const Particle* p)
461 const MCParticle* mcp = p->getMCParticle();
464 if (mcp->hasStatus(bitmask))
469 return std::numeric_limits<double>::quiet_NaN();
473 double particleMCInitialParticle(
const Particle* p)
475 const MCParticle* mcp = p->getMCParticle();
478 if (mcp->hasStatus(bitmask))
483 return std::numeric_limits<double>::quiet_NaN();
487 double particleMCISRParticle(
const Particle* p)
489 const MCParticle* mcp = p->getMCParticle();
492 if (mcp->hasStatus(bitmask))
497 return std::numeric_limits<double>::quiet_NaN();
501 double particleMCFSRParticle(
const Particle* p)
503 const MCParticle* mcp = p->getMCParticle();
506 if (mcp->hasStatus(bitmask))
511 return std::numeric_limits<double>::quiet_NaN();
515 double particleMCPhotosParticle(
const Particle* p)
517 const MCParticle* mcp = p->getMCParticle();
520 if (mcp->hasStatus(bitmask))
525 return std::numeric_limits<double>::quiet_NaN();
529 double generatorEventWeight(
const Particle*)
531 StoreObjPtr<EventMetaData> evtMetaData;
533 return std::numeric_limits<double>::quiet_NaN();
534 return evtMetaData->getGeneratedWeight();
537 int tauPlusMcMode(
const Particle*)
539 StoreObjPtr<TauPairDecay> tauDecay;
541 B2WARNING(
"Cannot find tau decay ID, did you forget to run TauDecayMarkerModule?");
542 return std::numeric_limits<int>::quiet_NaN();
544 int tauPlusId = tauDecay->getTauPlusIdMode();
548 int tauMinusMcMode(
const Particle*)
550 StoreObjPtr<TauPairDecay> tauDecay;
552 B2WARNING(
"Cannot find tau decay ID, did you forget to run TauDecayMarkerModule?");
553 return std::numeric_limits<int>::quiet_NaN();
555 int tauMinusId = tauDecay->getTauMinusIdMode();
559 int tauPlusMcProng(
const Particle*)
561 StoreObjPtr<TauPairDecay> tauDecay;
563 B2WARNING(
"Cannot find tau prong, did you forget to run TauDecayMarkerModule?");
564 return std::numeric_limits<int>::quiet_NaN();
566 int tauPlusMcProng = tauDecay->getTauPlusMcProng();
567 return tauPlusMcProng;
570 int tauMinusMcProng(
const Particle*)
572 StoreObjPtr<TauPairDecay> tauDecay;
574 B2WARNING(
"Cannot find tau prong, did you forget to run TauDecayMarkerModule?");
575 return std::numeric_limits<int>::quiet_NaN();
577 int tauMinusMcProng = tauDecay->getTauMinusMcProng();
578 return tauMinusMcProng;
583 double isReconstructible(
const Particle* p)
585 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
587 const MCParticle* mcp = p->getRelated<MCParticle>();
589 return std::numeric_limits<float>::quiet_NaN();
593 if (abs(mcp->getCharge()) > 0)
599 double seenInPXD(
const Particle* p)
601 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
603 const MCParticle* mcp = p->getRelated<MCParticle>();
605 return std::numeric_limits<float>::quiet_NaN();
606 return (
double)mcp->hasSeenInDetector(Const::PXD);
609 double seenInSVD(
const Particle* p)
611 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
613 const MCParticle* mcp = p->getRelated<MCParticle>();
615 return std::numeric_limits<float>::quiet_NaN();
616 return (
double)mcp->hasSeenInDetector(Const::SVD);
619 double seenInCDC(
const Particle* p)
621 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
623 const MCParticle* mcp = p->getRelated<MCParticle>();
625 return std::numeric_limits<float>::quiet_NaN();
626 return (
double)mcp->hasSeenInDetector(Const::CDC);
629 double seenInTOP(
const Particle* p)
631 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
633 const MCParticle* mcp = p->getRelated<MCParticle>();
635 return std::numeric_limits<float>::quiet_NaN();
636 return (
double)mcp->hasSeenInDetector(Const::TOP);
639 double seenInECL(
const Particle* p)
641 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
643 const MCParticle* mcp = p->getRelated<MCParticle>();
645 return std::numeric_limits<float>::quiet_NaN();
646 return (
double)mcp->hasSeenInDetector(Const::ECL);
649 double seenInARICH(
const Particle* p)
651 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
653 const MCParticle* mcp = p->getRelated<MCParticle>();
655 return std::numeric_limits<float>::quiet_NaN();
656 return (
double)mcp->hasSeenInDetector(Const::ARICH);
659 double seenInKLM(
const Particle* p)
661 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
663 const MCParticle* mcp = p->getRelated<MCParticle>();
665 return std::numeric_limits<float>::quiet_NaN();
666 return (
double)mcp->hasSeenInDetector(Const::KLM);
669 int genNStepsToDaughter(
const Particle* p,
const std::vector<double>& arguments)
671 if (arguments.size() != 1)
672 B2FATAL(
"Wrong number of arguments for genNStepsToDaughter");
674 const MCParticle* mcp = p->getRelated<MCParticle>();
676 B2WARNING(
"No MCParticle is associated to the particle");
677 return std::numeric_limits<int>::quiet_NaN();
680 int nChildren = p->getNDaughters();
681 if (arguments[0] >= nChildren) {
682 return std::numeric_limits<int>::quiet_NaN();
685 const Particle* daugP = p->getDaughter(arguments[0]);
686 const MCParticle* daugMCP = daugP->
getRelated<MCParticle>();
690 B2WARNING(
"No MCParticle is associated to the i-th daughter");
691 return std::numeric_limits<int>::quiet_NaN();
694 if (nChildren == 1) {
697 int motherIndex = mcp->getIndex();
699 std::vector<int> genMothers;
701 auto match = std::find(genMothers.begin(), genMothers.end(), motherIndex);
703 return match - genMothers.begin();
707 int genNMissingDaughter(
const Particle* p,
const std::vector<double>& arguments)
709 if (arguments.size() < 1)
710 B2FATAL(
"Wrong number of arguments for genNMissingDaughter");
712 const std::vector<int> PDGcodes(arguments.begin(), arguments.end());
714 const MCParticle* mcp = p->getRelated<MCParticle>();
716 B2WARNING(
"No MCParticle is associated to the particle");
717 return std::numeric_limits<int>::quiet_NaN();
723 double getHEREnergy(
const Particle*)
725 static DBObjPtr<BeamParameters> beamParamsDB;
726 return (beamParamsDB->getHER()).E();
729 double getLEREnergy(
const Particle*)
731 static DBObjPtr<BeamParameters> beamParamsDB;
732 return (beamParamsDB->getLER()).E();
735 double getCrossingAngle(
const Particle*)
737 static DBObjPtr<BeamParameters> beamParamsDB;
738 return (beamParamsDB->getHER()).Vect().Angle(-1.0 * (beamParamsDB->getLER()).Vect());
741 double particleClusterMatchWeight(
const Particle* particle)
749 const MCParticle* matchedToParticle = particle->getMCParticle();
750 if (!matchedToParticle)
return std::numeric_limits<float>::quiet_NaN();
751 int matchedToIndex = matchedToParticle->getArrayIndex();
753 const ECLCluster* cluster = particle->getECLCluster();
754 if (!cluster)
return std::numeric_limits<float>::quiet_NaN();
756 auto mcps = cluster->getRelationsTo<MCParticle>();
757 if (mcps.size() == 0)
return std::numeric_limits<float>::quiet_NaN();
759 for (
unsigned int i = 0; i < mcps.size(); ++i)
760 if (mcps[i]->getArrayIndex() == matchedToIndex)
761 return mcps.weight(i);
766 double particleClusterBestMCMatchWeight(
const Particle* particle)
778 const ECLCluster* cluster = particle->getECLCluster();
779 if (!cluster)
return std::numeric_limits<float>::quiet_NaN();
784 auto mcps = cluster->getRelationsTo<MCParticle>();
785 if (mcps.size() == 0)
return std::numeric_limits<float>::quiet_NaN();
787 std::vector<double> weights;
788 for (
unsigned int i = 0; i < mcps.size(); ++i)
789 weights.emplace_back(mcps.weight(i));
792 std::sort(weights.begin(), weights.end());
793 std::reverse(weights.begin(), weights.end());
797 double particleClusterBestMCPDGCode(
const Particle* particle)
807 const ECLCluster* cluster = particle->getECLCluster();
808 if (!cluster)
return std::numeric_limits<float>::quiet_NaN();
810 auto mcps = cluster->getRelationsTo<MCParticle>();
811 if (mcps.size() == 0)
return std::numeric_limits<float>::quiet_NaN();
813 std::vector<std::pair<double, int>> weightsAndIndices;
814 for (
unsigned int i = 0; i < mcps.size(); ++i)
815 weightsAndIndices.emplace_back(mcps.weight(i), i);
819 weightsAndIndices.begin(), weightsAndIndices.end(),
820 [](
const std::pair<double, int>& l,
const std::pair<double, int>& r) {
821 return l.first > r.first;
823 return mcps.object(weightsAndIndices[0].second)->getPDG();
826 double isMC(
const Particle*)
831 VARIABLE_GROUP(
"MC matching and MC truth");
832 REGISTER_VARIABLE(
"isSignal", isSignal,
833 "1.0 if Particle is correctly reconstructed (SIGNAL), 0.0 otherwise. \n"
834 "It behaves according to DecayStringGrammar.");
835 REGISTER_VARIABLE(
"isSignalAcceptWrongFSPs", isSignalAcceptWrongFSPs,
836 "1.0 if Particle is almost correctly reconstructed (SIGNAL), 0.0 otherwise.\n"
837 "Misidentification of charged FSP is allowed.");
838 REGISTER_VARIABLE(
"isPrimarySignal", isPrimarySignal,
839 "1.0 if Particle is correctly reconstructed (SIGNAL) and primary, 0.0 otherwise");
840 REGISTER_VARIABLE(
"isSignalAcceptBremsPhotons", isSignalAcceptBremsPhotons,
841 "1.0 if Particle is correctly reconstructed (SIGNAL), 0.0 otherwise.\n"
842 "Particles with gamma daughters attached through the bremsstrahlung recovery modules are allowed.");
843 REGISTER_VARIABLE(
"genMotherPDG", genMotherPDG,
844 "Check the PDG code of a particles MC mother particle");
845 REGISTER_VARIABLE(
"genMotherPDG(i)", genNthMotherPDG,
846 "Check the PDG code of a particles n-th MC mother particle by providing an argument. 0 is first mother, 1 is grandmother etc. :noindex:");
848 REGISTER_VARIABLE(
"genMotherID", genMotherIndex,
849 "Check the array index of a particles generated mother");
850 REGISTER_VARIABLE(
"genMotherID(i)", genNthMotherIndex,
851 "Check the array index of a particle n-th MC mother particle by providing an argument. 0 is first mother, 1 is grandmother etc. :noindex:");
856 REGISTER_VARIABLE(
"genMotherP", genMotherP,
857 "Generated momentum of a particles MC mother particle");
858 REGISTER_VARIABLE(
"genParticleID", genParticleIndex,
859 "Check the array index of a particle's related MCParticle");
860 REGISTER_VARIABLE(
"isSignalAcceptMissingNeutrino",
861 isSignalAcceptMissingNeutrino,
862 "same as isSignal, but also accept missing neutrino");
863 REGISTER_VARIABLE(
"isSignalAcceptMissingMassive",
864 isSignalAcceptMissingMassive,
865 "same as isSignal, but also accept missing massive particle");
866 REGISTER_VARIABLE(
"isSignalAcceptMissingGamma",
867 isSignalAcceptMissingGamma,
868 "same as isSignal, but also accept missing gamma, such as B -> K* gamma, pi0 -> gamma gamma");
869 REGISTER_VARIABLE(
"isSignalAcceptMissing",
870 isSignalAcceptMissing,
871 "same as isSignal, but also accept missing particle");
872 REGISTER_VARIABLE(
"isMisidentified", isMisidentified,
873 "return 1 if the particle is misidentified: one or more of the final state particles have the wrong PDG code assignment (including wrong charge), 0 in all other cases.");
874 REGISTER_VARIABLE(
"isWrongCharge", isWrongCharge,
875 "return 1 if the charge of the particle is wrongly assigned, 0 in all other cases");
876 REGISTER_VARIABLE(
"isCloneTrack", isCloneTrack,
877 "Return 1 if the charged final state particle comes from a cloned track, 0 if not a clone. Returns NAN if neutral, composite, or MCParticle not found (like for data or if not MCMatched)");
878 REGISTER_VARIABLE(
"isOrHasCloneTrack", isOrHasCloneTrack,
879 "Return 1 if the particle is a clone track or has a clone track as a daughter, 0 otherwise.");
880 REGISTER_VARIABLE(
"mcPDG", particleMCMatchPDGCode,
881 "The PDG code of matched MCParticle, 0 if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
882 REGISTER_VARIABLE(
"mcErrors", particleMCErrors,
883 "The bit pattern indicating the quality of MC match (see MCMatching::MCErrorFlags)");
884 REGISTER_VARIABLE(
"mcMatchWeight", particleMCMatchWeight,
885 "The weight of the Particle -> MCParticle relation (only for the first Relation = largest weight).");
886 REGISTER_VARIABLE(
"nMCMatches", particleNumberOfMCMatch,
887 "The number of relations of this Particle to MCParticle.");
888 REGISTER_VARIABLE(
"mcDecayTime", particleMCMatchDecayTime,
889 "The decay time of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
890 REGISTER_VARIABLE(
"mcLifeTime", particleMCMatchLifeTime,
891 "The life time of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
892 REGISTER_VARIABLE(
"mcPX", particleMCMatchPX,
893 "The px of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
894 REGISTER_VARIABLE(
"mcPY", particleMCMatchPY,
895 "The py of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
896 REGISTER_VARIABLE(
"mcPZ", particleMCMatchPZ,
897 "The pz of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
898 REGISTER_VARIABLE(
"mcPT", particleMCMatchPT,
899 "The pt of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
900 REGISTER_VARIABLE(
"mcE", particleMCMatchE,
901 "The energy of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
902 REGISTER_VARIABLE(
"mcP", particleMCMatchP,
903 "The total momentum of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
904 REGISTER_VARIABLE(
"mcPhi", particleMCMatchPhi,
905 "The phi of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
906 REGISTER_VARIABLE(
"mcTheta", particleMCMatchTheta,
907 "The theta of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
908 REGISTER_VARIABLE(
"mcRecoilMass", particleMCRecoilMass,
909 "The mass recoiling against the particles attached as particle's daughters calculated using MC truth values.");
912 REGISTER_VARIABLE(
"mcSecPhysProc", mcParticleSecondaryPhysicsProcess,
913 "Returns the secondary physics process flag.");
914 REGISTER_VARIABLE(
"mcParticleStatus", mcParticleStatus,
915 "Returns status bits of related MCParticle or NaN if MCParticle relation is not set.");
916 REGISTER_VARIABLE(
"mcPrimary", particleMCPrimaryParticle,
917 "Returns 1 if Particle is related to primary MCParticle, 0 if Particle is related to non - primary MCParticle, "
918 "NaN if Particle is not related to MCParticle.");
919 REGISTER_VARIABLE(
"mcVirtual", particleMCVirtualParticle,
920 "Returns 1 if Particle is related to virtual MCParticle, 0 if Particle is related to non - virtual MCParticle, "
921 "NaN if Particle is not related to MCParticle.")
922 REGISTER_VARIABLE("mcInitial", particleMCInitialParticle,
923 "Returns 1 if Particle is related to initial MCParticle, 0 if Particle is related to non - initial MCParticle, "
924 "NaN if Particle is not related to MCParticle.")
925 REGISTER_VARIABLE("mcISR", particleMCISRParticle,
926 "Returns 1 if Particle is related to ISR MCParticle, 0 if Particle is related to non - ISR MCParticle, "
927 "NaN if Particle is not related to MCParticle.")
928 REGISTER_VARIABLE("mcFSR", particleMCFSRParticle,
929 "Returns 1 if Particle is related to FSR MCParticle, 0 if Particle is related to non - FSR MCParticle ,"
930 "NaN if Particle is not related to MCParticle.")
931 REGISTER_VARIABLE("mcPhotos", particleMCPhotosParticle,
932 "Returns 1 if Particle is related to Photos MCParticle, 0 if Particle is related to non - Photos MCParticle, "
933 "NaN if Particle is not related to MCParticle.")
934 REGISTER_VARIABLE("generatorEventWeight", generatorEventWeight,
935 "[Eventbased] Returns the event weight produced by the event generator")
937 REGISTER_VARIABLE("genNStepsToDaughter(i)", genNStepsToDaughter,
938 "Returns number of steps to i-th daughter from the particle at generator level. "
939 "NaN if no MCParticle is associated to the particle or i-th daughter. "
940 "NaN if i-th daughter does not exist.");
941 REGISTER_VARIABLE("genNMissingDaughter(PDG)", genNMissingDaughter,
942 "Returns the number of missing daughters having assigned PDG codes. "
943 "NaN if no MCParticle is associated to the particle.")
944 REGISTER_VARIABLE("Eher", getHEREnergy, R"DOC(
945 [Eventbased] The nominal HER energy used by the generator.
947 .. warning:: This variable does not make sense for data.
949 REGISTER_VARIABLE("Eler", getLEREnergy, R"DOC(
950 [Eventbased] The nominal LER energy used by the generator.
952 .. warning:: This variable does not make sense for data.
954 REGISTER_VARIABLE("XAngle", getCrossingAngle, R"DOC(
955 [Eventbased] The nominal beam crossing angle from generator level beam kinematics.
957 .. warning:: This variable does not make sense for data.
960 VARIABLE_GROUP("Generated tau decay information");
961 REGISTER_VARIABLE("tauPlusMCMode", tauPlusMcMode,
962 "Decay ID for the positive tau lepton in a tau pair generated event.")
963 REGISTER_VARIABLE("tauMinusMCMode", tauMinusMcMode,
964 "Decay ID for the negative tau lepton in a tau pair generated event.")
965 REGISTER_VARIABLE("tauPlusMCProng", tauPlusMcProng,
966 "Prong for the positive tau lepton in a tau pair generated event.")
967 REGISTER_VARIABLE("tauMinusMCProng", tauMinusMcProng,
968 "Prong for the negative tau lepton in a tau pair generated event.")
970 VARIABLE_GROUP("MC particle seen in subdetectors");
971 REGISTER_VARIABLE("isReconstructible", isReconstructible,
972 "checks charged particles were seen in the SVD and neutrals in the ECL, returns 1.0 if so, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
973 REGISTER_VARIABLE("seenInPXD", seenInPXD,
974 "returns 1.0 if the MC particle was seen in the PXD, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
975 REGISTER_VARIABLE("seenInSVD", seenInSVD,
976 "returns 1.0 if the MC particle was seen in the SVD, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
977 REGISTER_VARIABLE("seenInCDC", seenInCDC,
978 "returns 1.0 if the MC particle was seen in the CDC, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
979 REGISTER_VARIABLE("seenInTOP", seenInTOP,
980 "returns 1.0 if the MC particle was seen in the TOP, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
981 REGISTER_VARIABLE("seenInECL", seenInECL,
982 "returns 1.0 if the MC particle was seen in the ECL, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
983 REGISTER_VARIABLE("seenInARICH", seenInARICH,
984 "returns 1.0 if the MC particle was seen in the ARICH, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
985 REGISTER_VARIABLE("seenInKLM", seenInKLM,
986 "returns 1.0 if the MC particle was seen in the KLM, 0.0 if not, -1.0 for composite particles. Useful for generator studies, not for reconstructed particles.");
988 VARIABLE_GROUP("MC Matching for ECLClusters");
989 REGISTER_VARIABLE("clusterMCMatchWeight", particleClusterMatchWeight,
990 "Returns the weight of the ECLCluster -> MCParticle relation for the MCParticle matched to the particle. "
991 "Returns NaN if: no cluster is related to the particle, the particle is not MC matched, or if there are no mcmatches for the cluster. "
992 "Returns -1 if the cluster *was* matched to particles, but not the match of the particle provided.");
993 REGISTER_VARIABLE("clusterBestMCMatchWeight", particleClusterBestMCMatchWeight,
994 "returns the weight of the ECLCluster -> MCParticle relation for the relation with the largest weight.");
995 REGISTER_VARIABLE("clusterBestMCPDG", particleClusterBestMCPDGCode,
996 "returns the PDG code of the MCParticle for the ECLCluster -> MCParticle relation with the largest weight.");
997 REGISTER_VARIABLE("isMC", isMC,
998 "[Eventbased] Returns 1 if run on MC and 0 for data.");