11 #include <analysis/modules/MCDecayFinder/MCDecayFinderModule.h>
12 #include <analysis/dataobjects/ParticleList.h>
13 #include <analysis/dataobjects/ParticleExtraInfoMap.h>
14 #include <framework/datastore/StoreObjPtr.h>
15 #include <framework/datastore/StoreArray.h>
16 #include <framework/gearbox/Const.h>
17 #include <mdst/dataobjects/MCParticle.h>
18 #include <analysis/DecayDescriptor/ParticleListName.h>
19 #include <analysis/utility/EvtPDLUtil.h>
20 #include <analysis/utility/MCMatching.h>
34 setDescription(
"Find decays in MCParticle list matching a given DecayString and create Particles from them.");
36 addParam(
"decayString", m_strDecay,
"DecayDescriptor string.");
37 addParam(
"listName", m_listName,
"Name of the output particle list");
38 addParam(
"writeOut", m_writeOut,
39 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
42 void MCDecayFinderModule::initialize()
44 m_decaydescriptor.init(m_strDecay);
46 m_antiListName = ParticleListName::antiParticleListName(m_listName);
47 m_isSelfConjugatedParticle = (m_listName == m_antiListName);
49 B2DEBUG(10,
"particle list name: " << m_listName);
50 B2DEBUG(10,
"antiparticle list name: " << m_antiListName);
58 mcparticles.isRequired();
61 particleList.registerInDataStore(flags);
62 particles.registerInDataStore(flags);
63 extraInfoMap.registerInDataStore();
64 particles.registerRelationTo(mcparticles, DataStore::c_Event, flags);
66 if (!m_isSelfConjugatedParticle) {
68 antiParticleList.registerInDataStore(flags);
72 void MCDecayFinderModule::event()
80 outputList->initialize(m_decaydescriptor.getMother()->getPDGCode(), m_listName);
82 if (!m_isSelfConjugatedParticle) {
84 antiOutputList.create();
85 antiOutputList->initialize(-1 * m_decaydescriptor.getMother()->getPDGCode(), m_antiListName);
86 outputList->bindAntiParticleList(*(antiOutputList));
92 for (
int i = 0; i < nMCParticles; i++) {
93 for (
int iCC = 0; iCC < 2; iCC++) {
94 std::unique_ptr<DecayTree<MCParticle>> decay(match(mcparticles[i], m_decaydescriptor, iCC));
95 if (decay->getObj()) {
96 B2DEBUG(19,
"Match!");
97 int iIndex = write(decay.get());
98 outputList->addParticle(particles[iIndex]);
114 int iPDGD = d->getMother()->getPDGCode();
115 int iPDGP = mcp->
getPDG();
117 bool isSelfConjugatedParticle = !(EvtPDLUtil::hasAntiParticle(iPDGD));
119 if (!isCC && iPDGD != iPDGP)
return decay;
120 else if (isCC && (iPDGD != -iPDGP && !isSelfConjugatedParticle))
return decay;
121 else if (isCC && (iPDGD != iPDGP && isSelfConjugatedParticle))
return decay;
122 B2DEBUG(19,
"PDG code matched: " << iPDGP);
126 int nDaughtersD = d->getNDaughters();
127 if (nDaughtersD == 0) {
128 B2DEBUG(19,
"DecayDescriptor has no Daughters, everything OK!");
133 int nDaughtersRecursiveD = nDaughtersD;
134 if (d->isIgnoreIntermediate()) {
135 nDaughtersRecursiveD = getNDaughtersRecursive(d);
139 vector<const MCParticle*> daughtersP;
140 if (d->isIgnoreIntermediate()) {
141 appendParticles(mcp, daughtersP);
143 const vector<MCParticle*>& tmpDaughtersP = mcp->
getDaughters();
144 for (
auto daug : tmpDaughtersP)
145 daughtersP.push_back(daug);
149 int nDaughtersP = daughtersP.size();
150 if (nDaughtersRecursiveD > nDaughtersP) {
151 B2DEBUG(10,
"DecayDescriptor has more daughters than MCParticle!");
156 for (
int iDD = 0; iDD < nDaughtersD; iDD++) {
158 bool isMatchDaughter =
false;
159 auto itDP = daughtersP.begin();
160 while (itDP != daughtersP.end()) {
163 if (!daughter->getObj()) {
168 decay->append(daughter);
169 isMatchDaughter =
true;
170 itDP = daughtersP.erase(itDP);
173 if (d->isIgnoreIntermediate() and d->getDaughter(iDD)->getNDaughters() != 0) {
174 vector<const MCParticle*> grandDaughtersP;
175 if (d->getDaughter(iDD)->isIgnoreIntermediate()) {
176 appendParticles(daugP, grandDaughtersP);
178 const vector<MCParticle*>& tmpGrandDaughtersP = daugP->
getDaughters();
179 for (
auto grandDaugP : tmpGrandDaughtersP)
180 grandDaughtersP.push_back(grandDaugP);
183 for (
auto grandDaugP : grandDaughtersP) {
185 while (jtDP != daughtersP.end()) {
188 if (grandDaugP == daugP_j)
189 jtDP = daughtersP.erase(jtDP);
198 if (!isMatchDaughter) {
205 bool isInclusive = (d->isIgnoreMassive() and d->isIgnoreNeutrino() and d->isIgnoreGamma() and d->isIgnoreRadiatedPhotons());
207 B2DEBUG(10,
"Check for left over MCParticles!\n");
208 for (
auto daugP : daughtersP) {
209 if (daugP->getPDG() == Const::photon.getPDGCode()) {
211 if (MCMatching::isFSR(daugP) or daugP->hasStatus(MCParticle::c_IsPHOTOSPhoton)) {
213 if (d->isIgnoreRadiatedPhotons())
continue;
216 else if (d->isIgnoreGamma())
continue;
217 }
else if ((abs(daugP->getPDG()) == 12 or abs(daugP->getPDG()) == 14 or abs(daugP->getPDG()) == 16)) {
218 if (d->isIgnoreNeutrino())
continue;
220 if (d->isIgnoreMassive())
continue;
222 if (d->isIgnoreIntermediate())
continue;
224 B2DEBUG(10,
"There was an additional particle left. Found " << daugP->getPDG());
229 B2DEBUG(19,
"Match found!");
241 Particle* newParticle = particles.appendNew(decay->getObj());
245 const int iIndex = particles.getEntries() - 1;
248 vector< DecayTree<MCParticle>* > daughters = decay->getDaughters();
249 int nDaughers = daughters.size();
250 for (
int i = 0; i < nDaughers; ++i) {
251 int iIndexDaughter = write(daughters[i]);
257 void MCDecayFinderModule::appendParticles(
const MCParticle* gen, vector<const MCParticle*>& children)
262 const vector<MCParticle*>& genDaughters = gen->
getDaughters();
263 for (
auto daug : genDaughters) {
264 children.push_back(daug);
265 appendParticles(daug, children);
271 const int nDaughter = d->getNDaughters();
272 if (nDaughter == 0)
return nDaughter;
274 int nDaughterRecursive = nDaughter;
275 for (
int iDaug = 0; iDaug < nDaughter; iDaug++) {
278 nDaughterRecursive += getNDaughtersRecursive(dDaug);
281 return nDaughterRecursive;