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.");
33 "If true, all daughters of the matched MCParticle will be added in the order defined at the MCParticle. "
34 "If false, only the daughters described in the given decayString will be appended to the output particle.",
37 "If true, the secondary MC daughters will be skipped to append to the output particles. Default: true",
40 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
47 B2ERROR(
"Invalid input DecayString: " <<
m_strDecay);
52 B2DEBUG(10,
"particle list name: " <<
m_listName);
88 for (
int i = 0; i < nMCParticles; i++) {
93 for (
int iCC = 0; iCC < 2; iCC++) {
100 B2DEBUG(19,
"Match!");
117 }
else if (arrayIndex == -1) {
143 const int iPDGD = d->getMother()->getPDGCode();
144 const int iPDGP = mcp->
getPDG();
147 if (!isCC && iPDGD != iPDGP)
return decay;
148 else if (isCC && (iPDGD != -iPDGP && !isSelfConjugatedParticle))
return decay;
149 else if (isCC && (iPDGD != iPDGP && isSelfConjugatedParticle))
return decay;
150 B2DEBUG(19,
"PDG code matched: " << iPDGP);
154 const int nDaughtersD = d->getNDaughters();
155 if (nDaughtersD == 0) {
156 B2DEBUG(19,
"DecayDescriptor has no Daughters, everything OK!");
162 vector<const MCParticle*> daughtersP;
163 int nDaughtersRecursiveD = 0;
164 if (d->isIgnoreIntermediate()) {
169 const vector<MCParticle*>& tmpDaughtersP = mcp->
getDaughters();
170 for (
auto daug : tmpDaughtersP)
171 daughtersP.push_back(daug);
172 nDaughtersRecursiveD = nDaughtersD;
176 if (nDaughtersRecursiveD > (
int)daughtersP.size()) {
177 B2DEBUG(10,
"DecayDescriptor has more daughters than MCParticle!");
182 std::vector<std::pair<int, int>> daughtersDepthMapD;
183 for (
int iDD = 0; iDD < nDaughtersD; iDD++) {
187 daughtersDepthMapD.push_back({-1 * depth, iDD});
190 std::sort(daughtersDepthMapD.begin(), daughtersDepthMapD.end());
193 for (
auto pair : daughtersDepthMapD) {
194 int iDD = pair.second;
196 bool isMatchDaughter =
false;
197 auto itDP = daughtersP.begin();
198 while (itDP != daughtersP.end()) {
203 if (!daughter->getObj()) {
209 decay->append(daughter);
210 isMatchDaughter =
true;
211 itDP = daughtersP.erase(itDP);
214 if (d->isIgnoreIntermediate() and d->getDaughter(iDD)->getNDaughters() != 0) {
215 vector<const MCParticle*> grandDaughtersP;
216 if (d->getDaughter(iDD)->isIgnoreIntermediate()) {
219 const vector<MCParticle*>& tmpGrandDaughtersP = daugP->
getDaughters();
220 for (
auto grandDaugP : tmpGrandDaughtersP)
221 grandDaughtersP.push_back(grandDaugP);
224 for (
auto grandDaugP : grandDaughtersP) {
226 while (jtDP != daughtersP.end()) {
229 if (grandDaugP == daugP_j)
230 jtDP = daughtersP.erase(jtDP);
239 if (!isMatchDaughter) {
250 B2DEBUG(10,
"isSignal is not True. There was an additional particle left.");
251 decay->setObj(
nullptr);
257 B2DEBUG(19,
"Match found!");
271 vector<const MCParticle*> tmp_children;
272 const vector<MCParticle*>& genDaughters = gen->
getDaughters();
273 for (
auto daug : genDaughters) {
274 tmp_children.push_back(daug);
275 children.push_back(daug);
277 for (
auto child : tmp_children) {
284 const int nDaughter = d->getNDaughters();
285 if (nDaughter == 0)
return nDaughter;
287 int nDaughterRecursive = nDaughter;
288 for (
int iDaug = 0; iDaug < nDaughter; iDaug++) {
294 return nDaughterRecursive;
300 for (
int i = 0; i < d->getNDaughters(); i++) {
304 if (tmp_depth > maxDepth)
305 maxDepth = tmp_depth;
322 const vector<DecayTree<MCParticle>*> decayDaughters = decay->
getDaughters();
325 if ((
int)decayDaughters.size() != nDaughters) {
326 B2ERROR(
"MCDecayFinderModule::buildParticleFromDecayTree Inconsistency on the number of daughters between DecayTree and DecayDescriptor");
353 std::vector<std::pair<int, int>> daughtersDepthMapD;
354 for (
int iDD = 0; iDD < nDaughters; iDD++) {
359 daughtersDepthMapD.push_back({-1 * depth, iDD});
361 std::sort(daughtersDepthMapD.begin(), daughtersDepthMapD.end());
363 for (
int iDD = 0; iDD < nDaughters; iDD++) {
365 int index_decayDaughter = 0;
366 for (
auto pair : daughtersDepthMapD) {
367 if (pair.second == iDD)
break;
368 index_decayDaughter++;
374 newParticle->
appendDaughter(partDaughter,
false, daughterProperty);
399 if (existingParticle.isCopyOf(newParticle))
int getPDGCode() const
PDG code.
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 getPDGCode() const
Return PDG code.
int getProperty() const
return property of the particle.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
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.
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.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
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 int getMCErrors(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle=nullptr)
Returns quality indicator of the match as a bit pattern where the individual bits indicate the the ty...
static bool isFSP(int pdg)
Returns true if given PDG code indicates a FSP.