Belle II Software  release-05-01-25
MCMatching.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * *
4  * Copyright(C) 2013-2018 - Belle II Collaboration *
5  * *
6  * Author: The Belle II Collaboration *
7  * Contributors: Anze Zupanc, Christian Pulvermacher, Yo Sato, *
8  * Alejandro Mora *
9  * *
10  * This software is provided "as is" without any warranty. *
11  **************************************************************************/
12 
13 #include <analysis/utility/MCMatching.h>
14 #include <analysis/utility/AnalysisConfiguration.h>
15 
16 #include <analysis/dataobjects/Particle.h>
17 #include <mdst/dataobjects/MCParticle.h>
18 
19 #include <framework/datastore/StoreArray.h>
20 #include <framework/logging/Logger.h>
21 
22 #include <unordered_set>
23 
24 using namespace Belle2;
25 using namespace std;
26 
27 const std::string MCMatching::c_extraInfoMCErrors = "mcErrors";
28 
29 std::string MCMatching::explainFlags(unsigned int flags)
30 {
31  if (flags == c_Correct)
32  return "c_Correct";
33 
34  std::string s;
35  unsigned int f = 1;
36  while (flags != 0) {
37  if (flags & f) {
38  switch (f) {
39  case c_MissFSR : s += "c_MissFSR"; break;
40  case c_MissingResonance : s += "c_MissingResonance"; break;
41  case c_DecayInFlight : s += "c_DecayInFlight"; break;
42  case c_MissNeutrino : s += "c_MissNeutrino"; break;
43  case c_MissGamma : s += "c_MissGamma"; break;
44  case c_MissMassiveParticle : s += "c_MissMassiveParticle"; break;
45  case c_MissKlong : s += "c_MissKlong"; break;
46  case c_MisID : s += "c_MisID"; break;
47  case c_AddedWrongParticle : s += "c_AddedWrongParticle"; break;
48  case c_InternalError : s += "c_InternalError"; break;
49  case c_MissPHOTOS : s += "c_MissPHOTOS"; break;
50  case c_AddedRecoBremsPhoton : s += "c_AddedRecoBremsPhoton"; break;
51  default:
52  s += to_string(f);
53  B2ERROR("MCMatching::explainFlags() doesn't know about flag " << f << ", please update it.");
54  }
55  flags -= f; //remove flag
56  if (flags != 0)
57  s += " | ";
58  }
59  f *= 2;
60  }
61  return s;
62 }
63 
64 void MCMatching::fillGenMothers(const MCParticle* mcP, vector<int>& genMCPMothers)
65 {
66  while (mcP) {
67  genMCPMothers.push_back(mcP->getIndex());
68  mcP = mcP->getMother();
69  }
70 }
71 
72 
73 int MCMatching::findCommonMother(const MCParticle* mcP, const vector<int>& firstMothers, int lastMother)
74 {
75  while (mcP) {
76  int idx = mcP->getIndex();
77  for (unsigned int i = lastMother; i < firstMothers.size(); i++) {
78  if (firstMothers[i] == idx)
79  return i;
80  }
81 
82  mcP = mcP->getMother();
83  }
84  //not found
85  return -1;
86 }
87 
88 
89 bool MCMatching::setMCTruth(const Particle* particle)
90 {
91  //if extra-info is set, we already handled this particle
92  //TODO check wether this actually speeds things up or not
93  if (particle->hasExtraInfo(c_extraInfoMCErrors))
94  return true;
95 
96  if (particle->getRelatedTo<MCParticle>()) {
97  //nothing to do
98  return true;
99  }
100 
101  int nChildren = particle->getNDaughters();
102  if (nChildren == 0) {
103  //no daughters -> should be an FSP, but no related MCParticle. Probably background.
104  return false;
105  }
106 
107  // check, if for all daughter particles Particle -> MCParticle relation exists
108  bool daugMCTruth = true;
109  for (int i = 0; i < nChildren; ++i) {
110  const Particle* daugP = particle->getDaughter(i);
111  // call setMCTruth for all daughters
112  daugMCTruth &= setMCTruth(daugP);
113  }
114  if (!daugMCTruth)
115  return false;
116 
117  int motherIndex = 0;
118  if (nChildren == 1) {
119  // assign mother of MCParticle related to our daughter
120  const Particle* daugP = particle->getDaughter(0);
121  const MCParticle* daugMCP = daugP->getRelatedTo<MCParticle>();
122  if (!daugMCP)
123  return false;
124  const MCParticle* mom = daugMCP->getMother();
125  if (!mom)
126  return false;
127  motherIndex = mom->getIndex();
128 
129  } else {
130  // at this stage for all daughters particles the Particle <-> MCParticle relation exists
131  // first fill vector with indices of all mothers of first daughter,
132  // then search common mother for each other daughter
133 
134  vector<int> firstDaugMothers; // indices of generated mothers of first daughter
135 
136  int lastMother = 0; //index in firstDaugMothers (start with first daughter itself)
137  for (int i = 0; i < nChildren; ++i) {
138  const Particle* daugP = particle->getDaughter(i);
139  const MCParticle* daugMCP = daugP->getRelatedTo<MCParticle>();
140 
141  if (i == 0) {
142  fillGenMothers(daugMCP, firstDaugMothers);
143  } else {
144  lastMother = findCommonMother(daugMCP, firstDaugMothers, lastMother);
145  if (lastMother == -1)
146  break; //not found
147  }
148  }
149  if (lastMother >= 0)
150  motherIndex = firstDaugMothers[lastMother];
151  }
152 
153  // if index is less than 1, the common mother particle was not found
154  // remember: it's 1-based index
155  if (motherIndex < 1)
156  return false;
157 
158  // finally the relation can be set
159  StoreArray<MCParticle> mcParticles;
160 
161  // sanity check
162  if (motherIndex > mcParticles.getEntries()) {
163  B2ERROR("setMCTruth(): sanity check failed!");
164  return false;
165  }
166 
167  const MCParticle* mcMatch = mcParticles[motherIndex - 1];
168  particle->addRelationTo(mcMatch);
169 
170  return true;
171 }
172 
173 
174 //utility functions used by setMCErrorsExtraInfo() getMissingParticleFlags()
175 namespace {
177  void appendParticles(const Particle* p, unordered_set<const MCParticle*>& mcMatchedParticles)
178  {
179  for (unsigned i = 0; i < p->getNDaughters(); ++i) {
180  const Particle* daug = p->getDaughter(i);
181 
182  //add matched MCParticle for 'daug'
183  const MCParticle* mcParticle = daug->getRelatedTo<MCParticle>();
184  if (mcParticle)
185  mcMatchedParticles.insert(mcParticle);
186 
187  if (daug->getNDaughters() != 0) {
188  // if daug has daughters, call appendParticles recursively.
189  appendParticles(daug, mcMatchedParticles);
190  continue;
191  }
192 
193  if (daug->hasExtraInfo(MCMatching::c_extraInfoMCErrors)) {
194  if (static_cast<unsigned int>(daug->getExtraInfo(MCMatching::c_extraInfoMCErrors)) & MCMatching::c_DecayInFlight) {
195  //now daug does not have any daughters.
196  //particle at the bottom of reconstructed decay tree, reconstructed from an MCParticle that is actually slightly deeper than we want,
197  //so we'll also add all mother MCParticles until the first primary mother
198  mcParticle = mcParticle->getMother();
199  while (mcParticle) {
200  mcMatchedParticles.insert(mcParticle);
201  if (mcParticle->hasStatus(MCParticle::c_PrimaryParticle))
202  break;
203 
204  mcParticle = mcParticle->getMother();
205  }
206  }
207  }
208 
209  }
210  }
211 
213  void appendParticles(const MCParticle* gen, vector<const MCParticle*>& children)
214  {
215  if (MCMatching::isFSP(gen->getPDG()))
216  return; //stop at the bottom of the MC decay tree (ignore secondaries)
217 
218  const vector<MCParticle*>& genDaughters = gen->getDaughters();
219  for (auto daug : genDaughters) {
220  children.push_back(daug);
221  appendParticles(daug, children);
222  }
223  }
224 
225  // Check if mcDaug is accepted to be missed by the property of part.
226  bool isDaughterAccepted(const MCParticle* mcDaug, const Particle* part)
227  {
228  const int property = part->getProperty();
229 
230  const int absPDG = abs(mcDaug->getPDG());
231 
232  // if mcDaug is not FSP, check c_IsIgnoreIntermediate property
233  if (!MCMatching::isFSP(absPDG)) {
234  if (property & Particle::PropertyFlags::c_IsIgnoreIntermediate)
235  return true;
236  } else if (absPDG == Const::photon.getPDGCode()) { // gamma
238  or (AnalysisConfiguration::instance()->useLegacyMCMatching() and MCMatching::isFSRLegacy(mcDaug))) {
239  if (property & Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons)
240  return true;
241  } else {
242  if (property & Particle::PropertyFlags::c_IsIgnoreGamma)
243  return true;
244  }
245  } else if (absPDG == 12 or absPDG == 14 or absPDG == 16) { // neutrino
246  if (property & Particle::PropertyFlags::c_IsIgnoreNeutrino)
247  return true;
248  } else { // otherwise, massive FSP
249  if (property & Particle::PropertyFlags::c_IsIgnoreMassive)
250  return true;
251  }
252 
253  return false;
254  }
255 
257  void appendAcceptedMissingDaughters(const Particle* p, unordered_set<const MCParticle*>& acceptedParticles)
258  {
259  const MCParticle* mcParticle = p->getRelatedTo<MCParticle>();
260  if (mcParticle) {
261  vector<const MCParticle*> genDaughters;
262  appendParticles(mcParticle, genDaughters);
263 
264  for (auto mcDaug : genDaughters) {
265  if (isDaughterAccepted(mcDaug, p))
266  acceptedParticles.insert(mcDaug);
267  else
268  acceptedParticles.erase(mcDaug);
269  }
270  }
271 
272  for (unsigned i = 0; i < p->getNDaughters(); ++i) {
273  const Particle* daug = p->getDaughter(i);
274  appendAcceptedMissingDaughters(daug, acceptedParticles);
275  }
276 
277  }
278 
279 
280 }
281 
282 int MCMatching::getMCErrors(const Particle* particle, const MCParticle* mcParticle)
283 {
284  if (particle->hasExtraInfo(c_extraInfoMCErrors)) {
285  return particle->getExtraInfo(c_extraInfoMCErrors);
286  } else {
287  if (!mcParticle)
288  mcParticle = particle->getRelatedTo<MCParticle>();
289  return setMCErrorsExtraInfo(const_cast<Particle*>(particle), mcParticle);
290  }
291 }
292 
293 int MCMatching::setMCErrorsExtraInfo(Particle* particle, const MCParticle* mcParticle)
294 {
295  auto setStatus = [](Particle * part, int s) -> int {
296  part->addExtraInfo(c_extraInfoMCErrors, s);
297  return s;
298  };
299 
300  if (!mcParticle)
301  return setStatus(particle, MCErrorFlags::c_InternalError);
302 
303  if (particle->getNDaughters() == 0) { //FSP
304  //other checks concern daughters of particle, so we're done here
305  return setStatus(particle, getFlagsOfFSP(particle, mcParticle));;
306  }
307 
308  int status = 0;
309 
310  // Check if particle (non FSP) has different PDG code than mcParticle
311  const Particle::EFlavorType flavorType = particle->getFlavorType();
312  if ((flavorType == Particle::c_Flavored and particle->getPDGCode() != mcParticle->getPDG())
313  or (flavorType == Particle::c_Unflavored and abs(particle->getPDGCode()) != abs(mcParticle->getPDG()))) {
314  auto mother = mcParticle->getMother();
315 
316  // Check if mother particle has the correct pdg code, if so we have to take care of the special case
317  // tau -> rho nu, where a the matched mother is the rho, but we have only a missing resonance and not added a wrong particle.
318  if (mother and particle->getPDGCode() == mother->getPDG() and getNumberOfDaughtersWithoutNeutrinos(mother) == 1
319  and !particle->hasExtraInfo("bremsCorrected")) {
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());
323  }
324  // if particle has c_IsIgnoreIntermediate flag, c_MissingResonance will not be added.
325  if (not(particle->getProperty() & Particle::PropertyFlags::c_IsIgnoreIntermediate))
326  status |= MCErrorFlags::c_MissingResonance;
327  } else if (!(particle->getProperty() & Particle::PropertyFlags::c_IsUnspecified)) {
328  // Check if the particle is unspecified. If so the flag of c_AddedWrongParticle will be ignored.
329  status |= MCErrorFlags::c_AddedWrongParticle;
330  }
331  }
332 
333  status |= getFlagsOfDaughters(particle, mcParticle);
334 
335  status |= getMissingParticleFlags(particle, mcParticle);
336 
337  // Mask the flags ignored by PropertyFlags of the particle
338  status &= ~(getFlagsIgnoredByProperty(particle));
339 
340  return setStatus(particle, status);
341 }
342 
343 int MCMatching::getFlagsOfFSP(const Particle* particle, const MCParticle* mcParticle)
344 {
345  if (particle->getPDGCode() == mcParticle->getPDG())
346  return MCErrorFlags::c_Correct;
347 
348  // if PDG of particle is different from that of mcParticle
349  if (mcParticle->hasStatus(MCParticle::c_PrimaryParticle)) {
350  // if particle is primary, add the c_MisID flag.
351  return MCErrorFlags::c_MisID;
352  } else {
353  // secondary particle, so the original particle probably decayed
354  int status = MCErrorFlags::c_DecayInFlight;
355 
356  //find first primary mother
357  const MCParticle* primary = mcParticle->getMother();
358  while (primary and !primary->hasStatus(MCParticle::c_PrimaryParticle))
359  primary = primary->getMother();
360 
361  if (!primary) {
362  status |= MCErrorFlags::c_InternalError;
363  } else if (particle->getPDGCode() != primary->getPDG()) {
364  //if primary particle also has wrong PDG code, we're actually MisIDed
365  status |= MCErrorFlags::c_MisID;
366  }
367  return status;
368  }
369 }
370 
371 int MCMatching::getFlagsOfDaughters(const Particle* particle, const MCParticle* mcParticle)
372 {
373  unsigned nChildren = particle->getNDaughters();
374 
375  //Vector to store all the MC (n*grand-)daughters of the mother of the bremsstrahlung corrected particle
376  vector<const MCParticle*> genParts;
377  //Fill it only in the case we have a particle that has been brems corrected
378  if (particle->hasExtraInfo("bremsCorrected") && nChildren > 1) {
379  if (mcParticle && mcParticle->getMother())
380  appendParticles(mcParticle->getMother(), genParts);
381  }
382 
383  int daughterStatuses = 0;
384  vector<int> daughterProperties = particle->getDaughterProperties();
385  for (unsigned i = 0; i < nChildren; ++i) {
386  const Particle* daughter = particle->getDaughter(i);
387  int daughterStatus = 0;
388  if (particle->hasExtraInfo("bremsCorrected") && daughter->getPDGCode() == Const::photon.getPDGCode()) {
389  // if the daughter is a brems photon, start the special treatment
390  daughterStatus |= getFlagsOfBremsPhotonDaughter(daughter, mcParticle, genParts);
391  } else {
392  daughterStatus |= getMCErrors(daughter);
393  }
394 
395  int daughterStatusAcceptMask = (~c_Correct);
396  if (i < daughterProperties.size()) // sanity check. daughterProperties should be larger than i.
397  daughterStatusAcceptMask = makeDaughterAcceptMask(daughterProperties[i]);
398 
399  daughterStatuses |= (daughterStatus & daughterStatusAcceptMask);
400  }
401 
402  //add up all (accepted) status flags we collected for our daughters
403  const int daughterStatusesAcceptMask = c_MisID | c_AddedWrongParticle | c_DecayInFlight | c_InternalError | c_AddedRecoBremsPhoton;
404  return (daughterStatuses & daughterStatusesAcceptMask);
405 
406 }
407 
408 
409 int MCMatching::getFlagsOfBremsPhotonDaughter(const Particle* daughter, const MCParticle* mcParticle,
410  const vector<const MCParticle*>& genParts)
411 {
412  //At first, call getMCErrors as usual
413  int daughterStatus = getMCErrors(daughter);
414 
415  //Check if the daugther has an MC particle related
416  const MCParticle* mcDaughter = daughter->getRelatedTo<MCParticle>();
417  //If it hasn't, add the c_BremsPhotonAdded flag to the mother and stop the propagation of c_InternalError
418  if (!mcDaughter) {
419  daughterStatus &= (~c_InternalError);
420  daughterStatus |= c_AddedRecoBremsPhoton;
421  }
422  //If it has, check if MCParticle of the daughter is same as the mother. If so, we'll stop the propagation of c_MisID
423  else if (mcDaughter == mcParticle) {
424  daughterStatus &= (~c_MisID);
425  }
426  //If it has, check if the MC particle is (n*grand)-daughter of the particle mother. If it isn't, we'll add the error flag
427  else if (std::find(genParts.begin(), genParts.end(), mcDaughter) == genParts.end()) {
428  daughterStatus |= c_AddedRecoBremsPhoton;
429  }
430  //else nothing to do
431 
432  return daughterStatus;
433 }
434 
436 {
437  auto daughters = mcParticle->getDaughters();
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++;
443  }
444  }
445  return daughters.size() - number_of_neutrinos;
446 }
447 
448 bool MCMatching::isFSP(int pdg)
449 {
450  switch (abs(pdg)) {
451  case 211:
452  case 321:
453  case 11:
454  case 12:
455  case 13:
456  case 14:
457  case 16:
458  case 22:
459  case 2212:
460  case 310: // K0S
461  case 130: // K0L
462  case 2112:
463  return true;
464  default:
465  return false;
466  }
467 }
468 
470 {
471  return p->hasStatus(MCParticle::c_IsFSRPhoton);
472 }
473 
475 {
476  // In older versions of MC MCParticles don't have c_IsFSRPhoton, c_IsISRPhoton or c_ISPHOTOSPhoton bits
477  // properly set. Instead this approximation is used to check if given photon is radiative (physics) photon
478  // or produced by PHOTOS (FSR).
479 
480  const MCParticle* mother = p->getMother();
481  if (!mother) {
482  B2ERROR("The hell? why would this gamma not have a mother?");
483  return false; //?
484  }
485 
486  int ndaug = mother->getNDaughters();
487  if (ndaug > 2) { // M -> A B (...) gamma is probably FSR
488  return true;
489  } else { // M -> A gamma is probably a decay
490  return false;
491  }
492 }
493 
494 
496 {
497  // Check if any of the bits c_IsFSRPhoton, c_IsISRPhoton or c_ISPHOTOSPhoton is set
498  return p->getStatus(MCParticle::c_IsRadiativePhoton) != 0;
499 }
500 
501 
502 int MCMatching::getMissingParticleFlags(const Particle* particle, const MCParticle* mcParticle)
503 {
504  int flags = 0;
505 
506  vector<const MCParticle*> genParts;
507  appendParticles(mcParticle, genParts);
508 
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);
515  }
516 
517 
518  for (const MCParticle* genPart : genParts) {
519 
520  // if genPart exists in mcMatchedParticles, continue.
521  if (mcMatchedParticles.find(genPart) != mcMatchedParticles.end())
522  continue;
523 
524  //we want to set a flag, so what kind of particle is genPart?
525  const int generatedPDG = genPart->getPDG();
526  const int absGeneratedPDG = abs(generatedPDG);
527 
528  if (!isFSP(generatedPDG)) {
529  flags |= c_MissingResonance;
530  } else if (generatedPDG == Const::photon.getPDGCode()) { //missing photon
531  if (AnalysisConfiguration::instance()->useLegacyMCMatching()) {
532  if (flags & (c_MissFSR | c_MissGamma)) {
533  // if flags already have c_MissFSR or c_MissGamm, do nothing.
534  } else {
535  if (isFSRLegacy(genPart)) {
536  flags |= c_MissFSR;
537  flags |= c_MissPHOTOS;
538  } else {
539  flags |= c_MissGamma;
540  }
541  }
542  } else {
543  if (isFSR(genPart))
544  flags |= c_MissFSR;
545  else if (genPart->hasStatus(MCParticle::c_IsPHOTOSPhoton))
546  flags |= c_MissPHOTOS;
547  else
548  flags |= c_MissGamma;
549  }
550  } else if (absGeneratedPDG == 12 || absGeneratedPDG == 14 || absGeneratedPDG == 16) { // missing neutrino
551  flags |= c_MissNeutrino;
552  } else { //neither photon nor neutrino -> massive
553  flags |= c_MissMassiveParticle;
554  if (absGeneratedPDG == 130)
555  flags |= c_MissKlong;
556  }
557  }
558  return flags;
559 }
560 
561 int MCMatching::countMissingParticle(const Particle* particle, const MCParticle* mcParticle, const vector<int>& daughterPDG)
562 {
563  unordered_set<const MCParticle*> mcMatchedParticles;
564  // Missing particles which are accepted by the property flags are NOT stored.
565  // --> Such particles are also counted in nMissingDaughter.
566  appendParticles(particle, mcMatchedParticles);
567  vector<const MCParticle*> genParts;
568  appendParticles(mcParticle, genParts);
569 
570  int nMissingDaughter = 0;
571 
572  for (const MCParticle* genPart : genParts) {
573  const bool missing = (mcMatchedParticles.find(genPart) == mcMatchedParticles.end());
574  if (missing) {
575 
576  const int generatedPDG = genPart->getPDG();
577  const int absGeneratedPDG = abs(generatedPDG);
578 
579  auto result = find(daughterPDG.begin(), daughterPDG.end(), absGeneratedPDG);
580  if (result != daughterPDG.end())
581  nMissingDaughter++;
582  }
583  }
584 
585  return nMissingDaughter;
586 }
587 
589 {
590  int flags = 0;
591 
592  if (part->getProperty() & Particle::PropertyFlags::c_IsIgnoreBrems) flags |= (MCMatching::c_AddedRecoBremsPhoton);
593 
594  return flags;
595 }
596 
597 int MCMatching::makeDaughterAcceptMask(int daughterProperty)
598 {
599  int flags = 0;
600 
601  if (daughterProperty & Particle::PropertyFlags::c_IsIgnoreMisID) flags |= (MCMatching::c_MisID);
602  if (daughterProperty & Particle::PropertyFlags::c_IsIgnoreDecayInFlight) flags |= (MCMatching::c_DecayInFlight);
603 
604  return (~flags);
605 
606 }
Belle2::MCParticle::getIndex
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:241
Belle2::Const::photon
static const ParticleType photon
photon particle
Definition: Const.h:547
Belle2::MCMatching::setMCErrorsExtraInfo
static int setMCErrorsExtraInfo(Belle2::Particle *particle, const Belle2::MCParticle *mcParticle)
Sets error flags in extra-info (also returns it).
Definition: MCMatching.cc:293
Belle2::MCMatching::countMissingParticle
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'.
Definition: MCMatching.cc:561
Belle2::MCParticle::c_IsPHOTOSPhoton
@ c_IsPHOTOSPhoton
bit 8: Particle is an radiative photon from PHOTOS
Definition: MCParticle.h:74
Belle2::MCMatching::getFlagsOfDaughters
static int getFlagsOfDaughters(const Particle *daughter, const MCParticle *mcParticle)
Returns flags of daughters of given particle.
Definition: MCMatching.cc:371
Belle2::MCMatching::isFSP
static bool isFSP(int pdg)
Returns true if given PDG code indicates a FSP.
Definition: MCMatching.cc:448
Belle2::MCMatching::findCommonMother
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].
Definition: MCMatching.cc:73
Belle2::isFSP
bool isFSP(int pdg)
defines what is a final state particle for this purpose.
Definition: ParticleMCDecayStringModule.cc:201
Belle2::AnalysisConfiguration::instance
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.
Definition: AnalysisConfiguration.h:104
Belle2::MCMatching::getFlagsOfBremsPhotonDaughter
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.
Definition: MCMatching.cc:409
Belle2::MCMatching::isFSR
static bool isFSR(const Belle2::MCParticle *p)
Returns true if given MCParticle is a final state radiation (FSR) photon based on MCParticle::c_IsFSR...
Definition: MCMatching.cc:469
Belle2::MCParticle::c_IsFSRPhoton
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
Definition: MCParticle.h:72
Belle2::MCMatching::c_extraInfoMCErrors
static const std::string c_extraInfoMCErrors
Name of extra-info field stored in Particle.
Definition: MCMatching.h:42
Belle2::MCMatching::c_DecayInFlight
@ c_DecayInFlight
A Particle was reconstructed from the secondary decay product of the actual particle.
Definition: MCMatching.h:49
Belle2::Const::ParticleType::getPDGCode
int getPDGCode() const
PDG code.
Definition: Const.h:349
Belle2::RelationsInterface::getRelatedTo
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
Definition: RelationsObject.h:250
Belle2::MCMatching::fillGenMothers
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.
Definition: MCMatching.cc:64
Belle2::MCMatching::isRadiativePhoton
static bool isRadiativePhoton(const Belle2::MCParticle *p)
Returns true if given MCParticle is a radiative photon.
Definition: MCMatching.cc:495
Belle2::Particle::c_Flavored
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:97
Belle2::MCParticle::hasStatus
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:140
Belle2::MCMatching::getFlagsIgnoredByProperty
static int getFlagsIgnoredByProperty(const Belle2::Particle *particle)
Returns the flags ignored by PropertyFlags of given particle.
Definition: MCMatching.cc:588
Belle2::MCMatching::explainFlags
static std::string explainFlags(unsigned int flags)
Return string with all human-readable flags, e.g.
Definition: MCMatching.cc:29
Belle2::Particle::EFlavorType
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:95
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::MCMatching::isFSRLegacy
static bool isFSRLegacy(const Belle2::MCParticle *p)
Returns true if given MCParticle is a final state radiation (FSR) photon.
Definition: MCMatching.cc:474
Belle2::MCMatching::getMissingParticleFlags
static int getMissingParticleFlags(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle)
Determines which daughters of 'mcParticle' are not reconstructed by any daughter of 'particle'.
Definition: MCMatching.cc:502
Belle2::MCParticle::getPDG
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:123
Belle2::Particle::c_Unflavored
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:96
Belle2::MCParticle::getMother
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition: MCParticle.h:593
Belle2::MCMatching::c_MisID
@ c_MisID
One of the charged final state particles is mis-identified.
Definition: MCMatching.h:54
Belle2::MCParticle::getDaughters
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition: MCParticle.cc:51
Belle2::MCParticle::c_IsRadiativePhoton
@ c_IsRadiativePhoton
combined flag to test whether the particle is radiative
Definition: MCParticle.h:76
Belle2::Particle
Class to store reconstructed particles.
Definition: Particle.h:77
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
Belle2::StoreArray< MCParticle >
Belle2::MCMatching::getFlagsOfFSP
static int getFlagsOfFSP(const Particle *particle, const MCParticle *mcParticle)
Returns flags of given Final State Particle.
Definition: MCMatching.cc:343
Belle2::MCMatching::setMCTruth
static bool setMCTruth(const Belle2::Particle *particle)
This is the main function of MC matching algorithm.
Definition: MCMatching.cc:89
Belle2::MCMatching::c_AddedRecoBremsPhoton
@ c_AddedRecoBremsPhoton
A photon added with the bremsstrahlung recovery tools (correctBrems or correctBremsBelle) has no MC p...
Definition: MCMatching.h:58
Belle2::MCMatching::getMCErrors
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...
Definition: MCMatching.cc:282
Belle2::MCMatching::getNumberOfDaughtersWithoutNeutrinos
static int getNumberOfDaughtersWithoutNeutrinos(const MCParticle *mcParticle)
Determines the number of daughter particles which are not neutrinos.
Definition: MCMatching.cc:435
Belle2::StoreArray::getEntries
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:226
Belle2::MCParticle::c_PrimaryParticle
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:58
Belle2::MCMatching::makeDaughterAcceptMask
static int makeDaughterAcceptMask(int daughterProperty)
Returns the daughter mask from given daughterProperty.
Definition: MCMatching.cc:597