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>
14#include <analysis/modules/MCDecayFinder/DecayTree.h>
28 setDescription(
"Find decays in MCParticle list matching a given DecayString and create Particles from them.");
34 "If true, all daughters of the matched MCParticle will be added in the order defined at the MCParticle. "
35 "If false, only the daughters described in the given decayString will be appended to the output particle.",
38 "If true, the secondary MC daughters will be skipped to append to the output particles. Default: true",
41 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
48 B2ERROR(
"Invalid input DecayString: " <<
m_strDecay);
53 B2DEBUG(10,
"particle list name: " <<
m_listName);
89 for (
int i = 0; i < nMCParticles; i++) {
94 for (
int iCC = 0; iCC < 2; iCC++) {
101 B2DEBUG(19,
"Match!");
118 }
else if (arrayIndex == -1) {
144 const int iPDGD = d->getMother()->getPDGCode();
145 const int iPDGP = mcp->
getPDG();
148 if (!isCC && iPDGD != iPDGP)
return decay;
149 else if (isCC && (iPDGD != -iPDGP && !isSelfConjugatedParticle))
return decay;
150 else if (isCC && (iPDGD != iPDGP && isSelfConjugatedParticle))
return decay;
151 B2DEBUG(19,
"PDG code matched: " << iPDGP);
155 const int nDaughtersD = d->getNDaughters();
156 if (nDaughtersD == 0) {
157 B2DEBUG(19,
"DecayDescriptor has no Daughters, everything OK!");
163 vector<const MCParticle*> daughtersP;
164 int nDaughtersRecursiveD = 0;
165 if (d->isIgnoreIntermediate()) {
170 const vector<MCParticle*>& tmpDaughtersP = mcp->
getDaughters();
171 for (
auto daug : tmpDaughtersP)
172 daughtersP.push_back(daug);
173 nDaughtersRecursiveD = nDaughtersD;
177 if (nDaughtersRecursiveD > (
int)daughtersP.size()) {
178 B2DEBUG(10,
"DecayDescriptor has more daughters than MCParticle!");
183 std::vector<std::pair<int, int>> daughtersDepthMapD;
184 for (
int iDD = 0; iDD < nDaughtersD; iDD++) {
188 daughtersDepthMapD.push_back({-1 * depth, iDD});
191 std::sort(daughtersDepthMapD.begin(), daughtersDepthMapD.end());
194 for (
auto pair : daughtersDepthMapD) {
195 int iDD = pair.second;
197 bool isMatchDaughter =
false;
198 auto itDP = daughtersP.begin();
199 while (itDP != daughtersP.end()) {
204 if (!daughter->getObj()) {
210 decay->append(daughter);
211 isMatchDaughter =
true;
212 itDP = daughtersP.erase(itDP);
215 if (d->isIgnoreIntermediate() and d->getDaughter(iDD)->getNDaughters() != 0) {
216 vector<const MCParticle*> grandDaughtersP;
217 if (d->getDaughter(iDD)->isIgnoreIntermediate()) {
220 const vector<MCParticle*>& tmpGrandDaughtersP = daugP->
getDaughters();
221 for (
auto grandDaugP : tmpGrandDaughtersP)
222 grandDaughtersP.push_back(grandDaugP);
225 for (
auto grandDaugP : grandDaughtersP) {
227 while (jtDP != daughtersP.end()) {
230 if (grandDaugP == daugP_j)
231 jtDP = daughtersP.erase(jtDP);
240 if (!isMatchDaughter) {
251 B2DEBUG(10,
"isSignal is not True. There was an additional particle left.");
252 decay->setObj(
nullptr);
258 B2DEBUG(19,
"Match found!");
272 vector<const MCParticle*> tmp_children;
273 const vector<MCParticle*>& genDaughters = gen->
getDaughters();
274 for (
auto daug : genDaughters) {
275 tmp_children.push_back(daug);
276 children.push_back(daug);
278 for (
auto child : tmp_children) {
285 const int nDaughter = d->getNDaughters();
286 if (nDaughter == 0)
return nDaughter;
288 int nDaughterRecursive = nDaughter;
289 for (
int iDaug = 0; iDaug < nDaughter; iDaug++) {
295 return nDaughterRecursive;
301 for (
int i = 0; i < d->getNDaughters(); i++) {
305 if (tmp_depth > maxDepth)
306 maxDepth = tmp_depth;
323 const vector<DecayTree<MCParticle>*> decayDaughters = decay->
getDaughters();
326 if ((
int)decayDaughters.size() != nDaughters) {
327 B2ERROR(
"MCDecayFinderModule::buildParticleFromDecayTree Inconsistency on the number of daughters between DecayTree and DecayDescriptor");
354 std::vector<std::pair<int, int>> daughtersDepthMapD;
355 for (
int iDD = 0; iDD < nDaughters; iDD++) {
360 daughtersDepthMapD.push_back({-1 * depth, iDD});
362 std::sort(daughtersDepthMapD.begin(), daughtersDepthMapD.end());
364 for (
int iDD = 0; iDD < nDaughters; iDD++) {
366 int index_decayDaughter = 0;
367 for (
auto pair : daughtersDepthMapD) {
368 if (pair.second == iDD)
break;
369 index_decayDaughter++;
375 newParticle->
appendDaughter(partDaughter,
false, daughterProperty);
400 if (existingParticle.isCopyOf(newParticle))
static const ParticleType Lambda
Lambda particle.
static const ParticleType Kshort
K^0_S particle.
EStoreFlags
Flags describing behaviours of objects etc.
@ c_WriteOut
Object/array should be saved by output modules.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
int getProperty() const
return property of the particle.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
int getNDaughters() const
return number of direct daughters.
int getProperty() const
return property of the particle.
const DecayDescriptorParticle * getMother() const
return mother.
This is a helper class for the MCDecayFinderModule.
Particle * createParticleRecursively(const MCParticle *mcp, bool skipNonPrimaryDaughters)
Create a Particle from the given MCParticle appending all daughters of the MCParticle.
bool m_isSelfConjugatedParticle
Is the particle list for a self-conjugated particle.
std::string m_antiListName
Name of output anti-particle list.
DecayTree< MCParticle > * match(const MCParticle *mcp, const DecayDescriptor *d, bool isCC, int &arrayIndex)
Search for MCParticles matching the given DecayString.
Particle * buildParticleFromDecayTree(const DecayTree< MCParticle > *decay, const DecayDescriptor *dd)
Build a Particle from the given DecayTree and DecayDescriptor.
int getNDaughtersRecursive(const DecayDescriptor *d)
Recursively get number of daughters of given DecayDescriptor.
virtual void initialize() override
Initialises the module.
bool performMCMatching(const DecayTree< MCParticle > *decay, const DecayDescriptor *dd)
Perform the MCMatching on the Particle built from the given DecayTree and DecayDescriptor.
virtual void event() override
Method called for each event.
StoreArray< MCParticle > m_mcparticles
StoreArray of MCParticles.
std::string m_listName
Name of output particle list.
StoreArray< Particle > m_particles
StoreArray of Particles.
StoreObjPtr< ParticleList > m_outputList
output particle list
std::string m_strDecay
Decay string to build the decay descriptor.
void appendParticles(const MCParticle *gen, std::vector< const MCParticle * > &children)
Recursively gather all MC daughters of gen.
void addUniqueParticleToList(Particle *newParticle)
Add a new Particle into the output ParticleList if it does not exist already.
bool m_appendAllDaughters
if true, all daughters are appended
bool m_skipNonPrimaryDaughters
toggle skip of secondary MC daughters
MCDecayFinderModule()
Constructor.
StoreObjPtr< ParticleList > m_antiOutputList
output anti-particle list
DecayDescriptor m_decaydescriptor
Decay descriptor of decays to look for.
bool m_writeOut
toggle output particle list btw.
void countMaxDepthOfNest(const DecayDescriptor *d, int &depth)
Count the max depth of nest from the given DecayDescriptor.
StoreObjPtr< ParticleExtraInfoMap > m_extraInfoMap
object pointer to ParticleExtraInfoMaps
A Class to store the Monte Carlo particle information.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
int getPDG() const
Return PDG code of particle.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class to store reconstructed particles.
void setProperty(const int properties)
sets m_properties
void appendDaughter(const Particle *daughter, const bool updateType=true, const int daughterProperty=c_Ordinary)
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).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
T * getObj() const
Return the decaying object itself, e.g.
std::vector< DecayTree< T > * > getDaughters() const
Return list of decay daughters.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
bool hasAntiParticle(int pdgCode)
Checks if the particle with given pdg code has an anti-particle or not.
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.
@ c_Correct
This Particle and all its daughters are perfectly reconstructed.
static bool isFSP(int pdg)
Returns true if given PDG code indicates a FSP.
static int getMCErrors(const Particle *particle, const MCParticle *mcParticle=nullptr)
Returns quality indicator of the match as a bit pattern where the individual bits indicate the the ty...