9 #include <analysis/variables/MCTruthVariables.h>
10 #include <analysis/VariableManager/Manager.h>
11 #include <analysis/dataobjects/Particle.h>
12 #include <analysis/dataobjects/TauPairDecay.h>
13 #include <analysis/utility/MCMatching.h>
14 #include <analysis/utility/ReferenceFrame.h>
16 #include <mdst/dataobjects/MCParticle.h>
17 #include <mdst/dataobjects/ECLCluster.h>
19 #include <framework/datastore/StoreArray.h>
20 #include <framework/datastore/StoreObjPtr.h>
21 #include <framework/dataobjects/EventMetaData.h>
22 #include <framework/gearbox/Const.h>
23 #include <framework/logging/Logger.h>
24 #include <framework/database/DBObjPtr.h>
25 #include <framework/dbobjects/BeamParameters.h>
36 static const double realNaN = std::numeric_limits<double>::quiet_NaN();
37 static const int intNaN = std::numeric_limits<int>::quiet_NaN();
40 double isSignal(
const Particle* part)
42 const MCParticle* mcparticle = part->getMCParticle();
43 if (!mcparticle)
return realNaN;
49 double isSignalAcceptWrongFSPs(
const Particle* part)
51 const MCParticle* mcparticle = part->getMCParticle();
52 if (!mcparticle)
return realNaN;
56 status &= (~MCMatching::c_MisID);
57 status &= (~MCMatching::c_AddedWrongParticle);
62 double isPrimarySignal(
const Particle* part)
64 return (isSignal(part) > 0.5 and particleMCPrimaryParticle(part) > 0.5);
67 double isMisidentified(
const Particle* part)
69 const MCParticle* mcp = part->getMCParticle();
75 double isWrongCharge(
const Particle* part)
77 const MCParticle* mcp = part->getMCParticle();
79 return (part->getCharge() != mcp->getCharge());
82 double isCloneTrack(
const Particle* particle)
88 const auto mcpww = particle->getRelatedToWithWeight<MCParticle>();
89 if (!mcpww.first)
return realNaN;
90 return (mcpww.second < 0);
93 double isOrHasCloneTrack(
const Particle* particle)
96 std::queue<const Particle*> qq;
99 const auto d = qq.front();
101 if (isCloneTrack(d) == 1.0)
return 1.0;
102 size_t nDau = d->getNDaughters();
103 for (
size_t iDau = 0; iDau < nDau; ++iDau)
104 qq.push(d->getDaughter(iDau));
109 double genNthMotherPDG(
const Particle* part,
const std::vector<double>& args)
111 const MCParticle* mcparticle = part->getMCParticle();
112 if (!mcparticle)
return 0.0;
114 unsigned int nLevels = args.empty() ? 0 : args[0];
116 const MCParticle* curMCParticle = mcparticle;
117 for (
unsigned int i = 0; i <= nLevels; ++i) {
118 const MCParticle* curMCMother = curMCParticle->getMother();
119 if (!curMCMother)
return 0.0;
120 curMCParticle = curMCMother;
122 return curMCParticle->getPDG();
125 double genNthMotherIndex(
const Particle* part,
const std::vector<double>& args)
127 const MCParticle* mcparticle = part->getMCParticle();
128 if (!mcparticle)
return 0.0;
130 unsigned int nLevels = args.empty() ? 0 : args[0];
132 const MCParticle* curMCParticle = mcparticle;
133 for (
unsigned int i = 0; i <= nLevels; ++i) {
134 const MCParticle* curMCMother = curMCParticle->getMother();
135 if (!curMCMother)
return 0.0;
136 curMCParticle = curMCMother;
141 double genMotherPDG(
const Particle* part)
143 return genNthMotherPDG(part, {});
146 double genMotherP(
const Particle* part)
148 const MCParticle* mcparticle = part->getMCParticle();
149 if (!mcparticle)
return realNaN;
151 const MCParticle* mcmother = mcparticle->getMother();
154 return mcmother->getMomentum().Mag();
157 double genMotherIndex(
const Particle* part)
159 return genNthMotherIndex(part, {});
162 double genParticleIndex(
const Particle* part)
164 const MCParticle* mcparticle = part->getMCParticle();
165 if (!mcparticle)
return realNaN;
166 return mcparticle->getArrayIndex();
169 double isSignalAcceptMissingNeutrino(
const Particle* part)
171 const MCParticle* mcparticle = part->getMCParticle();
172 if (!mcparticle)
return realNaN;
176 status &= (~MCMatching::c_MissNeutrino);
181 double isSignalAcceptMissingMassive(
const Particle* part)
183 const MCParticle* mcparticle = part->getMCParticle();
184 if (!mcparticle)
return realNaN;
188 status &= (~MCMatching::c_MissMassiveParticle);
189 status &= (~MCMatching::c_MissKlong);
194 double isSignalAcceptMissingGamma(
const Particle* part)
196 const MCParticle* mcparticle = part->getMCParticle();
197 if (!mcparticle)
return realNaN;
201 status &= (~MCMatching::c_MissGamma);
206 double isSignalAcceptMissing(
const Particle* part)
208 const MCParticle* mcparticle = part->getMCParticle();
209 if (!mcparticle)
return realNaN;
213 status &= (~MCMatching::c_MissGamma);
214 status &= (~MCMatching::c_MissMassiveParticle);
215 status &= (~MCMatching::c_MissKlong);
216 status &= (~MCMatching::c_MissNeutrino);
221 double isSignalAcceptBremsPhotons(
const Particle* part)
223 const MCParticle* mcparticle = part->getMCParticle();
224 if (!mcparticle)
return realNaN;
228 status &= (~MCMatching::c_AddedRecoBremsPhoton);
233 double particleMCMatchPDGCode(
const Particle* part)
235 const MCParticle* mcparticle = part->getMCParticle();
236 if (!mcparticle)
return realNaN;
237 return mcparticle->getPDG();
240 double particleMCErrors(
const Particle* part)
245 double particleNumberOfMCMatch(
const Particle* particle)
247 RelationVector<MCParticle> mcRelations = particle->getRelationsTo<MCParticle>();
248 return (mcRelations.size());
251 double particleMCMatchWeight(
const Particle* particle)
253 auto relWithWeight = particle->getRelatedToWithWeight<MCParticle>();
254 if (!relWithWeight.first)
return realNaN;
255 return relWithWeight.second;
258 double particleMCMatchDecayTime(
const Particle* part)
260 const MCParticle* mcparticle = part->getMCParticle();
261 if (!mcparticle)
return realNaN;
262 return mcparticle->getDecayTime();
265 double particleMCMatchLifeTime(
const Particle* part)
267 const MCParticle* mcparticle = part->getMCParticle();
268 if (!mcparticle)
return realNaN;
269 return mcparticle->getLifetime();
272 double particleMCMatchPX(
const Particle* part)
274 const MCParticle* mcparticle = part->getMCParticle();
275 if (!mcparticle)
return realNaN;
278 TLorentzVector mcpP4 = mcparticle->get4Vector();
279 return frame.getMomentum(mcpP4).Px();
282 double particleMCMatchPY(
const Particle* part)
284 const MCParticle* mcparticle = part->getMCParticle();
285 if (!mcparticle)
return realNaN;
288 TLorentzVector mcpP4 = mcparticle->get4Vector();
289 return frame.getMomentum(mcpP4).Py();
292 double particleMCMatchPZ(
const Particle* part)
294 const MCParticle* mcparticle = part->getMCParticle();
295 if (!mcparticle)
return realNaN;
298 TLorentzVector mcpP4 = mcparticle->get4Vector();
299 return frame.getMomentum(mcpP4).Pz();
302 double particleMCMatchPT(
const Particle* part)
304 const MCParticle* mcparticle = part->getMCParticle();
305 if (!mcparticle)
return realNaN;
308 TLorentzVector mcpP4 = mcparticle->get4Vector();
309 return frame.getMomentum(mcpP4).Pt();
312 double particleMCMatchE(
const Particle* part)
314 const MCParticle* mcparticle = part->getMCParticle();
315 if (!mcparticle)
return realNaN;
318 TLorentzVector mcpP4 = mcparticle->get4Vector();
319 return frame.getMomentum(mcpP4).E();
322 double particleMCMatchP(
const Particle* part)
324 const MCParticle* mcparticle = part->getMCParticle();
325 if (!mcparticle)
return realNaN;
328 TLorentzVector mcpP4 = mcparticle->get4Vector();
329 return frame.getMomentum(mcpP4).P();
332 double particleMCMatchTheta(
const Particle* part)
334 const MCParticle* mcparticle = part->getMCParticle();
335 if (!mcparticle)
return realNaN;
338 TLorentzVector mcpP4 = mcparticle->get4Vector();
339 return frame.getMomentum(mcpP4).Theta();
342 double particleMCMatchPhi(
const Particle* part)
344 const MCParticle* mcparticle = part->getMCParticle();
345 if (!mcparticle)
return realNaN;
348 TLorentzVector mcpP4 = mcparticle->get4Vector();
349 return frame.getMomentum(mcpP4).Phi();
352 double particleMCRecoilMass(
const Particle* part)
354 StoreArray<MCParticle> mcparticles;
355 if (mcparticles.getEntries() < 1)
return realNaN;
357 TLorentzVector pInitial = mcparticles[0]->get4Vector();
358 TLorentzVector pDaughters;
359 const std::vector<Particle*> daughters = part->getDaughters();
360 for (
auto daughter : daughters) {
361 const MCParticle* mcD = daughter->getMCParticle();
364 pDaughters += mcD->get4Vector();
366 return (pInitial - pDaughters).M();
369 TLorentzVector MCInvisibleP4(
const MCParticle* mcparticle)
371 TLorentzVector ResultP4;
372 int pdg = abs(mcparticle->getPDG());
373 bool isNeutrino = (pdg == 12 or pdg == 14 or pdg == 16);
375 if (mcparticle->getNDaughters() > 0) {
376 const std::vector<MCParticle*> daughters = mcparticle->getDaughters();
377 for (
auto daughter : daughters)
378 ResultP4 += MCInvisibleP4(daughter);
379 }
else if (isNeutrino)
380 ResultP4 += mcparticle->get4Vector();
385 double particleMCCosThetaBetweenParticleAndNominalB(
const Particle* part)
387 int particlePDG = abs(part->getPDGCode());
388 if (particlePDG != 511 and particlePDG != 521)
389 B2FATAL(
"The variable mcCosThetaBetweenParticleAndNominalB is only meant to be used on B mesons!");
392 double e_Beam = T.getCMSEnergy() / 2.0;
393 double m_B = part->getPDGMass();
396 const double mY4S = 10.5794;
399 if (e_Beam * e_Beam - m_B * m_B < 0) {
402 double p_B = std::sqrt(e_Beam * e_Beam - m_B * m_B);
405 const MCParticle* mcB = part->getMCParticle();
408 int mcParticlePDG = abs(mcB->getPDG());
409 if (mcParticlePDG != 511 and mcParticlePDG != 521)
412 TLorentzVector p = T.rotateLabToCms() * (mcB->get4Vector() - MCInvisibleP4(mcB));
415 double p_d = p.Rho();
417 double theta_BY = (2 * e_Beam * e_d - m_B * m_B - m_d * m_d)
422 double mcParticleSecondaryPhysicsProcess(
const Particle* p)
424 const MCParticle* mcp = p->getMCParticle();
426 return mcp->getSecondaryPhysicsProcess();
429 double mcParticleStatus(
const Particle* p)
431 const MCParticle* mcp = p->getMCParticle();
433 return mcp->getStatus();
436 double particleMCPrimaryParticle(
const Particle* p)
438 const MCParticle* mcp = p->getMCParticle();
442 return mcp->hasStatus(bitmask);
445 double particleMCVirtualParticle(
const Particle* p)
447 const MCParticle* mcp = p->getMCParticle();
451 return mcp->hasStatus(bitmask);
454 double particleMCInitialParticle(
const Particle* p)
456 const MCParticle* mcp = p->getMCParticle();
460 return mcp->hasStatus(bitmask);
463 double particleMCISRParticle(
const Particle* p)
465 const MCParticle* mcp = p->getMCParticle();
469 return mcp->hasStatus(bitmask);
472 double particleMCFSRParticle(
const Particle* p)
474 const MCParticle* mcp = p->getMCParticle();
478 return mcp->hasStatus(bitmask);
481 double particleMCPhotosParticle(
const Particle* p)
483 const MCParticle* mcp = p->getMCParticle();
487 return mcp->hasStatus(bitmask);
490 double generatorEventWeight(
const Particle*)
492 StoreObjPtr<EventMetaData> evtMetaData;
493 if (!evtMetaData)
return realNaN;
494 return evtMetaData->getGeneratedWeight();
497 int tauPlusMcMode(
const Particle*)
499 StoreObjPtr<TauPairDecay> tauDecay;
501 B2WARNING(
"Cannot find tau decay ID, did you forget to run TauDecayMarkerModule?");
504 return tauDecay->getTauPlusIdMode();
507 int tauMinusMcMode(
const Particle*)
509 StoreObjPtr<TauPairDecay> tauDecay;
511 B2WARNING(
"Cannot find tau decay ID, did you forget to run TauDecayMarkerModule?");
514 return tauDecay->getTauMinusIdMode();
517 int tauPlusMcProng(
const Particle*)
519 StoreObjPtr<TauPairDecay> tauDecay;
521 B2WARNING(
"Cannot find tau prong, did you forget to run TauDecayMarkerModule?");
524 return tauDecay->getTauPlusMcProng();
527 int tauMinusMcProng(
const Particle*)
529 StoreObjPtr<TauPairDecay> tauDecay;
531 B2WARNING(
"Cannot find tau prong, did you forget to run TauDecayMarkerModule?");
534 return tauDecay->getTauMinusMcProng();
539 double isReconstructible(
const Particle* p)
541 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
543 const MCParticle* mcp = p->getMCParticle();
548 return (abs(mcp->getCharge()) > 0) ? seenInSVD(p) : seenInECL(p);
551 double seenInPXD(
const Particle* p)
553 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
555 const MCParticle* mcp = p->getMCParticle();
557 return mcp->hasSeenInDetector(Const::PXD);
560 double seenInSVD(
const Particle* p)
562 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
564 const MCParticle* mcp = p->getMCParticle();
566 return mcp->hasSeenInDetector(Const::SVD);
569 double seenInCDC(
const Particle* p)
571 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
573 const MCParticle* mcp = p->getMCParticle();
575 return mcp->hasSeenInDetector(Const::CDC);
578 double seenInTOP(
const Particle* p)
580 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
582 const MCParticle* mcp = p->getMCParticle();
584 return mcp->hasSeenInDetector(Const::TOP);
587 double seenInECL(
const Particle* p)
589 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
591 const MCParticle* mcp = p->getMCParticle();
593 return mcp->hasSeenInDetector(Const::ECL);
596 double seenInARICH(
const Particle* p)
598 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
600 const MCParticle* mcp = p->getMCParticle();
602 return mcp->hasSeenInDetector(Const::ARICH);
605 double seenInKLM(
const Particle* p)
607 if (p->getParticleSource() == Particle::EParticleSourceObject::c_Composite)
609 const MCParticle* mcp = p->getMCParticle();
611 return mcp->hasSeenInDetector(Const::KLM);
614 int genNStepsToDaughter(
const Particle* p,
const std::vector<double>& arguments)
616 if (arguments.size() != 1)
617 B2FATAL(
"Wrong number of arguments for genNStepsToDaughter");
619 const MCParticle* mcp = p->getMCParticle();
621 B2WARNING(
"No MCParticle is associated to the particle");
625 int nChildren = p->getNDaughters();
626 if (arguments[0] >= nChildren) {
630 const Particle* daugP = p->getDaughter(arguments[0]);
635 B2WARNING(
"No MCParticle is associated to the i-th daughter");
639 if (nChildren == 1)
return 1;
641 std::vector<int> genMothers;
643 auto match = std::find(genMothers.begin(), genMothers.end(), mcp->getIndex());
644 return match - genMothers.begin();
647 int genNMissingDaughter(
const Particle* p,
const std::vector<double>& arguments)
649 if (arguments.size() < 1)
650 B2FATAL(
"Wrong number of arguments for genNMissingDaughter");
652 const std::vector<int> PDGcodes(arguments.begin(), arguments.end());
654 const MCParticle* mcp = p->getMCParticle();
656 B2WARNING(
"No MCParticle is associated to the particle");
663 double getHEREnergy(
const Particle*)
665 static DBObjPtr<BeamParameters> beamParamsDB;
666 return (beamParamsDB->getHER()).E();
669 double getLEREnergy(
const Particle*)
671 static DBObjPtr<BeamParameters> beamParamsDB;
672 return (beamParamsDB->getLER()).E();
675 double getCrossingAngleX(
const Particle*)
678 static DBObjPtr<BeamParameters> beamParamsDB;
679 TVector3 herVec = beamParamsDB->getHER().Vect();
680 TVector3 lerVec = beamParamsDB->getLER().Vect();
687 return herVec.Angle(-lerVec);
690 double getCrossingAngleY(
const Particle*)
693 static DBObjPtr<BeamParameters> beamParamsDB;
694 TVector3 herVec = beamParamsDB->getHER().Vect();
695 TVector3 lerVec = beamParamsDB->getLER().Vect();
702 return herVec.Angle(-lerVec);
706 double particleClusterMatchWeight(
const Particle* particle)
714 const MCParticle* matchedToParticle = particle->getMCParticle();
715 if (!matchedToParticle)
return realNaN;
716 int matchedToIndex = matchedToParticle->getArrayIndex();
718 const ECLCluster* cluster = particle->getECLCluster();
721 const auto mcps = cluster->getRelationsTo<MCParticle>();
722 for (
unsigned int i = 0; i < mcps.size(); ++i)
723 if (mcps[i]->getArrayIndex() == matchedToIndex)
724 return mcps.weight(i);
729 double particleClusterBestMCMatchWeight(
const Particle* particle)
741 const ECLCluster* cluster = particle->getECLCluster();
747 auto mcps = cluster->getRelationsTo<MCParticle>();
748 if (mcps.size() == 0)
return realNaN;
750 std::vector<double> weights;
751 for (
unsigned int i = 0; i < mcps.size(); ++i)
752 weights.emplace_back(mcps.weight(i));
755 std::sort(weights.begin(), weights.end());
756 std::reverse(weights.begin(), weights.end());
760 double particleClusterBestMCPDGCode(
const Particle* particle)
770 const ECLCluster* cluster = particle->getECLCluster();
773 auto mcps = cluster->getRelationsTo<MCParticle>();
774 if (mcps.size() == 0)
return realNaN;
776 std::vector<std::pair<double, int>> weightsAndIndices;
777 for (
unsigned int i = 0; i < mcps.size(); ++i)
778 weightsAndIndices.emplace_back(mcps.weight(i), i);
782 weightsAndIndices.begin(), weightsAndIndices.end(),
783 [](
const std::pair<double, int>& l,
const std::pair<double, int>& r) {
784 return l.first > r.first;
786 return mcps.object(weightsAndIndices[0].second)->getPDG();
789 double isBBCrossfeed(
const Particle* particle)
791 if (particle ==
nullptr)
792 return std::numeric_limits<double>::quiet_NaN();
794 int pdg = particle->getPDGCode();
795 if (abs(pdg) != 511 && abs(pdg) != 521 && abs(pdg) != 531)
796 return std::numeric_limits<double>::quiet_NaN();
798 std::vector<const Particle*> daughters = particle->getFinalStateDaughters();
799 int nDaughters = daughters.size();
802 std::vector<int> mother_ids;
804 for (
int j = 0; j < nDaughters; ++j) {
805 const MCParticle* curMCParticle = daughters[j]->
getMCParticle();
806 while (curMCParticle !=
nullptr) {
807 pdg = curMCParticle->getPDG();
808 if (abs(pdg) == 511 || abs(pdg) == 521 || abs(pdg) == 531) {
809 mother_ids.emplace_back(curMCParticle->getArrayIndex());
812 const MCParticle* curMCMother = curMCParticle->getMother();
813 curMCParticle = curMCMother;
815 if (curMCParticle ==
nullptr) {
816 return std::numeric_limits<double>::quiet_NaN();
820 std::set<int> distinctIDs = std::set(mother_ids.begin(), mother_ids.end());
821 if (distinctIDs.size() == 1)
827 VARIABLE_GROUP(
"MC matching and MC truth");
828 REGISTER_VARIABLE(
"isSignal", isSignal,
829 "1.0 if Particle is correctly reconstructed (SIGNAL), 0.0 if not, and NaN if no related MCParticle could be found. \n"
830 "It behaves according to DecayStringGrammar.");
831 REGISTER_VARIABLE(
"isSignalAcceptWrongFSPs", isSignalAcceptWrongFSPs,
832 "1.0 if Particle is almost correctly reconstructed (SIGNAL), 0.0 if not, and NaN if no related MCParticle could be found.\n"
833 "Misidentification of charged FSP is allowed.");
834 REGISTER_VARIABLE(
"isPrimarySignal", isPrimarySignal,
835 "1.0 if Particle is correctly reconstructed (SIGNAL) and primary, 0.0 if not, and NaN if no related MCParticle could be found");
836 REGISTER_VARIABLE(
"isSignalAcceptBremsPhotons", isSignalAcceptBremsPhotons,
837 "1.0 if Particle is correctly reconstructed (SIGNAL), 0.0 if not, and NaN if no related MCParticle could be found.\n"
838 "Particles with gamma daughters attached through the bremsstrahlung recovery modules are allowed.");
839 REGISTER_VARIABLE(
"genMotherPDG", genMotherPDG,
840 "Check the PDG code of a particles MC mother particle");
841 REGISTER_VARIABLE(
"genMotherPDG(i)", genNthMotherPDG,
842 "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:");
844 REGISTER_VARIABLE(
"genMotherID", genMotherIndex,
845 "Check the array index of a particles generated mother");
846 REGISTER_VARIABLE(
"genMotherID(i)", genNthMotherIndex,
847 "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:");
851 REGISTER_VARIABLE(
"isBBCrossfeed", isBBCrossfeed,
852 "Returns 1 for crossfeed in reconstruction of given B meson, 0 for no crossfeed and NaN for no true B meson or failed truthmatching.");
853 REGISTER_VARIABLE(
"genMotherP", genMotherP,
854 "Generated momentum of a particles MC mother particle");
855 REGISTER_VARIABLE(
"genParticleID", genParticleIndex,
856 "Check the array index of a particle's related MCParticle");
857 REGISTER_VARIABLE(
"isSignalAcceptMissingNeutrino",
858 isSignalAcceptMissingNeutrino,
859 "same as isSignal, but also accept missing neutrino");
860 REGISTER_VARIABLE(
"isSignalAcceptMissingMassive",
861 isSignalAcceptMissingMassive,
862 "same as isSignal, but also accept missing massive particle");
863 REGISTER_VARIABLE(
"isSignalAcceptMissingGamma",
864 isSignalAcceptMissingGamma,
865 "same as isSignal, but also accept missing gamma, such as B -> K* gamma, pi0 -> gamma gamma");
866 REGISTER_VARIABLE(
"isSignalAcceptMissing",
867 isSignalAcceptMissing,
868 "same as isSignal, but also accept missing particle");
869 REGISTER_VARIABLE(
"isMisidentified", isMisidentified,
870 "return 1 if the particle is misidentified: at least one of the final state particles has the wrong PDG code assignment (including wrong charge), 0 if PDG code is fine, and NaN if no related MCParticle could be found.");
871 REGISTER_VARIABLE(
"isWrongCharge", isWrongCharge,
872 "return 1 if the charge of the particle is wrongly assigned, 0 if it's the correct charge, and NaN if no related MCParticle could be found.");
873 REGISTER_VARIABLE(
"isCloneTrack", isCloneTrack,
874 "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)");
875 REGISTER_VARIABLE(
"isOrHasCloneTrack", isOrHasCloneTrack,
876 "Return 1 if the particle is a clone track or has a clone track as a daughter, 0 otherwise.");
877 REGISTER_VARIABLE(
"mcPDG", particleMCMatchPDGCode,
878 "The PDG code of matched MCParticle, NaN if no match. Requires running matchMCTruth() on the reconstructed particles, or a particle list filled with generator particles (MCParticle objects).");
879 REGISTER_VARIABLE(
"mcErrors", particleMCErrors,
880 "The bit pattern indicating the quality of MC match (see MCMatching::MCErrorFlags)");
881 REGISTER_VARIABLE(
"mcMatchWeight", particleMCMatchWeight,
882 "The weight of the Particle -> MCParticle relation (only for the first Relation = largest weight).");
883 REGISTER_VARIABLE(
"nMCMatches", particleNumberOfMCMatch,
884 "The number of relations of this Particle to MCParticle.");
885 REGISTER_VARIABLE(
"mcDecayTime", particleMCMatchDecayTime,
886 "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).");
887 REGISTER_VARIABLE(
"mcLifeTime", particleMCMatchLifeTime,
888 "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).");
889 REGISTER_VARIABLE(
"mcPX", particleMCMatchPX,
890 "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).");
891 REGISTER_VARIABLE(
"mcPY", particleMCMatchPY,
892 "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).");
893 REGISTER_VARIABLE(
"mcPZ", particleMCMatchPZ,
894 "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).");
895 REGISTER_VARIABLE(
"mcPT", particleMCMatchPT,
896 "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).");
897 REGISTER_VARIABLE(
"mcE", particleMCMatchE,
898 "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).");
899 REGISTER_VARIABLE(
"mcP", particleMCMatchP,
900 "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).");
901 REGISTER_VARIABLE(
"mcPhi", particleMCMatchPhi,
902 "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).");
903 REGISTER_VARIABLE(
"mcTheta", particleMCMatchTheta,
904 "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).");
905 REGISTER_VARIABLE(
"mcRecoilMass", particleMCRecoilMass,
906 "The mass recoiling against the particles attached as particle's daughters calculated using MC truth values.");
907 REGISTER_VARIABLE(
"mcCosThetaBetweenParticleAndNominalB",
908 particleMCCosThetaBetweenParticleAndNominalB,
909 "Cosine of the angle in CMS between momentum the particle and a nominal B particle. In this calculation, the momenta of all descendant neutrinos are subtracted from the B momentum.");
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", getCrossingAngleX, R"DOC(
955 [Eventbased] The nominal beam crossing angle in the x-z plane from generator level beam kinematics.
957 .. warning:: This variable does not make sense for data.
959 REGISTER_VARIABLE("YAngle", getCrossingAngleY, R"DOC(
960 [Eventbased] The nominal beam crossing angle in the y-z plane from generator level beam kinematics.
962 .. warning:: This variable does not make sense for data.
965 VARIABLE_GROUP("Generated tau decay information");
966 REGISTER_VARIABLE("tauPlusMCMode", tauPlusMcMode,
967 "[Eventbased] Decay ID for the positive tau lepton in a tau pair generated event.")
968 REGISTER_VARIABLE("tauMinusMCMode", tauMinusMcMode,
969 "[Eventbased] Decay ID for the negative tau lepton in a tau pair generated event.")
970 REGISTER_VARIABLE("tauPlusMCProng", tauPlusMcProng,
971 "[Eventbased] Prong for the positive tau lepton in a tau pair generated event.")
972 REGISTER_VARIABLE("tauMinusMCProng", tauMinusMcProng,
973 "[Eventbased] Prong for the negative tau lepton in a tau pair generated event.")
975 VARIABLE_GROUP("MC particle seen in subdetectors");
976 REGISTER_VARIABLE("isReconstructible", isReconstructible,
977 "checks charged particles were seen in the SVD and neutrals in the ECL, returns 1.0 if so, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
978 REGISTER_VARIABLE("seenInPXD", seenInPXD,
979 "returns 1.0 if the MC particle was seen in the PXD, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
980 REGISTER_VARIABLE("seenInSVD", seenInSVD,
981 "returns 1.0 if the MC particle was seen in the SVD, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
982 REGISTER_VARIABLE("seenInCDC", seenInCDC,
983 "returns 1.0 if the MC particle was seen in the CDC, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
984 REGISTER_VARIABLE("seenInTOP", seenInTOP,
985 "returns 1.0 if the MC particle was seen in the TOP, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
986 REGISTER_VARIABLE("seenInECL", seenInECL,
987 "returns 1.0 if the MC particle was seen in the ECL, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
988 REGISTER_VARIABLE("seenInARICH", seenInARICH,
989 "returns 1.0 if the MC particle was seen in the ARICH, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
990 REGISTER_VARIABLE("seenInKLM", seenInKLM,
991 "returns 1.0 if the MC particle was seen in the KLM, 0.0 if not, NaN for composite particles or if no related MCParticle could be found. Useful for generator studies, not for reconstructed particles.");
993 VARIABLE_GROUP("MC Matching for ECLClusters");
994 REGISTER_VARIABLE("clusterMCMatchWeight", particleClusterMatchWeight,
995 "Returns the weight of the ECLCluster -> MCParticle relation for the MCParticle matched to the particle. "
996 "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. "
997 "Returns -1 if the cluster *was* matched to particles, but not the match of the particle provided.");
998 REGISTER_VARIABLE("clusterBestMCMatchWeight", particleClusterBestMCMatchWeight,
999 "returns the weight of the ECLCluster -> MCParticle relation for the relation with the largest weight.");
1000 REGISTER_VARIABLE("clusterBestMCPDG", particleClusterBestMCPDGCode,
1001 "returns the PDG code of the MCParticle for the ECLCluster -> MCParticle relation with the largest weight.");
static const ParticleSet chargedStableSet
set of charged stable particles
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
@ c_IsPHOTOSPhoton
bit 8: Particle is an radiative photon from PHOTOS
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
static const ReferenceFrame & GetCurrent()
Get current rest frame.
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
Controls the configuration and initialization of Photos.
static const double realNaN
shortcut for NaN of double type
static const int intNaN
constant for integer NaN
Abstract base class for different kinds of events.
static int countMissingParticle(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle, const std::vector< int > &daughterPDG)
Count the number of missing daughters of the 'particle'.
@ c_Correct
This Particle and all its daughters are perfectly reconstructed.
@ c_MisID
One of the charged final state particles is mis-identified.
static int getMCErrors(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle=nullptr)
Returns quality indicator of the match as a bit pattern where the individual bits indicate the the ty...
static void fillGenMothers(const Belle2::MCParticle *mcP, std::vector< int > &genMCPMothers)
Fills vector with array (1-based) indices of all generator ancestors of given MCParticle.