9 #include <analysis/modules/MCMatcherParticles/MCMatcherParticlesModule.h>
12 #include <analysis/utility/MCMatching.h>
13 #include <analysis/utility/AnalysisConfiguration.h>
16 #include <unordered_map>
18 typedef std::unordered_map<unsigned int, unsigned int> CounterMap;
40 setDescription(
"Performs MC matching (sets relation Particle->MCParticle) for all particles\n"
41 "(and its (grand)^N-daughter particles) in the ParticleList. The relation can\n"
42 "be used in conjunction with MCMatching::MCErrorFlags flags, e.g. using the\n"
43 "isSignal or mcPDG & mcErrors variables.\n"
45 "In addition to the usual mc matching algorithm the module can run also loose mc\n"
46 "matching. The difference between loose and normal mc matching algorithm is that\n"
47 "the loose algorithm will find the common mother of the majority of daughter\n"
48 "particles while the normal algorithm finds the common mother of all daughters.\n"
49 "The results of loose mc matching algorithm are stored to the following extraInfo\n"
51 " - looseMCMotherPDG: PDG code of most common mother\n"
52 " - looseMCMotherIndex: 1-based StoreArray<MCParticle> index of most common mother\n"
53 " - looseMCWrongDaughterN: number of daughters that don't originate from the most\n"
55 " - looseMCWrongDaughterPDG: PDG code of the daughter that doesn't originate from\n"
56 " the most common mother \n"
57 " (only if looseMCWrongDaughterN = 1)\n"
58 " - looseMCWrongDaughterBiB: 1 if the wrong daughter is Beam Induced Background\n"
61 setPropertyFlags(c_ParallelProcessingCertified);
63 addParam(
"listName", m_listName,
"Name of the input ParticleList.");
64 addParam(
"looseMCMatching", m_looseMatching,
"Perform loose mc matching",
false);
68 void MCMatcherParticlesModule::initialize()
71 if (!m_mcparticles.isValid()) {
72 B2WARNING(
"No MCParticles array found!"
73 <<
" This is obvously fine if you're analysing real data,"
74 <<
" but you have added the MCMatcher module to your path,"
75 <<
" did you mean to do this?");
80 m_particles.isRequired();
81 m_particles.registerRelationTo(m_mcparticles);
82 m_plist.isRequired(m_listName);
84 bool legacyAlgorithm = AnalysisConfiguration::instance()->useLegacyMCMatching();
85 B2INFO(
"MCMatcher module will search for Particle -> MCParticle associations for the ParticleList " << m_listName <<
".");
87 B2INFO(
" - The MCMatcher will use legacy algorithm suitable for analysis of Belle MC or Belle II MC5.");
89 B2INFO(
" - The MCMatcher will use default algorithm suitable for analysis of Belle II MC (for MC5 use legacy algorithm).");
93 void MCMatcherParticlesModule::event()
96 if (!m_mcparticles.isValid())
99 B2ERROR(
"ParticleList " << m_listName <<
" not found");
103 const unsigned int n = m_plist->getListSize();
104 for (
unsigned i = 0; i < n; i++) {
105 const Particle* part = m_plist->getParticle(i);
107 MCMatching::setMCTruth(part);
110 setLooseMCMatch(part);
114 void MCMatcherParticlesModule::setLooseMCMatch(
const Particle* particle)
116 if (particle->hasExtraInfo(
"looseMCMotherPDG"))
120 vector<const Belle2::Particle*> fsDaughters = particle->getFinalStateDaughters();
123 CounterMap motherCount;
125 for (
auto daughter : fsDaughters) {
130 vector<int> genMothers;
131 MCMatching::fillGenMothers(mcDaughter, genMothers);
133 for (
auto motherIndex : genMothers) {
135 int motherPDG = m_mcparticles[motherIndex - 1]->getPDG();
136 if ((motherPDG == 553) ||
137 (motherPDG == 100553) ||
138 (motherPDG == 200553) ||
139 (motherPDG == 300553) ||
140 (motherPDG == 9000553) ||
141 (motherPDG == 9010553) ||
142 (motherPDG == 10022))
145 motherCount[motherIndex]++;
150 auto commonMother = std::max_element
152 std::begin(motherCount), std::end(motherCount),
153 [](std::pair <unsigned int, unsigned int> p1, std::pair <unsigned int, unsigned int> p2) {
154 bool returnValue =
false;
155 if (p1.second < p2.second)
157 else if (p1.second == p2.second)
158 returnValue = p2.first > p1.first;
165 if (commonMother == std::end(motherCount)) {
166 Particle* thisParticle = m_particles[particle->getArrayIndex()];
169 thisParticle->
addExtraInfo(
"looseMCWrongDaughterN", -1);
170 thisParticle->
addExtraInfo(
"looseMCWrongDaughterPDG", -1);
171 thisParticle->
addExtraInfo(
"looseMCWrongDaughterBiB", -1);
175 const MCParticle* mcMother = m_mcparticles[commonMother->first - 1];
177 Particle* thisParticle = m_particles[particle->getArrayIndex()];
178 thisParticle->
addExtraInfo(
"looseMCMotherPDG", mcMother->getPDG());
179 thisParticle->
addExtraInfo(
"looseMCMotherIndex", mcMother->getArrayIndex());
180 thisParticle->
addExtraInfo(
"looseMCWrongDaughterN", fsDaughters.size() - commonMother->second);
187 int wrongParticlePDG = 0;
188 int wrongParticleBiB = 0;
189 if (fsDaughters.size() - commonMother->second == 1) {
190 for (
auto daughter : fsDaughters) {
193 wrongParticlePDG = daughter->getPDGCode();
194 wrongParticleBiB = 1;
197 vector<int> genMothers;
198 MCMatching::fillGenMothers(mcDaughter, genMothers);
201 if (find(genMothers.begin(), genMothers.end(), commonMother->first) != genMothers.end())
205 wrongParticlePDG = daughter->getPDGCode();
209 thisParticle->
addExtraInfo(
"looseMCWrongDaughterPDG", wrongParticlePDG);
210 thisParticle->
addExtraInfo(
"looseMCWrongDaughterBiB", wrongParticleBiB);
MC matching module: module performs MC matching (sets the relation Particle -> MCParticle) for all pa...
A Class to store the Monte Carlo particle information.
Class to store reconstructed particles.
void addExtraInfo(const std::string &name, float value)
Sets the user-defined data of given name to the given value.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.