Belle II Software development
ParticleCombinerFromMCModule.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// Own header.
10#include <analysis/modules/ParticleCombinerFromMC/ParticleCombinerFromMCModule.h>
11
12// framework aux
13#include <framework/logging/Logger.h>
14
15// decay descriptor
16#include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
17#include <analysis/DecayDescriptor/ParticleListName.h>
18
19#include <analysis/ParticleCombiner/ParticleCombiner.h>
20
21// utilities
22#include <analysis/utility/MCMatching.h>
23
24#include <memory>
25
26using namespace std;
27using namespace Belle2;
28
29//-----------------------------------------------------------------
30// Register module
31//-----------------------------------------------------------------
32
33REG_MODULE(ParticleCombinerFromMC);
34
35//-----------------------------------------------------------------
36// Implementation
37//-----------------------------------------------------------------
38
40 Module()
41
42{
43 // set module description (e.g. insert text)
44 setDescription("Makes particle combinations");
46
47 // Add parameters
48 addParam("decayString", m_decayString,
49 "Input DecayDescriptor string (see :ref:`DecayString`).");
50 addParam("cut", m_cutParameter, "Selection criteria to be applied", std::string(""));
51 addParam("decayMode", m_decayModeID, "User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
52 0);
53
54 addParam("writeOut", m_writeOut,
55 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", false);
56 addParam("chargeConjugation", m_chargeConjugation,
57 "If true, the charge-conjugated mode will be reconstructed as well", true);
58
59 // initializing the rest of private members
60 m_generator = nullptr;
61 m_cut = nullptr;
62}
63
65{
66 // obtain the input and output particle lists from the decay string
67 bool valid = m_decaydescriptor.init(m_decayString);
68 if (!valid)
69 B2ERROR("Invalid input DecayString: " << m_decayString);
70
71 // Mother particle
72 const DecayDescriptorParticle* mother = m_decaydescriptor.getMother();
73
74 m_listName = mother->getFullName();
75
77
78 // register particles which have (sub-)decay recursively
80
81}
82
84{
85 B2DEBUG(10, "event() started !!!");
86
87 // combine particles recursively
89
91 bool existingList = plist.isValid();
92
93 if (!existingList) {
94 B2WARNING("Output list " << m_listName << " was not created");
95 return;
96 }
97
98 // loop over list only if cuts should be applied
99 if (!m_cutParameter.empty()) {
100 std::vector<unsigned int> toRemove;
101 unsigned int n = plist->getListSize();
102 for (unsigned i = 0; i < n; i++) {
103 const Particle* part = plist->getParticle(i);
104
107
108 if (!m_cut->check(part)) toRemove.push_back(part->getArrayIndex());
109 }
110 plist->removeParticles(toRemove);
111 }
112}
113
114
116{
117 int nProducts = decaydescriptor.getNDaughters();
118
119 for (int i = 0; i < nProducts; ++i) {
120 if (decaydescriptor.getDaughter(i)->getNDaughters() == 0) {
121 // if daughter does not have daughters, it must be already registered
122 const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
123 StoreObjPtr<ParticleList>().isRequired(daughter->getFullName());
124 } else {
125 // if daughter has daughters, call the function recursively
126 registerParticleRecursively(*(decaydescriptor.getDaughter(i)));
127 }
128 }
129
130 // Mother particle
131 const DecayDescriptorParticle* mother = decaydescriptor.getMother();
132 std::string listName = mother->getFullName();
133 StoreObjPtr<ParticleList> particleList(listName);
134
135 // if particleList already exists
136 auto existList = std::find(m_vector_listName.begin(), m_vector_listName.end(), listName);
137 if (existList != m_vector_listName.end()) {
138 B2ERROR(listName << " already exist ! You cannot write same sub-decay twice !!!");
139 return;
140 }
141
142 std::string antiListName = ParticleListName::antiParticleListName(listName);
143 bool isSelfConjugatedParticle = (listName == antiListName);
144
146 particleList.registerInDataStore(flags);
147 if (!isSelfConjugatedParticle && m_chargeConjugation) {
148 StoreObjPtr<ParticleList> antiParticleList(antiListName);
149 antiParticleList.registerInDataStore(flags);
150 }
151
152 m_vector_listName.push_back(listName);
153
154}
155
157{
158 // Mother particle
159 const DecayDescriptorParticle* mother = decaydescriptor.getMother();
160 int pdgCode = mother->getPDGCode();
161 std::string listName = mother->getFullName();
162 std::string antiListName = ParticleListName::antiParticleListName(listName);
163 bool isSelfConjugatedParticle = (listName == antiListName);
164
165 StoreObjPtr<ParticleList> outputList(listName);
166 outputList.create();
167 outputList->initialize(pdgCode, listName);
168
169 if (!isSelfConjugatedParticle && m_chargeConjugation) {
170 StoreObjPtr<ParticleList> outputAntiList(antiListName);
171 outputAntiList.create();
172 outputAntiList->initialize(-1 * pdgCode, antiListName);
173
174 outputList->bindAntiParticleList(*(outputAntiList));
175 }
176
177 unsigned int numberOfLists = decaydescriptor.getNDaughters();
178
179 for (unsigned int i = 0; i < numberOfLists; ++i) {
180 const DecayDescriptor* dDaughter = decaydescriptor.getDaughter(i);
181
182 if (dDaughter->getNDaughters() == 0) {
183 // if daughter does not have daughters, check if it is not reconstructed particle.
184 const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
185 StoreObjPtr<ParticleList> plist(daughter->getFullName());
186 // if daughter is not created, returns error
187 if (!plist.isValid())
188 B2ERROR(daughter->getFullName() << " is not created");
189 // if daughter contains reconstructed particles, returns error.
190 unsigned nPart = plist->getListSize();
191 for (unsigned iPart = 0; iPart < nPart; iPart++) {
192 const Particle* part = plist->getParticle(iPart);
194 if (particleType == Particle::c_Track or
195 particleType == Particle::c_ECLCluster or
196 particleType == Particle::c_KLMCluster)
197 B2ERROR(daughter->getFullName() << " contains a reconstructed particle! It is not accepted in ParticleCombinerFromMCModule!");
198 }
199 // if not, do nothing.
200 } else {
201 // if daughter has daughter, call the function recursively
202 combineRecursively(*dDaughter);
203 }
204 }
205
206 // initialize the generator
207 m_generator = std::make_unique<ParticleGenerator>(decaydescriptor, "");
208 m_generator->init();
209
210 while (m_generator->loadNext(m_chargeConjugation)) {
211 Particle&& particle = m_generator->getCurrentParticle();
212
213 Particle* newParticle = m_particles.appendNew(particle);
214 // append to the created particle the user specified decay mode ID
215 newParticle->addExtraInfo("decayModeID", m_decayModeID);
216
217 int iparticle = m_particles.getEntries() - 1;
218 outputList->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
219 }
220
221 // select only signal particles
222 std::unique_ptr<Variable::Cut> cutIsSignal = Variable::Cut::compile("isSignal");
223
224 std::vector<unsigned int> toRemove;
225 unsigned int n = outputList->getListSize();
226 for (unsigned i = 0; i < n; i++) {
227 const Particle* part = outputList->getParticle(i);
228
231
232 if (!cutIsSignal->check(part)) toRemove.push_back(part->getArrayIndex());
233 }
234 outputList->removeParticles(toRemove);
235
236}
EStoreFlags
Flags describing behaviours of objects etc.
Definition DataStore.h:69
@ c_WriteOut
Object/array should be saved by output modules.
Definition DataStore.h:70
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition DataStore.h:71
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
std::string getFullName() const
returns the full name of the particle full_name = name:label
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
int getNDaughters() const
return number of direct daughters.
const DecayDescriptorParticle * getMother() const
return mother.
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Definition GeneralCut.h:84
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
void combineRecursively(const DecayDescriptor &decaydescriptor)
Combine particles which have (sub-)decay recursively.
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
void registerParticleRecursively(const DecayDescriptor &decaydescriptor)
Register particles which have (sub-)decay recursively.
std::string m_decayString
Input DecayString specifying the decay being reconstructed.
std::string m_listName
output particle list name
StoreArray< Particle > m_particles
StoreArray of Particles.
std::unique_ptr< ParticleGenerator > m_generator
Generates the combinations.
std::unique_ptr< Variable::Cut > m_cut
cut object which performs the cuts
int m_decayModeID
user specified decay mode identifier
DecayDescriptor m_decaydescriptor
Decay descriptor of the decay being reconstructed.
bool m_writeOut
toggle output particle list btw.
std::vector< std::string > m_vector_listName
vector of output particle list name
bool m_chargeConjugation
boolean to control whether charge conjugated decay should be reconstructed as well
Class to store reconstructed particles.
Definition Particle.h:76
EParticleSourceObject
particle source enumerators
Definition Particle.h:83
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition Particle.cc:1421
EParticleSourceObject getParticleSource() const
Returns particle source as defined with enum EParticleSourceObject.
Definition Particle.h:489
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
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
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
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
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...