9#include <analysis/utility/MCMatching.h>
10#include <analysis/utility/AnalysisConfiguration.h>
12#include <analysis/dataobjects/Particle.h>
13#include <mdst/dataobjects/MCParticle.h>
15#include <framework/datastore/StoreArray.h>
16#include <framework/gearbox/Const.h>
17#include <framework/logging/Logger.h>
19#include <unordered_set>
43 case c_MisID : s +=
"c_MisID";
break;
50 B2ERROR(
"MCMatching::explainFlags() doesn't know about flag " << f <<
", please update it.");
64 genMCPMothers.push_back(mcP->
getIndex());
74 for (
unsigned int i = lastMother; i < firstMothers.size(); i++) {
75 if (firstMothers[i] == idx)
105 bool daugMCTruth =
true;
106 for (
int i = 0; i < nChildren; ++i) {
115 if (nChildren == 1) {
131 vector<int> firstDaugMothers;
134 for (
int i = 0; i < nChildren; ++i) {
142 if (lastMother == -1)
147 motherIndex = firstDaugMothers[lastMother];
160 B2ERROR(
"setMCTruth(): sanity check failed!");
164 const MCParticle* mcMatch = mcParticles[motherIndex - 1];
174 void appendParticles(
const Particle* p, unordered_set<const MCParticle*>& mcMatchedParticles)
176 for (
unsigned i = 0; i < p->getNDaughters(); ++i) {
177 const Particle* daug = p->getDaughter(i);
182 mcMatchedParticles.insert(mcParticle);
186 appendParticles(daug, mcMatchedParticles);
197 mcMatchedParticles.insert(mcParticle);
210 void appendParticles(
const MCParticle* gen, vector<const MCParticle*>& children)
218 const vector<MCParticle*>& genDaughters = gen->
getDaughters();
219 for (
auto daug : genDaughters) {
220 children.push_back(daug);
221 appendParticles(daug, children);
230 const int absPDG = abs(mcDaug->
getPDG());
245 }
else if (absPDG == 12 or absPDG == 14 or absPDG == 16) {
257 void appendAcceptedMissingDaughters(
const Particle* p, unordered_set<const MCParticle*>& acceptedParticles)
261 vector<const MCParticle*> genDaughters;
262 appendParticles(mcParticle, genDaughters);
264 for (
auto mcDaug : genDaughters) {
265 if (isDaughterAccepted(mcDaug, p))
266 acceptedParticles.insert(mcDaug);
268 acceptedParticles.erase(mcDaug);
272 for (
unsigned i = 0; i < p->getNDaughters(); ++i) {
273 const Particle* daug = p->getDaughter(i);
274 appendAcceptedMissingDaughters(daug, acceptedParticles);
295 auto setStatus = [](
Particle * part,
int s) ->
int {
305 return setStatus(particle,
getFlagsOfFSP(particle, mcParticle));;
320 if (abs(mother->getPDG()) != 15 and abs(mcParticle->
getPDG()) != 15) {
321 B2WARNING(
"Special treatment in MCMatching for tau is called for a non-tau particle. Check if you discovered another special case here, or if we have a bug! "
322 << mother->getPDG() <<
" " << particle->
getPDGCode() <<
" " << mcParticle->
getPDG());
340 return setStatus(particle, status);
376 vector<const MCParticle*> genParts;
378 if (particle->
hasExtraInfo(
"bremsCorrected") && nChildren > 1) {
379 if (mcParticle && mcParticle->
getMother())
380 appendParticles(mcParticle->
getMother(), genParts);
383 int daughterStatuses = 0;
385 for (
unsigned i = 0; i < nChildren; ++i) {
387 int daughterStatus = 0;
395 int daughterStatusAcceptMask = (~c_Correct);
396 if (i < daughterProperties.size())
399 daughterStatuses |= (daughterStatus & daughterStatusAcceptMask);
404 return (daughterStatuses & daughterStatusesAcceptMask);
410 const vector<const MCParticle*>& genParts)
419 daughterStatus &= (~c_InternalError);
423 else if (mcDaughter == mcParticle) {
424 daughterStatus &= (~c_MisID);
427 else if (std::find(genParts.begin(), genParts.end(), mcDaughter) == genParts.end()) {
432 return daughterStatus;
438 unsigned int number_of_neutrinos = 0;
439 for (
auto& p : daughters) {
440 auto pdg = abs(p->getPDG());
441 if (pdg == 12 || pdg == 14 || pdg == 16) {
442 number_of_neutrinos++;
445 return daughters.size() - number_of_neutrinos;
482 B2ERROR(
"The hell? why would this gamma not have a mother?");
506 vector<const MCParticle*> genParts;
507 appendParticles(mcParticle, genParts);
509 unordered_set<const MCParticle*> mcMatchedParticles;
510 appendParticles(particle, mcMatchedParticles);
511 unordered_set<const MCParticle*> acceptedParticles;
512 appendAcceptedMissingDaughters(particle, acceptedParticles);
513 for (
auto part : acceptedParticles) {
514 mcMatchedParticles.insert(part);
521 if (mcMatchedParticles.find(genPart) != mcMatchedParticles.end())
525 const int generatedPDG = genPart->getPDG();
526 const int absGeneratedPDG = abs(generatedPDG);
528 if (!
isFSP(generatedPDG)) {
550 }
else if (absGeneratedPDG == 12 || absGeneratedPDG == 14 || absGeneratedPDG == 16) {
563 unordered_set<const MCParticle*> mcMatchedParticles;
566 appendParticles(particle, mcMatchedParticles);
567 vector<const MCParticle*> genParts;
568 appendParticles(mcParticle, genParts);
570 int nMissingDaughter = 0;
573 const bool missing = (mcMatchedParticles.find(genPart) == mcMatchedParticles.end());
576 const int generatedPDG = genPart->getPDG();
577 const int absGeneratedPDG = abs(generatedPDG);
579 auto result = find(daughterPDG.begin(), daughterPDG.end(), absGeneratedPDG);
580 if (result != daughterPDG.end())
585 return nMissingDaughter;
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.
int getPDGCode() const
PDG code.
static const ParticleType Klong
K^0_L particle.
static const ParticleType Kshort
K^0_S particle.
static const ParticleType photon
photon particle
A Class to store the Monte Carlo particle information.
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
@ c_IsPHOTOSPhoton
bit 8: Particle is an radiative photon from PHOTOS
@ c_IsRadiativePhoton
combined flag to test whether the particle is radiative
@ c_PrimaryParticle
bit 0: Particle is primary particle.
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
int getNDaughters() const
Return number of daughter MCParticles.
int getPDG() const
Return PDG code of particle.
Class to store reconstructed particles.
const std::vector< int > & getDaughterProperties() const
Returns a vector of properties of daughter particles.
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
EFlavorType getFlavorType() const
Returns flavor type of the decay (for FS particles: flavor type of particle)
int getPDGCode(void) const
Returns PDG code.
int getProperty() const
Returns particle property as a bit pattern The values are defined in the PropertyFlags enum and descr...
unsigned getNDaughters(void) const
Returns number of daughter particles.
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
EFlavorType
describes flavor type, see getFlavorType().
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
@ c_Flavored
Is either particle or antiparticle.
@ c_IsIgnoreNeutrino
Is the particle MC matched with the ignore missing neutrino flag set?
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
@ c_IsIgnoreGamma
Is the particle MC matched with the ignore missing gamma flag set?
@ c_IsUnspecified
Ordinary particles.
@ c_IsIgnoreBrems
Is the particle MC matched with the ignore added Brems gamma flag set?
@ c_IsIgnoreDecayInFlight
Is the particle MC matched with the ignore DecayInFlight flag set?
@ c_IsIgnoreMisID
Is the particle MC matched with the ignore MisID flag set?
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
@ c_IsIgnoreMassive
Is the particle MC matched with the ignore missing massive particle flag set?
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
double getExtraInfo(const std::string &name) const
Return given value if set.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
Accessor to arrays stored in the data store.
int getEntries() const
Get the number of objects in the array.
MCParticle * getMother() const
Returns a pointer to the mother particle.
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'.
static std::string explainFlags(unsigned int flags)
Return string with all human-readable flags, e.g.
@ c_MissMassiveParticle
A generated massive FSP is missing (not reconstructed).
@ c_MissFSR
A Final State Radiation (FSR) photon is not reconstructed (based on MCParticle::c_IsFSRPhoton).
@ c_AddedWrongParticle
A non-FSP Particle has wrong PDG code, meaning one of the daughters (or their daughters) belongs to a...
@ c_MissNeutrino
A neutrino is missing (not reconstructed).
@ c_Correct
This Particle and all its daughters are perfectly reconstructed.
@ c_DecayInFlight
A Particle was reconstructed from the secondary decay product of the actual particle.
@ c_InternalError
There was an error in MC matching.
@ c_MissingResonance
The associated MCParticle decay contained additional non-final-state particles (e....
@ c_MissPHOTOS
A photon created by PHOTOS was not reconstructed (based on MCParticle::c_IsPHOTOSPhoton)
@ c_MissGamma
A photon (not FSR) is missing (not reconstructed).
@ c_MisID
One of the charged final state particles is mis-identified, i.e.
@ c_MissKlong
A Klong is missing (not reconstructed).
@ c_AddedRecoBremsPhoton
A photon added with the bremsstrahlung recovery tools (correctBrems or correctBremsBelle) has no MC p...
static bool isRadiativePhoton(const Belle2::MCParticle *p)
Returns true if given MCParticle is a radiative photon.
static int makeDaughterAcceptMask(int daughterProperty)
Returns the daughter mask from given daughterProperty.
static int getNumberOfDaughtersWithoutNeutrinos(const MCParticle *mcParticle)
Determines the number of daughter particles which are not neutrinos.
static int getFlagsOfBremsPhotonDaughter(const Particle *daughter, const MCParticle *mcParticle, const std::vector< const MCParticle * > &genParts)
Returns flags of given daughter which is a brems photon.
static bool setMCTruth(const Belle2::Particle *particle)
This is the main function of MC matching algorithm.
static int getFlagsOfFSP(const Particle *particle, const MCParticle *mcParticle)
Returns flags of given Final State Particle.
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 int getFlagsOfDaughters(const Particle *daughter, const MCParticle *mcParticle)
Returns flags of daughters of given particle.
static bool isFSR(const Belle2::MCParticle *p)
Returns true if given MCParticle is a final state radiation (FSR) photon based on MCParticle::c_IsFSR...
static bool isFSRLegacy(const Belle2::MCParticle *p)
Returns true if given MCParticle is a final state radiation (FSR) photon.
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.
static int setMCErrorsExtraInfo(Belle2::Particle *particle, const Belle2::MCParticle *mcParticle)
Sets error flags in extra-info (also returns it).
static int getFlagsIgnoredByProperty(const Belle2::Particle *particle)
Returns the flags ignored by PropertyFlags of given particle.
static int getMissingParticleFlags(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle)
Determines which daughters of 'mcParticle' are not reconstructed by any daughter of 'particle'.
static bool isFSP(int pdg)
Returns true if given PDG code indicates a FSP.
static const std::string c_extraInfoMCErrors
Name of extra-info field stored in Particle.
static int findCommonMother(const Belle2::MCParticle *mcP, const std::vector< int > &firstMothers, int lastMother)
Finds a mother of mcP that is in firstMothers, from [lastMother, end].