9 #include <analysis/modules/MCDecayFinder/MCDecayFinderModule.h>
10 #include <framework/gearbox/Const.h>
11 #include <analysis/DecayDescriptor/ParticleListName.h>
12 #include <analysis/utility/EvtPDLUtil.h>
13 #include <analysis/utility/MCMatching.h>
27 setDescription(
"Find decays in MCParticle list matching a given DecayString and create Particles from them.");
29 addParam(
"decayString", m_strDecay,
"DecayDescriptor string.");
30 addParam(
"listName", m_listName,
"Name of the output particle list");
31 addParam(
"writeOut", m_writeOut,
32 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
35 void MCDecayFinderModule::initialize()
37 m_decaydescriptor.init(m_strDecay);
39 m_antiListName = ParticleListName::antiParticleListName(m_listName);
40 m_isSelfConjugatedParticle = (m_listName == m_antiListName);
42 B2DEBUG(10,
"particle list name: " << m_listName);
43 B2DEBUG(10,
"antiparticle list name: " << m_antiListName);
47 m_mcparticles.isRequired();
50 m_outputList.registerInDataStore(m_listName, flags);
51 m_particles.registerInDataStore(flags);
52 m_extraInfoMap.registerInDataStore();
53 m_particles.registerRelationTo(m_mcparticles, DataStore::c_Event, flags);
55 if (!m_isSelfConjugatedParticle) {
56 m_antiOutputList.registerInDataStore(m_antiListName, flags);
60 void MCDecayFinderModule::event()
63 m_outputList.create();
64 m_outputList->initialize(m_decaydescriptor.getMother()->getPDGCode(), m_listName);
66 if (!m_isSelfConjugatedParticle) {
67 m_antiOutputList.create();
68 m_antiOutputList->initialize(-1 * m_decaydescriptor.getMother()->getPDGCode(), m_antiListName);
69 m_outputList->bindAntiParticleList(*(m_antiOutputList));
73 int nMCParticles = m_mcparticles.getEntries();
74 for (
int i = 0; i < nMCParticles; i++) {
75 for (
int iCC = 0; iCC < 2; iCC++) {
76 std::unique_ptr<DecayTree<MCParticle>> decay(match(m_mcparticles[i], m_decaydescriptor, iCC));
77 if (decay->getObj()) {
78 B2DEBUG(19,
"Match!");
79 int iIndex = write(decay.get());
80 m_outputList->addParticle(m_particles[iIndex]);
96 int iPDGD = d->getMother()->getPDGCode();
99 bool isSelfConjugatedParticle = !(EvtPDLUtil::hasAntiParticle(iPDGD));
101 if (!isCC && iPDGD != iPDGP)
return decay;
102 else if (isCC && (iPDGD != -iPDGP && !isSelfConjugatedParticle))
return decay;
103 else if (isCC && (iPDGD != iPDGP && isSelfConjugatedParticle))
return decay;
104 B2DEBUG(19,
"PDG code matched: " << iPDGP);
108 int nDaughtersD = d->getNDaughters();
109 if (nDaughtersD == 0) {
110 B2DEBUG(19,
"DecayDescriptor has no Daughters, everything OK!");
115 int nDaughtersRecursiveD = nDaughtersD;
116 if (d->isIgnoreIntermediate()) {
117 nDaughtersRecursiveD = getNDaughtersRecursive(d);
121 vector<const MCParticle*> daughtersP;
122 if (d->isIgnoreIntermediate()) {
123 appendParticles(mcp, daughtersP);
125 const vector<MCParticle*>& tmpDaughtersP = mcp->
getDaughters();
126 for (
auto daug : tmpDaughtersP)
127 daughtersP.push_back(daug);
131 int nDaughtersP = daughtersP.size();
132 if (nDaughtersRecursiveD > nDaughtersP) {
133 B2DEBUG(10,
"DecayDescriptor has more daughters than MCParticle!");
138 for (
int iDD = 0; iDD < nDaughtersD; iDD++) {
140 bool isMatchDaughter =
false;
141 auto itDP = daughtersP.begin();
142 while (itDP != daughtersP.end()) {
145 if (!daughter->getObj()) {
150 decay->append(daughter);
151 isMatchDaughter =
true;
152 itDP = daughtersP.erase(itDP);
155 if (d->isIgnoreIntermediate() and d->getDaughter(iDD)->getNDaughters() != 0) {
156 vector<const MCParticle*> grandDaughtersP;
157 if (d->getDaughter(iDD)->isIgnoreIntermediate()) {
158 appendParticles(daugP, grandDaughtersP);
160 const vector<MCParticle*>& tmpGrandDaughtersP = daugP->
getDaughters();
161 for (
auto grandDaugP : tmpGrandDaughtersP)
162 grandDaughtersP.push_back(grandDaugP);
165 for (
auto grandDaugP : grandDaughtersP) {
167 while (jtDP != daughtersP.end()) {
170 if (grandDaugP == daugP_j)
171 jtDP = daughtersP.erase(jtDP);
180 if (!isMatchDaughter) {
187 bool isInclusive = (d->isIgnoreMassive() and d->isIgnoreNeutrino() and d->isIgnoreGamma() and d->isIgnoreRadiatedPhotons());
189 B2DEBUG(10,
"Check for left over MCParticles!\n");
190 for (
auto daugP : daughtersP) {
191 if (daugP->getPDG() == Const::photon.getPDGCode()) {
193 if (MCMatching::isFSR(daugP) or daugP->hasStatus(MCParticle::c_IsPHOTOSPhoton)) {
195 if (d->isIgnoreRadiatedPhotons())
continue;
198 else if (d->isIgnoreGamma())
continue;
199 }
else if ((abs(daugP->getPDG()) == 12 or abs(daugP->getPDG()) == 14 or abs(daugP->getPDG()) == 16)) {
200 if (d->isIgnoreNeutrino())
continue;
202 if (d->isIgnoreMassive())
continue;
204 if (d->isIgnoreIntermediate())
continue;
206 B2DEBUG(10,
"There was an additional particle left. Found " << daugP->getPDG());
211 B2DEBUG(19,
"Match found!");
218 Particle* newParticle = m_particles.appendNew(decay->getObj());
222 const int iIndex = m_particles.getEntries() - 1;
225 vector< DecayTree<MCParticle>* > daughters = decay->getDaughters();
226 int nDaughers = daughters.size();
227 for (
int i = 0; i < nDaughers; ++i) {
228 int iIndexDaughter = write(daughters[i]);
234 void MCDecayFinderModule::appendParticles(
const MCParticle* gen, vector<const MCParticle*>& children)
239 const vector<MCParticle*>& genDaughters = gen->
getDaughters();
240 for (
auto daug : genDaughters) {
241 children.push_back(daug);
242 appendParticles(daug, children);
248 const int nDaughter = d->getNDaughters();
249 if (nDaughter == 0)
return nDaughter;
251 int nDaughterRecursive = nDaughter;
252 for (
int iDaug = 0; iDaug < nDaughter; iDaug++) {
255 nDaughterRecursive += getNDaughtersRecursive(dDaug);
258 return nDaughterRecursive;
EStoreFlags
Flags describing behaviours of objects etc.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
This is a helper class for the MCDecayFinderModule.
Find decays in MCParticle list matching a given DecayString.
A Class to store the Monte Carlo particle information.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
int getPDG() const
Return PDG code of particle.
Class to store reconstructed particles.
void appendDaughter(const Particle *daughter, const bool updateType=true)
Appends index of daughter to daughters index array.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
bool isFSP(int pdg)
defines what is a final state particle for this purpose.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.