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;
 
  396    if (i < daughterProperties.size()) 
 
  399    daughterStatuses |= (daughterStatus & daughterStatusAcceptMask);
 
  404  return (daughterStatuses & daughterStatusesAcceptMask);
 
 
  410                                              const vector<const MCParticle*>& genParts)
 
  423  else if (mcDaughter == mcParticle) {
 
  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.
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 final 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].