12 #include <analysis/modules/ParticleCombinerFromMC/ParticleCombinerFromMCModule.h>
15 #include <framework/logging/Logger.h>
18 #include <analysis/dataobjects/Particle.h>
21 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
24 #include <analysis/DecayDescriptor/ParticleListName.h>
25 #include <analysis/utility/PCmsLabTransform.h>
26 #include <analysis/utility/MCMatching.h>
53 setDescription(
"Makes particle combinations");
54 setPropertyFlags(c_ParallelProcessingCertified);
57 addParam(
"decayString", m_decayString,
58 "Input DecayDescriptor string (see :ref:`DecayString`).");
59 addParam(
"cut", m_cutParameter,
"Selection criteria to be applied", std::string(
""));
60 addParam(
"decayMode", m_decayModeID,
"User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
63 addParam(
"writeOut", m_writeOut,
64 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
65 addParam(
"chargeConjugation", m_chargeConjugation,
66 "If true, the charge-conjugated mode will be reconstructed as well",
true);
70 m_isSelfConjugatedParticle =
false;
71 m_generator =
nullptr;
75 void ParticleCombinerFromMCModule::initialize()
82 bool valid = m_decaydescriptor.init(m_decayString);
84 B2ERROR(
"Invalid input DecayString: " << m_decayString);
89 m_pdgCode = mother->getPDGCode();
90 m_listName = mother->getFullName();
92 m_antiListName = ParticleListName::antiParticleListName(m_listName);
93 m_isSelfConjugatedParticle = (m_listName == m_antiListName);
95 m_cut = Variable::Cut::compile(m_cutParameter);
98 registerParticleRecursively(m_decaydescriptor);
102 void ParticleCombinerFromMCModule::event()
104 B2DEBUG(10,
"event() started !!!");
107 combineRecursively(m_decaydescriptor);
110 bool existingList = plist.
isValid();
113 B2WARNING(
"Output list " << m_listName <<
" was not created");
118 if (!m_cutParameter.empty()) {
119 std::vector<unsigned int> toRemove;
120 unsigned int n = plist->getListSize();
121 for (
unsigned i = 0; i < n; i++) {
122 const Particle* part = plist->getParticle(i);
124 MCMatching::setMCTruth(part);
125 MCMatching::getMCErrors(part);
127 if (!m_cut->check(part)) toRemove.push_back(part->getArrayIndex());
129 plist->removeParticles(toRemove);
134 void ParticleCombinerFromMCModule::registerParticleRecursively(
const DecayDescriptor& decaydescriptor)
138 for (
int i = 0; i < nProducts; ++i) {
145 registerParticleRecursively(*(decaydescriptor.
getDaughter(i)));
151 std::string listName = mother->getFullName();
155 auto existList = std::find(m_vector_listName.begin(), m_vector_listName.end(), listName);
156 if (existList != m_vector_listName.end()) {
157 B2ERROR(listName <<
" already exist ! You cannot write same sub-decay twice !!!");
161 std::string antiListName = ParticleListName::antiParticleListName(listName);
162 bool isSelfConjugatedParticle = (listName == antiListName);
165 particleList.registerInDataStore(flags);
166 if (!isSelfConjugatedParticle && m_chargeConjugation) {
168 antiParticleList.registerInDataStore(flags);
171 m_vector_listName.push_back(listName);
175 void ParticleCombinerFromMCModule::combineRecursively(
const DecayDescriptor& decaydescriptor)
179 int pdgCode = mother->getPDGCode();
180 std::string listName = mother->getFullName();
181 std::string antiListName = ParticleListName::antiParticleListName(listName);
182 bool isSelfConjugatedParticle = (listName == antiListName);
188 outputList->initialize(pdgCode, listName);
190 if (!isSelfConjugatedParticle && m_chargeConjugation) {
192 outputAntiList.create();
193 outputAntiList->initialize(-1 * pdgCode, antiListName);
195 outputList->bindAntiParticleList(*(outputAntiList));
198 unsigned int numberOfLists = decaydescriptor.
getNDaughters();
200 for (
unsigned int i = 0; i < numberOfLists; ++i) {
209 B2ERROR(daughter->getFullName() <<
" is not created");
211 unsigned nPart = plist->getListSize();
212 for (
unsigned iPart = 0; iPart < nPart; iPart++) {
213 const Particle* part = plist->getParticle(iPart);
215 if (particleType == Particle::c_Track or
216 particleType == Particle::c_ECLCluster or
217 particleType == Particle::c_KLMCluster)
218 B2ERROR(daughter->getFullName() <<
" contains a reconstructed particle! It is not accepted in ParticleCombinerFromMCModule!");
223 combineRecursively(*dDaughter);
228 m_generator = std::make_unique<ParticleGenerator>(decaydescriptor,
"");
231 while (m_generator->loadNext(m_chargeConjugation)) {
232 Particle&& particle = m_generator->getCurrentParticle();
234 Particle* newParticle = particles.appendNew(particle);
236 newParticle->
addExtraInfo(
"decayModeID", m_decayModeID);
238 int iparticle = particles.getEntries() - 1;
239 outputList->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
243 std::unique_ptr<Variable::Cut> cutIsSignal = Variable::Cut::compile(
"isSignal");
245 std::vector<unsigned int> toRemove;
246 unsigned int n = outputList->getListSize();
247 for (
unsigned i = 0; i < n; i++) {
248 const Particle* part = outputList->getParticle(i);
250 MCMatching::setMCTruth(part);
251 MCMatching::getMCErrors(part);
253 if (!cutIsSignal->check(part)) toRemove.push_back(part->getArrayIndex());
255 outputList->removeParticles(toRemove);