10 #include <analysis/modules/ParticleCombinerFromMC/ParticleCombinerFromMCModule.h>
13 #include <framework/logging/Logger.h>
16 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
19 #include <analysis/DecayDescriptor/ParticleListName.h>
20 #include <analysis/utility/MCMatching.h>
47 setDescription(
"Makes particle combinations");
48 setPropertyFlags(c_ParallelProcessingCertified);
51 addParam(
"decayString", m_decayString,
52 "Input DecayDescriptor string (see :ref:`DecayString`).");
53 addParam(
"cut", m_cutParameter,
"Selection criteria to be applied", std::string(
""));
54 addParam(
"decayMode", m_decayModeID,
"User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
57 addParam(
"writeOut", m_writeOut,
58 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
59 addParam(
"chargeConjugation", m_chargeConjugation,
60 "If true, the charge-conjugated mode will be reconstructed as well",
true);
63 m_generator =
nullptr;
67 void ParticleCombinerFromMCModule::initialize()
70 bool valid = m_decaydescriptor.init(m_decayString);
72 B2ERROR(
"Invalid input DecayString: " << m_decayString);
77 m_listName = mother->getFullName();
79 m_cut = Variable::Cut::compile(m_cutParameter);
82 registerParticleRecursively(m_decaydescriptor);
86 void ParticleCombinerFromMCModule::event()
88 B2DEBUG(10,
"event() started !!!");
91 combineRecursively(m_decaydescriptor);
94 bool existingList = plist.
isValid();
97 B2WARNING(
"Output list " << m_listName <<
" was not created");
102 if (!m_cutParameter.empty()) {
103 std::vector<unsigned int> toRemove;
104 unsigned int n = plist->getListSize();
105 for (
unsigned i = 0; i < n; i++) {
106 const Particle* part = plist->getParticle(i);
108 MCMatching::setMCTruth(part);
109 MCMatching::getMCErrors(part);
111 if (!m_cut->check(part)) toRemove.push_back(part->getArrayIndex());
113 plist->removeParticles(toRemove);
118 void ParticleCombinerFromMCModule::registerParticleRecursively(
const DecayDescriptor& decaydescriptor)
122 for (
int i = 0; i < nProducts; ++i) {
129 registerParticleRecursively(*(decaydescriptor.
getDaughter(i)));
135 std::string listName = mother->getFullName();
139 auto existList = std::find(m_vector_listName.begin(), m_vector_listName.end(), listName);
140 if (existList != m_vector_listName.end()) {
141 B2ERROR(listName <<
" already exist ! You cannot write same sub-decay twice !!!");
145 std::string antiListName = ParticleListName::antiParticleListName(listName);
146 bool isSelfConjugatedParticle = (listName == antiListName);
149 particleList.registerInDataStore(flags);
150 if (!isSelfConjugatedParticle && m_chargeConjugation) {
155 m_vector_listName.push_back(listName);
159 void ParticleCombinerFromMCModule::combineRecursively(
const DecayDescriptor& decaydescriptor)
163 int pdgCode = mother->getPDGCode();
164 std::string listName = mother->getFullName();
165 std::string antiListName = ParticleListName::antiParticleListName(listName);
166 bool isSelfConjugatedParticle = (listName == antiListName);
170 outputList->initialize(pdgCode, listName);
172 if (!isSelfConjugatedParticle && m_chargeConjugation) {
175 outputAntiList->initialize(-1 * pdgCode, antiListName);
177 outputList->bindAntiParticleList(*(outputAntiList));
180 unsigned int numberOfLists = decaydescriptor.
getNDaughters();
182 for (
unsigned int i = 0; i < numberOfLists; ++i) {
191 B2ERROR(daughter->getFullName() <<
" is not created");
193 unsigned nPart = plist->getListSize();
194 for (
unsigned iPart = 0; iPart < nPart; iPart++) {
195 const Particle* part = plist->getParticle(iPart);
197 if (particleType == Particle::c_Track or
198 particleType == Particle::c_ECLCluster or
199 particleType == Particle::c_KLMCluster)
200 B2ERROR(daughter->getFullName() <<
" contains a reconstructed particle! It is not accepted in ParticleCombinerFromMCModule!");
205 combineRecursively(*dDaughter);
210 m_generator = std::make_unique<ParticleGenerator>(decaydescriptor,
"");
213 while (m_generator->loadNext(m_chargeConjugation)) {
214 Particle&& particle = m_generator->getCurrentParticle();
216 Particle* newParticle = m_particles.appendNew(particle);
218 newParticle->
addExtraInfo(
"decayModeID", m_decayModeID);
220 int iparticle = m_particles.getEntries() - 1;
221 outputList->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
225 std::unique_ptr<Variable::Cut> cutIsSignal = Variable::Cut::compile(
"isSignal");
227 std::vector<unsigned int> toRemove;
228 unsigned int n = outputList->getListSize();
229 for (
unsigned i = 0; i < n; i++) {
230 const Particle* part = outputList->getParticle(i);
232 MCMatching::setMCTruth(part);
233 MCMatching::getMCErrors(part);
235 if (!cutIsSignal->check(part)) toRemove.push_back(part->getArrayIndex());
237 outputList->removeParticles(toRemove);
EStoreFlags
Flags describing behaviours of objects etc.
Represents a particle in the DecayDescriptor.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
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).
Class to store reconstructed particles.
EParticleSourceObject
particle source enumerators
void addExtraInfo(const std::string &name, float value)
Sets the user-defined data of given name to the given value.
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.
bool isValid() const
Check whether the object was created.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.