Belle II Software  release-08-01-10
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 
18 // utilities
19 #include <analysis/DecayDescriptor/ParticleListName.h>
20 #include <analysis/utility/MCMatching.h>
21 
22 #include <memory>
23 
24 using namespace std;
25 using namespace Belle2;
26 
27 //-----------------------------------------------------------------
28 // Register module
29 //-----------------------------------------------------------------
30 
31 REG_MODULE(ParticleCombinerFromMC);
32 
33 //-----------------------------------------------------------------
34 // Implementation
35 //-----------------------------------------------------------------
36 
37 ParticleCombinerFromMCModule::ParticleCombinerFromMCModule() :
38  Module()
39 
40 {
41  // set module description (e.g. insert text)
42  setDescription("Makes particle combinations");
44 
45  // Add parameters
46  addParam("decayString", m_decayString,
47  "Input DecayDescriptor string (see :ref:`DecayString`).");
48  addParam("cut", m_cutParameter, "Selection criteria to be applied", std::string(""));
49  addParam("decayMode", m_decayModeID, "User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
50  0);
51 
52  addParam("writeOut", m_writeOut,
53  "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", false);
54  addParam("chargeConjugation", m_chargeConjugation,
55  "If true, the charge-conjugated mode will be reconstructed as well", true);
56 
57  // initializing the rest of private members
58  m_generator = nullptr;
59  m_cut = nullptr;
60 }
61 
63 {
64  // obtain the input and output particle lists from the decay string
65  bool valid = m_decaydescriptor.init(m_decayString);
66  if (!valid)
67  B2ERROR("Invalid input DecayString: " << m_decayString);
68 
69  // Mother particle
71 
72  m_listName = mother->getFullName();
73 
75 
76  // register particles which have (sub-)decay recursively
78 
79 }
80 
82 {
83  B2DEBUG(10, "event() started !!!");
84 
85  // combine particles recursively
87 
89  bool existingList = plist.isValid();
90 
91  if (!existingList) {
92  B2WARNING("Output list " << m_listName << " was not created");
93  return;
94  }
95 
96  // loop over list only if cuts should be applied
97  if (!m_cutParameter.empty()) {
98  std::vector<unsigned int> toRemove;
99  unsigned int n = plist->getListSize();
100  for (unsigned i = 0; i < n; i++) {
101  const Particle* part = plist->getParticle(i);
102 
105 
106  if (!m_cut->check(part)) toRemove.push_back(part->getArrayIndex());
107  }
108  plist->removeParticles(toRemove);
109  }
110 }
111 
112 
114 {
115  int nProducts = decaydescriptor.getNDaughters();
116 
117  for (int i = 0; i < nProducts; ++i) {
118  if (decaydescriptor.getDaughter(i)->getNDaughters() == 0) {
119  // if daughter does not have daughters, it must be already registered
120  const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
121  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName());
122  } else {
123  // if daughter has daughters, call the function recursively
124  registerParticleRecursively(*(decaydescriptor.getDaughter(i)));
125  }
126  }
127 
128  // Mother particle
129  const DecayDescriptorParticle* mother = decaydescriptor.getMother();
130  std::string listName = mother->getFullName();
131  StoreObjPtr<ParticleList> particleList(listName);
132 
133  // if particleList already exists
134  auto existList = std::find(m_vector_listName.begin(), m_vector_listName.end(), listName);
135  if (existList != m_vector_listName.end()) {
136  B2ERROR(listName << " already exist ! You cannot write same sub-decay twice !!!");
137  return;
138  }
139 
140  std::string antiListName = ParticleListName::antiParticleListName(listName);
141  bool isSelfConjugatedParticle = (listName == antiListName);
142 
144  particleList.registerInDataStore(flags);
145  if (!isSelfConjugatedParticle && m_chargeConjugation) {
146  StoreObjPtr<ParticleList> antiParticleList(antiListName);
147  antiParticleList.registerInDataStore(flags);
148  }
149 
150  m_vector_listName.push_back(listName);
151 
152 }
153 
155 {
156  // Mother particle
157  const DecayDescriptorParticle* mother = decaydescriptor.getMother();
158  int pdgCode = mother->getPDGCode();
159  std::string listName = mother->getFullName();
160  std::string antiListName = ParticleListName::antiParticleListName(listName);
161  bool isSelfConjugatedParticle = (listName == antiListName);
162 
163  StoreObjPtr<ParticleList> outputList(listName);
164  outputList.create();
165  outputList->initialize(pdgCode, listName);
166 
167  if (!isSelfConjugatedParticle && m_chargeConjugation) {
168  StoreObjPtr<ParticleList> outputAntiList(antiListName);
169  outputAntiList.create();
170  outputAntiList->initialize(-1 * pdgCode, antiListName);
171 
172  outputList->bindAntiParticleList(*(outputAntiList));
173  }
174 
175  unsigned int numberOfLists = decaydescriptor.getNDaughters();
176 
177  for (unsigned int i = 0; i < numberOfLists; ++i) {
178  const DecayDescriptor* dDaughter = decaydescriptor.getDaughter(i);
179 
180  if (dDaughter->getNDaughters() == 0) {
181  // if daughter does not have daughters, check if it is not reconstructed particle.
182  const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
183  StoreObjPtr<ParticleList> plist(daughter->getFullName());
184  // if daughter is not created, returns error
185  if (!plist.isValid())
186  B2ERROR(daughter->getFullName() << " is not created");
187  // if daughter contains reconstructed particles, returns error.
188  unsigned nPart = plist->getListSize();
189  for (unsigned iPart = 0; iPart < nPart; iPart++) {
190  const Particle* part = plist->getParticle(iPart);
191  Particle::EParticleSourceObject particleType = part->getParticleSource();
192  if (particleType == Particle::c_Track or
193  particleType == Particle::c_ECLCluster or
194  particleType == Particle::c_KLMCluster)
195  B2ERROR(daughter->getFullName() << " contains a reconstructed particle! It is not accepted in ParticleCombinerFromMCModule!");
196  }
197  // if not, do nothing.
198  } else {
199  // if daughter has daughter, call the function recursively
200  combineRecursively(*dDaughter);
201  }
202  }
203 
204  // initialize the generator
205  m_generator = std::make_unique<ParticleGenerator>(decaydescriptor, "");
206  m_generator->init();
207 
208  while (m_generator->loadNext(m_chargeConjugation)) {
209  Particle&& particle = m_generator->getCurrentParticle();
210 
211  Particle* newParticle = m_particles.appendNew(particle);
212  // append to the created particle the user specified decay mode ID
213  newParticle->addExtraInfo("decayModeID", m_decayModeID);
214 
215  int iparticle = m_particles.getEntries() - 1;
216  outputList->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
217  }
218 
219  // select only signal particles
220  std::unique_ptr<Variable::Cut> cutIsSignal = Variable::Cut::compile("isSignal");
221 
222  std::vector<unsigned int> toRemove;
223  unsigned int n = outputList->getListSize();
224  for (unsigned i = 0; i < n; i++) {
225  const Particle* part = outputList->getParticle(i);
226 
229 
230  if (!cutIsSignal->check(part)) toRemove.push_back(part->getArrayIndex());
231  }
232  outputList->removeParticles(toRemove);
233 
234 }
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.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
int getNDaughters() const
return number of direct daughters.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
Definition: GeneralCut.h:84
Base class for Modules.
Definition: Module.h:72
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
@ 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:75
EParticleSourceObject
particle source enumerators
Definition: Particle.h:82
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition: Particle.cc:1337
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.
static bool setMCTruth(const Belle2::Particle *particle)
This is the main function of MC matching algorithm.
Definition: MCMatching.cc:86
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