Belle II Software development
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
21using namespace Belle2;
22using namespace std;
23
24const std::string MCMatching::c_extraInfoMCErrors = "mcErrors";
25
26std::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
61void 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
70int 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
86bool 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()
172namespace {
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 (mcParticle and 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);
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()) and gen->getPDG() != Const::Kshort.getPDGCode())
213 return; //stop at the bottom of the MC decay tree (ignore secondaries)
214
215 // Ks that decays interacting with materials can have additional daughters not only 2-pions.
216 // To check the missing daughters, the exception for Ks is introduced.
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)) {
235 return true;
236 } else if (absPDG == Const::photon.getPDGCode()) { // gamma
238 or (AnalysisConfiguration::instance()->useLegacyMCMatching() and MCMatching::isFSRLegacy(mcDaug))) {
240 return true;
241 } else {
243 return true;
244 }
245 } else if (absPDG == 12 or absPDG == 14 or absPDG == 16) { // neutrino
247 return true;
248 } else { // otherwise, massive FSP
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
282int 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
293int MCMatching::setMCErrorsExtraInfo(Particle* particle, const MCParticle* mcParticle)
294{
295 auto setStatus = [](Particle * part, int s) -> int {
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))
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.
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
343int MCMatching::getFlagsOfFSP(const Particle* particle, const MCParticle* mcParticle)
344{
345 if (particle->getPDGCode() == mcParticle->getPDG())
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.
352 } else {
353 // secondary particle, so the original particle probably decayed
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) {
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
371int 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
409int 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 daughter 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
448bool MCMatching::isFSP(int pdg)
449{
450 switch (abs(pdg)) {
451 case 211: // pi
452 case 321: // K
453 case 11: // e
454 case 12: // nu_e
455 case 13: // mu
456 case 14: // nu_mu
457 case 16: // nu_tau
458 case 22: // gamma
459 case 2212: // proton
460 case 310: // K0S
461 case 130: // K0L
462 case 2112: // neutron
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
502int 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 == Const::Klong.getPDGCode())
555 flags |= c_MissKlong;
556 }
557 }
558 return flags;
559}
560
561int 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
593
594 return flags;
595}
596
597int MCMatching::makeDaughterAcceptMask(int daughterProperty)
598{
599 int flags = 0;
600
601 if (daughterProperty & Particle::PropertyFlags::c_IsIgnoreMisID) flags |= (MCMatching::c_MisID);
603
604 return (~flags);
605
606}
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.
int getPDGCode() const
PDG code.
Definition: Const.h:473
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:678
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:677
static const ParticleType photon
photon particle
Definition: Const.h:673
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:52
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:129
int getNDaughters() const
Return number of daughter MCParticles.
Definition: MCParticle.cc:75
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
Class to store reconstructed particles.
Definition: Particle.h:75
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
Definition: Particle.cc:1266
int getProperty() const
Returns particle property as a bit pattern The values are defined in the PropertyFlags enum and descr...
Definition: Particle.h:498
unsigned getNDaughters(void) const
Returns number of daughter particles.
Definition: Particle.h:727
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition: Particle.cc:1336
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:94
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:95
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:96
@ c_IsIgnoreNeutrino
Is the particle MC matched with the ignore missing neutrino flag set?
Definition: Particle.h:122
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
Definition: Particle.h:119
@ c_IsIgnoreGamma
Is the particle MC matched with the ignore missing gamma flag set?
Definition: Particle.h:123
@ c_IsUnspecified
Ordinary particles.
Definition: Particle.h:118
@ c_IsIgnoreBrems
Is the particle MC matched with the ignore added Brems gamma flag set?
Definition: Particle.h:124
@ c_IsIgnoreDecayInFlight
Is the particle MC matched with the ignore DecayInFlight flag set?
Definition: Particle.h:126
@ c_IsIgnoreMisID
Is the particle MC matched with the ignore MisID flag set?
Definition: Particle.h:125
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
Definition: Particle.h:120
@ c_IsIgnoreMassive
Is the particle MC matched with the ignore missing massive particle flag set?
Definition: Particle.h:121
double getExtraInfo(const std::string &name) const
Return given value if set.
Definition: Particle.cc:1289
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.
Definition: StoreArray.h:113
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition: MCParticle.h:600
Abstract base class for different kinds of events.
STL namespace.
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
static std::string explainFlags(unsigned int flags)
Return string with all human-readable flags, e.g.
Definition: MCMatching.cc:26
@ c_MissMassiveParticle
A generated massive FSP is missing (not reconstructed).
Definition: MCMatching.h:40
@ c_MissFSR
A Final State Radiation (FSR) photon is not reconstructed (based on MCParticle::c_IsFSRPhoton).
Definition: MCMatching.h:35
@ c_AddedWrongParticle
A non-FSP Particle has wrong PDG code, meaning one of the daughters (or their daughters) belongs to a...
Definition: MCMatching.h:43
@ c_MissNeutrino
A neutrino is missing (not reconstructed).
Definition: MCMatching.h:38
@ c_Correct
This Particle and all its daughters are perfectly reconstructed.
Definition: MCMatching.h:34
@ c_DecayInFlight
A Particle was reconstructed from the secondary decay product of the actual particle.
Definition: MCMatching.h:37
@ c_InternalError
There was an error in MC matching.
Definition: MCMatching.h:44
@ c_MissingResonance
The associated MCParticle decay contained additional non-final-state particles (e....
Definition: MCMatching.h:36
@ c_MissPHOTOS
A photon created by PHOTOS was not reconstructed (based on MCParticle::c_IsPHOTOSPhoton)
Definition: MCMatching.h:45
@ c_MissGamma
A photon (not FSR) is missing (not reconstructed).
Definition: MCMatching.h:39
@ c_MisID
One of the charged final state particles is mis-identified, i.e.
Definition: MCMatching.h:42
@ c_MissKlong
A Klong is missing (not reconstructed).
Definition: MCMatching.h:41
@ 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:495
static int makeDaughterAcceptMask(int daughterProperty)
Returns the daughter mask from given daughterProperty.
Definition: MCMatching.cc:597
static int getNumberOfDaughtersWithoutNeutrinos(const MCParticle *mcParticle)
Determines the number of daughter particles which are not neutrinos.
Definition: MCMatching.cc:435
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
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:343
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
static int getFlagsOfDaughters(const Particle *daughter, const MCParticle *mcParticle)
Returns flags of daughters of given particle.
Definition: MCMatching.cc:371
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
static bool isFSRLegacy(const Belle2::MCParticle *p)
Returns true if given MCParticle is a final state radiation (FSR) photon.
Definition: MCMatching.cc:474
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:293
static int getFlagsIgnoredByProperty(const Belle2::Particle *particle)
Returns the flags ignored by PropertyFlags of given particle.
Definition: MCMatching.cc:588
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
static bool isFSP(int pdg)
Returns true if given PDG code indicates a FSP.
Definition: MCMatching.cc:448
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