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