Belle II Software light-2511-gacrux
MCMatcherParticlesModule.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/modules/MCMatcherParticles/MCMatcherParticlesModule.h>
10
11// utility
12#include <analysis/utility/MCMatching.h>
13#include <analysis/utility/AnalysisConfiguration.h>
14
15// map
16#include <unordered_map>
17#include <algorithm>
18typedef std::unordered_map<unsigned int, unsigned int> CounterMap;
19
20using namespace std;
21using namespace Belle2;
22
23//-----------------------------------------------------------------
24// Register module
25//-----------------------------------------------------------------
26
27REG_MODULE(MCMatcherParticles);
28
29//-----------------------------------------------------------------
30// Implementation
31//-----------------------------------------------------------------
32
34{
35 setDescription("Performs MC matching (sets relation Particle->MCParticle) for all particles\n"
36 "(and its (grand)^N-daughter particles) in the ParticleList. The relation can\n"
37 "be used in conjunction with MCMatching::MCErrorFlags flags, e.g. using the\n"
38 "isSignal or mcPDG & mcErrors variables.\n"
39 "\n"
40 "In addition to the usual mc matching algorithm the module can run also loose mc\n"
41 "matching. The difference between loose and normal mc matching algorithm is that\n"
42 "the loose algorithm will find the common mother of the majority of daughter\n"
43 "particles while the normal algorithm finds the common mother of all daughters.\n"
44 "The results of loose mc matching algorithm are stored to the following extraInfo\n"
45 "items:\n\n"
46 "- looseMCMotherPDG: PDG code of most common mother\n"
47 "- looseMCMotherIndex: 1-based StoreArray<MCParticle> index of most common mother\n"
48 "- looseMCWrongDaughterN: number of daughters that don't originate from the most"
49 " common mother\n"
50 "- looseMCWrongDaughterPDG: PDG code of the daughter that doesn't originate from\n"
51 " the most common mother (only if looseMCWrongDaughterN = 1)\n"
52 "- looseMCWrongDaughterBiB: 1 if the wrong daughter is Beam Induced Background Particle\n"
53 "\n"
54 "Can also perform tag matching for (ccbar) tags. Requires that normal MC\n"
55 "matching has already been performed and set relations.\n"
56 "Low energy photons with energy < 0.1 GeV and ISR are ignored.\n"
57 "The results of (ccbar) tag matching algorithm are stored to the following extraInfo\n"
58 "items:\n\n"
59 "- ccbarTagSignal: 1st digit is status of signal particle, 2nd digit is Nleft-1, 3rd digit is NextraFSP.\n"
60 "- ccbarTagMCpdg: PDG code of (charm) hadron outside tag (signal side).\n"
61 "- ccbarTagMCpdgMother: PDG code of the mother of the (charm) hadron outside tag (signal side).\n"
62 "- ccbarTagNleft: number of particles (composites have priority) left outisde tag.\n"
63 "- ccbarTagNextraFSP: number of extra FSP particles attached to the tag.\n"
64 "- ccbarTagSignalStatus: status of the targeted signal side particle.\n"
65 "- ccbarTagNwoMC: number of daughters without MC match.\n"
66 "- ccbarTagNwoMCMother: number of daughters without MC mother.\n"
67 "- ccbarTagNnoAllMother: number of daughters without common allmother.\n"
68 "- ccbarTagNmissGamma: number of daughters with missing gamma mc error.\n"
69 "- ccbarTagNmissNeutrino: number of daughters with missing neutrino mc error.\n"
70 "- ccbarTagNdecayInFlight: number of daughters with decay in flight mc error.\n"
71 "- ccbarTagNsevereMCError: number of daughters with severe mc error.\n"
72 "- ccbarTagNmissRecoDaughters: number of daughters with any mc error.\n"
73 "- ccbarTagNleft2ndPDG: PDG of one particle left additionally to the signal particle.\n"
74 "- ccbarTagAllMotherPDG: PDG code of the allmother (Z0 or virtual photon).");
75
77
78 addParam("listName", m_listName, "Name of the input ParticleList.");
79 addParam("looseMCMatching", m_looseMatching, "Perform loose mc matching", false);
80 addParam("ccbarTagMatching", m_ccbarTagMatching, "Perform ccbar tag matching", false);
81}
82
83
85{
86 // check that there are MCParticles: shout if not
87 if (!m_mcparticles.isValid()) {
88 B2WARNING("No MCParticles array found!"
89 << " This is obvously fine if you're analysing real data,"
90 << " but you have added the MCMatcher module to your path,"
91 << " did you mean to do this?");
92 return;
93 }
94
95 // if we have MCParticles then continue with the initialisation
96 m_particles.isRequired();
97 m_particles.registerRelationTo(m_mcparticles);
98 m_plist.isRequired(m_listName);
99
100 bool legacyAlgorithm = AnalysisConfiguration::instance()->useLegacyMCMatching();
101 B2INFO("MCMatcher module will search for Particle -> MCParticle associations for the ParticleList " << m_listName << ".");
102 if (legacyAlgorithm)
103 B2INFO(" - The MCMatcher will use legacy algorithm suitable for analysis of Belle MC.");
104 else
105 B2INFO(" - The MCMatcher will use default algorithm suitable for analysis of Belle II MC.");
106}
107
108
110{
111 // if no MCParticles then silently skip
112 if (!m_mcparticles.isValid())
113 return;
114 if (!m_plist) {
115 B2ERROR("ParticleList " << m_listName << " not found");
116 return;
117 }
118
119 const unsigned int n = m_plist->getListSize();
120 for (unsigned i = 0; i < n; i++) {
121 const Particle* part = m_plist->getParticle(i);
122
124
125 if (m_looseMatching)
126 setLooseMCMatch(part);
127
129 setCCbarTagMatch(part);
130 }
131}
132
134{
135 if (particle->hasExtraInfo("looseMCMotherPDG")) // nothing to do; already set
136 return;
137
138 // get all FS daughters
139 vector<const Particle*> fsDaughters = particle->getFinalStateDaughters();
140
141 // map for counting how many times given mcparticle is mother of daughters
142 CounterMap motherCount;
143
144 for (auto daughter : fsDaughters) {
145 const MCParticle* mcDaughter = daughter->getRelatedTo<MCParticle>();
146 if (!mcDaughter)
147 continue;
148
149 vector<int> genMothers;
150 MCMatching::fillGenMothers(mcDaughter, genMothers);
151
152 for (auto motherIndex : genMothers) {
153 // exclude ROOT particles: Upsilon(nS), virtual photon
154 int motherPDG = m_mcparticles[motherIndex - 1]->getPDG();
155 if ((motherPDG == 553) ||
156 (motherPDG == 100553) ||
157 (motherPDG == 200553) ||
158 (motherPDG == 300553) ||
159 (motherPDG == 9000553) ||
160 (motherPDG == 9010553) ||
161 (motherPDG == 10022))
162 continue;
163
164 motherCount[motherIndex]++;
165 }
166 }
167
168 // find first most common mother
169 auto commonMother = std::max_element
170 (
171 motherCount.begin(), motherCount.end(),
172 [](std::pair <unsigned int, unsigned int> p1, std::pair <unsigned int, unsigned int> p2) {
173 bool returnValue = false;
174 if (p1.second < p2.second)
175 returnValue = true;
176 else if (p1.second == p2.second)
177 returnValue = p2.first > p1.first;
178
179 return returnValue;
180 }
181 );
182
183 // No common mother found, all daughters have no associated MC Particle
184 if (commonMother == motherCount.end()) {
185 Particle* thisParticle = m_particles[particle->getArrayIndex()];
186 thisParticle->addExtraInfo("looseMCMotherPDG", -1);
187 thisParticle->addExtraInfo("looseMCMotherIndex", -1);
188 thisParticle->addExtraInfo("looseMCWrongDaughterN", -1);
189 thisParticle->addExtraInfo("looseMCWrongDaughterPDG", -1);
190 thisParticle->addExtraInfo("looseMCWrongDaughterBiB", -1);
191 return;
192 }
193
194 const MCParticle* mcMother = m_mcparticles[commonMother->first - 1];
195
196 Particle* thisParticle = m_particles[particle->getArrayIndex()];
197 thisParticle->addExtraInfo("looseMCMotherPDG", mcMother->getPDG());
198 thisParticle->addExtraInfo("looseMCMotherIndex", mcMother->getArrayIndex());
199 thisParticle->addExtraInfo("looseMCWrongDaughterN", fsDaughters.size() - commonMother->second);
200
201 // find out what kind of particle was wrongly added
202 // only for the case where there is only one such particle
203 // This is the most interesting case. If two or more
204 // particles are wrongly added, then a candidate looks
205 // like background
206 int wrongParticlePDG = 0; // PDG code of the wrongly matched particle
207 int wrongParticleBiB = 0; // true (false) if particle doesn't (does) have MCParticle relation
208 if (fsDaughters.size() - commonMother->second == 1) {
209 for (auto daughter : fsDaughters) {
210 const MCParticle* mcDaughter = daughter->getRelatedTo<MCParticle>();
211 if (!mcDaughter) {
212 wrongParticlePDG = daughter->getPDGCode();
213 wrongParticleBiB = 1;
214 }
215
216 vector<int> genMothers;
217 MCMatching::fillGenMothers(mcDaughter, genMothers);
218
219 // check if current daughter descends from common mother
220 if (find(genMothers.begin(), genMothers.end(), commonMother->first) != genMothers.end())
221 continue;
222
223 // daughter is not a child of common mother
224 wrongParticlePDG = daughter->getPDGCode();
225 }
226 }
227
228 thisParticle->addExtraInfo("looseMCWrongDaughterPDG", wrongParticlePDG);
229 thisParticle->addExtraInfo("looseMCWrongDaughterBiB", wrongParticleBiB);
230
231}
232
233
235 const MCParticle* mcParticle,
236 std::vector<const Particle*>& fspParticles,
237 std::vector<const MCParticle*>& missedParticles
238)
239{
240 bool CaughtAll = true;
241 bool missedAll = true;
242 for (auto& mcDaughter : mcParticle->getDaughters()) {
243
244 auto it = std::find_if(fspParticles.begin(), fspParticles.end(), [mcDaughter](const Particle * fsp) { return fsp->getMCParticle() == mcDaughter; });
245 if (it != fspParticles.end()) {
246 fspParticles.erase(it);
247 missedAll = false;
248 } else {
249 if (mcDaughter->getPDG() == Const::photon.getPDGCode() && (mcDaughter->getEnergy() < 0.1
250 or mcDaughter->hasStatus(MCParticle::c_IsISRPhoton))) {
251 continue; // ignore radiative photons with energy < 0.1 GeV and ISR as if they are not in the event
252 }
253 // Belle MC legacy remnants
254 if (abs(mcDaughter->getPDG()) == 21) continue; // ignore gluons
255 if (abs(mcDaughter->getPDG()) == 1) continue; // ignore down quarks
256 if (abs(mcDaughter->getPDG()) == 2) continue; // ignore up quarks
257 if (abs(mcDaughter->getPDG()) == 3) continue; // ignore strange quarks
258 if (abs(mcDaughter->getPDG()) == 4) continue; // ignore charm quarks
259 if (abs(mcDaughter->getPDG()) == 5) continue; // ignore bottom quarks
260 if (abs(mcDaughter->getPDG()) == 6) continue; // ignore top quarks
261 // TODO are there any other particles that should be ignored, due to Belle MC generation?
262
263 else if (mcDaughter->getNDaughters() == 0) {
264 missedParticles.push_back(mcDaughter);
265 CaughtAll = false;
266 } else {
267 std::vector<const MCParticle*> tempMissedParticles;
268 int status = ccbarTagPartialHelper(mcDaughter, fspParticles, tempMissedParticles);
269 if (status == 0) {
270 missedParticles.push_back(mcDaughter);
271 CaughtAll = false;
272 } else if (status == 1) {
273 missedAll = false; // tempMissedParticles is empty
274 } else {
275 missedAll = false;
276 CaughtAll = false;
277 missedParticles.insert(missedParticles.end(), tempMissedParticles.begin(), tempMissedParticles.end());
278 }
279 }
280 }
281
282 }
283
284 if (missedAll) return 0;
285 else if (CaughtAll) return 1;
286 else return 2;
287}
288
289
291 const MCParticle* mcParticle,
292 const std::vector<const Particle*>& fspParticles
293)
294{
295 bool CaughtAll = true;
296 bool missedAll = true;
297 for (auto& mcDaughter : mcParticle->getDaughters()) {
298 if (mcDaughter->getPDG() == Const::photon.getPDGCode()
299 && mcDaughter->getEnergy() < 0.1) continue; // ignore radiative photons with energy < 0.1 GeV as if they are not in the event
300 auto it = std::find_if(fspParticles.begin(), fspParticles.end(), [mcDaughter](const Particle * fsp) { return fsp->getMCParticle() == mcDaughter; });
301 if (it != fspParticles.end()) missedAll = false;
302 else if (mcDaughter->getNDaughters() == 0) CaughtAll = false;
303 else {
304 int status = ccbarTagPartialHelper(mcDaughter, fspParticles);
305 if (status == 0) CaughtAll = false;
306 else if (status == 1) missedAll = false;
307 else {
308 missedAll = false;
309 CaughtAll = false;
310 }
311 }
312 }
313 if (missedAll) return 0;
314 else if (CaughtAll) return 1;
315 else return 2;
316}
317
318
320{
321 if (particle->hasExtraInfo("ccbarTagSignalStatus")) // nothing to do; already set
322 return;
323 int ccbarTagSignal = 0;
324 Particle* thisParticle = m_particles[particle->getArrayIndex()];
325
326 // get Z0, virtual photon
327 StoreArray<MCParticle> mcparticles;
328 const MCParticle* allMother = nullptr;
329 for (int i = 0; i < mcparticles.getEntries(); i++) {
330 if (abs(mcparticles[i]->getPDG()) == 23 ||
331 abs(mcparticles[i]->getPDG()) == 553 ||
332 abs(mcparticles[i]->getPDG()) == 100553 ||
333 abs(mcparticles[i]->getPDG()) == 200553 ||
334 abs(mcparticles[i]->getPDG()) == 300553 ||
335 abs(mcparticles[i]->getPDG()) == 9000553 ||
336 abs(mcparticles[i]->getPDG()) == 9010553 ||
337 abs(mcparticles[i]->getPDG()) == 10022) {
338 allMother = mcparticles[i];
339 break;
340 }
341 }
342 if (!allMother) {
343 B2WARNING("MCMatcherParticlesModule; tag matching - event has no AllMother?");
344 return;
345 }
346 thisParticle->addExtraInfo("ccbarTagAllMotherPDG", allMother->getPDG());
347
348 int sigPDGCode = particle->getPDGCode() * (-1); // get info about signal particles
349 int eventStatus = 0; // default: signal particle is missing
350 for (int i = 0; i < mcparticles.getEntries(); i++) {
351 if (mcparticles[i]->getPDG() == sigPDGCode) {
352 int recStatus = ccbarTagPartialHelper(mcparticles[i], particle->getFinalStateDaughters());
353 if (recStatus == 0) {
354 eventStatus = 1; // 1 still present in event
355 break;
356 } else if (recStatus == 2) eventStatus = 2; // 2 partially reconstructed by tag
357 else if (recStatus == 1 && eventStatus != 2) eventStatus = 3; // 3 fully absorbed by tag
358 }
359 }
360 thisParticle->addExtraInfo("ccbarTagSignalStatus", eventStatus);
361 ccbarTagSignal += eventStatus;
362
363 // recursive TagMCpdg, Nleft particles ---------------------------------
364 std::vector<const Particle*> fspDaughters = particle->getFinalStateDaughters();
365 std::vector<const MCParticle*> missedParticles;
366 ccbarTagPartialHelper(allMother, fspDaughters, missedParticles);
367 bool foundCharm = false;
368 for (auto* mcpart : missedParticles) {
369 int pdg = abs(mcpart->getPDG());
370 if ((pdg > 400 && pdg < 500) || (pdg > 4000 && pdg < 5000) || (pdg > 10400 && pdg < 10500) || (pdg > 20400 && pdg < 20500)) {
371 foundCharm = true;
372 thisParticle->addExtraInfo("ccbarTagMCpdg", mcpart->getPDG());
373 const MCParticle* mcpartMother = mcpart->getMother();
374 int mcpartMotherPDG = 0;
375 if (mcpartMother) mcpartMotherPDG = mcpartMother->getPDG();
376 thisParticle->addExtraInfo("ccbarTagMCpdgMother", mcpartMotherPDG);
377 break;
378 }
379 }
380 if (!foundCharm) {
381 thisParticle->addExtraInfo("ccbarTagMCpdg", 0);
382 thisParticle->addExtraInfo("ccbarTagMCpdgMother", 0);
383 }
384 thisParticle->addExtraInfo("ccbarTagNextraFSP", fspDaughters.size());
385 ccbarTagSignal += 10 * fspDaughters.size();
386 thisParticle->addExtraInfo("ccbarTagNleft", missedParticles.size());
387 ccbarTagSignal += 100 * (missedParticles.size() - 1);
388 thisParticle->addExtraInfo("ccbarTagSignal", ccbarTagSignal);
389
390 // debugging purposes only, to be removed, probably
391 int secondLeftParticle = 0;
392 if (missedParticles.size() == 2) {
393 if (missedParticles[0]->getPDG() == sigPDGCode) secondLeftParticle = missedParticles[1]->getPDG();
394 else if (missedParticles[1]->getPDG() == sigPDGCode) secondLeftParticle = missedParticles[0]->getPDG();
395 }
396 thisParticle->addExtraInfo("ccbarTagNleft2ndPDG", secondLeftParticle);
397
398
399 // daughter and allmother checks
400 int nWOmcParticles = 0;
401 int nWOmother = 0;
402 int nNonCommonAllMother = 0;
403 for (auto& daughter : particle->getDaughters()) {
404 if (!daughter->getMCParticle()) {
405 nWOmcParticles++;
406 continue;
407 }
408 const MCParticle* curMCMother = daughter->getMCParticle()->getMother();
409 if (curMCMother == nullptr) {
410 nWOmother++;
411 continue;
412 }
413
414 const MCParticle* grandMother = curMCMother->getMother();
415 while (grandMother != nullptr) {
416 curMCMother = grandMother;
417 grandMother = curMCMother->getMother();
418 }
419 if (curMCMother->getPDG() != Const::photon.getPDGCode() && curMCMother->getPDG() != 23
420 && curMCMother->getPDG() != 10022) nNonCommonAllMother++;
421 else if (allMother != curMCMother) nNonCommonAllMother++;
422 }
423 thisParticle->addExtraInfo("ccbarTagNwoMC", nWOmcParticles);
424 thisParticle->addExtraInfo("ccbarTagNwoMCMother", nWOmother);
425 thisParticle->addExtraInfo("ccbarTagNnoAllMother", nNonCommonAllMother);
426
427 // daughter mcErrors ---------------------------------
428 int nHasMissingGamma = 0;
429 int nHasMissingNeutrino = 0;
430 int nHasDecayInFlight = 0;
431 int nHasSevereMCError = 0;
432 int nMissRecoDaughters = 0;
433 for (auto& daughter : particle->getDaughters()) { // TODO think about less strict conditions
434 if (daughter->hasExtraInfo("ccbarTagNmissRecoDaughters")) {
435 nHasMissingGamma += daughter->getExtraInfo("ccbarTagNmissGamma");
436 nHasMissingNeutrino += daughter->getExtraInfo("ccbarTagNmissNeutrino");
437 nHasDecayInFlight += daughter->getExtraInfo("ccbarTagNdecayInFlight");
438 nHasSevereMCError += daughter->getExtraInfo("ccbarTagNsevereMCError");
439 nMissRecoDaughters += daughter->getExtraInfo("ccbarTagNmissRecoDaughters");
440 continue;
441 }
442
443 int mcError = MCMatching::getMCErrors(daughter, daughter->getMCParticle());
444 nMissRecoDaughters += 1;
445 if (mcError == MCMatching::c_Correct || mcError == MCMatching::c_MissingResonance) {
446 nMissRecoDaughters -= 1;
447 continue;
448 } else if (mcError == MCMatching::c_MissGamma || mcError == MCMatching::c_MissFSR
449 || mcError == MCMatching::c_MissPHOTOS) nHasMissingGamma += 1;
450 else if (mcError == MCMatching::c_MissNeutrino) nHasMissingNeutrino += 1;
451 else if (mcError == MCMatching::c_DecayInFlight) nHasDecayInFlight += 1;
452 else nHasSevereMCError += 1;
453 }
454 thisParticle->addExtraInfo("ccbarTagNmissGamma", nHasMissingGamma);
455 thisParticle->addExtraInfo("ccbarTagNmissNeutrino", nHasMissingNeutrino);
456 thisParticle->addExtraInfo("ccbarTagNdecayInFlight", nHasDecayInFlight);
457 thisParticle->addExtraInfo("ccbarTagNsevereMCError", nHasSevereMCError);
458 thisParticle->addExtraInfo("ccbarTagNmissRecoDaughters", nMissRecoDaughters);
459}
void useLegacyMCMatching(const bool flag)
Determines whether to use the legacy MCMatching algorithm (true) or not (false).
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.
static const ParticleType photon
photon particle
Definition Const.h:673
void setCCbarTagMatch(const Particle *particle)
Investigates the composition of the tag and remaining signal side and saves the inforamtion to extraI...
int ccbarTagPartialHelper(const MCParticle *mcParticle, std::vector< const Particle * > &fspParticles, std::vector< const MCParticle * > &missedParticles)
returns 1 if the eventParticle daughters were all caught in recParticles, 2 if partially and 0 if non...
virtual void initialize() override
Initialize the Module.
bool m_ccbarTagMatching
perform ccbar tag matching
virtual void event() override
Event processor.
StoreArray< MCParticle > m_mcparticles
the array of MCParticles.
std::string m_listName
steering variable: name of the input ParticleList
StoreArray< Particle > m_particles
the array of Particles.
bool m_looseMatching
perform loose mc matching
void setLooseMCMatch(const Particle *particle)
Finds common mother of the majority of daughters.
StoreObjPtr< ParticleList > m_plist
the input ParticleList.
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
Definition MCParticle.h:59
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition MCParticle.cc:52
int getPDG() const
Return PDG code of particle.
Definition MCParticle.h:101
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
Class to store reconstructed particles.
Definition Particle.h:76
std::vector< const Particle * > getFinalStateDaughters() const
Returns a vector of pointers to Final State daughter particles.
Definition Particle.cc:680
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
Definition Particle.cc:1351
int getPDGCode(void) const
Returns PDG code.
Definition Particle.h:465
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition Particle.cc:1421
std::vector< Particle * > getDaughters() const
Returns a vector of pointers to daughter particles.
Definition Particle.cc:668
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
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
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition MCParticle.h:590
Abstract base class for different kinds of events.
STL namespace.
static bool setMCTruth(const Particle *particle)
This is the main function of MC matching algorithm.
Definition MCMatching.cc:86
@ c_MissFSR
A Final State Radiation (FSR) photon is not reconstructed (based on MCParticle::c_IsFSRPhoton).
Definition MCMatching.h:35
@ 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_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
static void fillGenMothers(const 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 getMCErrors(const Particle *particle, const MCParticle *mcParticle=nullptr)
Returns quality indicator of the match as a bit pattern where the individual bits indicate the the ty...