11 #include <analysis/modules/MCMatcherParticles/MCMatcherParticlesModule.h>
14 #include <analysis/utility/MCMatching.h>
15 #include <analysis/utility/AnalysisConfiguration.h>
18 #include <unordered_map>
20 typedef std::unordered_map<unsigned int, unsigned int> CounterMap;
42 setDescription(
"Performs MC matching (sets relation Particle->MCParticle) for all particles\n"
43 "(and its (grand)^N-daughter particles) in the ParticleList. The relation can\n"
44 "be used in conjuction with MCMatching::MCErrorFlags flags, e.g. using the\n"
45 "isSignal or mcPDG & mcErrors variables.\n"
47 "In addition to the usual mc matching algorithm the module can run also loose mc\n"
48 "matching. The difference between loose and normal mc matching algorithm is that\n"
49 "the loose algorithm will find the common mother of the majority of daughter\n"
50 "particles while the normal algorithm finds the common mother of all daughters.\n"
51 "The results of loose mc matching algorithm are stored to the following extraInfo\n"
53 " - looseMCMotherPDG: PDG code of most common mother\n"
54 " - looseMCMotherIndex: 1-based StoreArray<MCParticle> index of most common mother\n"
55 " - looseMCWrongDaughterN: number of daughters that don't originate from the most\n"
57 " - looseMCWrongDaughterPDG: PDG code of the daughter that doesn't orginate from\n"
58 " the most common mother \n"
59 " (only if looseMCWrongDaughterN = 1)\n"
60 " - looseMCWrongDaughterBiB: 1 if the wrong daughter is Beam Induced Background\n"
63 setPropertyFlags(c_ParallelProcessingCertified);
65 addParam(
"listName", m_listName,
"Name of the input ParticleList.");
66 addParam(
"looseMCMatching", m_looseMatching,
"Perform loose mc matching",
false);
70 void MCMatcherParticlesModule::initialize()
73 if (!m_mcparticles.isValid()) {
74 B2WARNING(
"No MCParticles array found!"
75 <<
" This is obvously fine if you're analysing real data,"
76 <<
" but you have added the MCMatcher module to your path,"
77 <<
" did you mean to do this?");
82 m_particles.isRequired();
83 m_particles.registerRelationTo(m_mcparticles);
84 m_plist.isRequired(m_listName);
86 bool legacyAlgorithm = AnalysisConfiguration::instance()->useLegacyMCMatching();
87 B2INFO(
"MCMatcher module will search for Particle -> MCParticle associations for the ParticleList " << m_listName <<
".");
89 B2INFO(
" - The MCMatcher will use legacy algorithm suitable for analysis of Belle MC or Belle II MC5.");
91 B2INFO(
" - The MCMatcher will use default algorithm suitable for analysis of Belle II MC (for MC5 use legacy algorithm).");
95 void MCMatcherParticlesModule::event()
98 if (!m_mcparticles.isValid())
101 B2ERROR(
"ParticleList " << m_listName <<
" not found");
105 const unsigned int n = m_plist->getListSize();
106 for (
unsigned i = 0; i < n; i++) {
107 const Particle* part = m_plist->getParticle(i);
109 MCMatching::setMCTruth(part);
112 setLooseMCMatch(part);
116 void MCMatcherParticlesModule::setLooseMCMatch(
const Particle* particle)
118 if (particle->hasExtraInfo(
"looseMCMotherPDG"))
122 vector<const Belle2::Particle*> fsDaughters = particle->getFinalStateDaughters();
125 CounterMap motherCount;
127 for (
auto daughter : fsDaughters) {
132 vector<int> genMothers;
133 MCMatching::fillGenMothers(mcDaughter, genMothers);
135 for (
auto motherIndex : genMothers) {
137 int motherPDG = m_mcparticles[motherIndex - 1]->getPDG();
138 if ((motherPDG == 553) ||
139 (motherPDG == 100553) ||
140 (motherPDG == 200553) ||
141 (motherPDG == 300553) ||
142 (motherPDG == 9000553) ||
143 (motherPDG == 9010553) ||
144 (motherPDG == 10022))
147 motherCount[motherIndex]++;
152 auto commonMother = std::max_element
154 std::begin(motherCount), std::end(motherCount),
155 [](std::pair <unsigned int, unsigned int> p1, std::pair <unsigned int, unsigned int> p2) {
156 bool returnValue =
false;
157 if (p1.second < p2.second)
159 else if (p1.second == p2.second)
160 returnValue = p2.first > p1.first;
167 if (commonMother == std::end(motherCount)) {
168 Particle* thisParticle = m_particles[particle->getArrayIndex()];
171 thisParticle->
addExtraInfo(
"looseMCWrongDaughterN", -1);
172 thisParticle->
addExtraInfo(
"looseMCWrongDaughterPDG", -1);
173 thisParticle->
addExtraInfo(
"looseMCWrongDaughterBiB", -1);
177 const MCParticle* mcMother = m_mcparticles[commonMother->first - 1];
179 Particle* thisParticle = m_particles[particle->getArrayIndex()];
180 thisParticle->
addExtraInfo(
"looseMCMotherPDG", mcMother->getPDG());
181 thisParticle->
addExtraInfo(
"looseMCMotherIndex", mcMother->getArrayIndex());
182 thisParticle->
addExtraInfo(
"looseMCWrongDaughterN", fsDaughters.size() - commonMother->second);
189 int wrongParticlePDG = 0;
190 int wrongParticleBiB = 0;
191 if (fsDaughters.size() - commonMother->second == 1) {
192 for (
auto daughter : fsDaughters) {
195 wrongParticlePDG = daughter->getPDGCode();
196 wrongParticleBiB = 1;
199 vector<int> genMothers;
200 MCMatching::fillGenMothers(mcDaughter, genMothers);
203 if (find(genMothers.begin(), genMothers.end(), commonMother->first) != genMothers.end())
207 wrongParticlePDG = daughter->getPDGCode();
211 thisParticle->
addExtraInfo(
"looseMCWrongDaughterPDG", wrongParticlePDG);
212 thisParticle->
addExtraInfo(
"looseMCWrongDaughterBiB", wrongParticleBiB);