Belle II Software development
DecayDescriptor Class Reference

The DecayDescriptor stores information about a decay tree or parts of a decay tree. More...

#include <DecayDescriptor.h>

Public Member Functions

 operator DecayDescriptor * ()
 Dereference operator.
 
 DecayDescriptor ()
 Default ctor.
 
 DecayDescriptor (const DecayDescriptor &)=default
 Want the default copy ctor.
 
DecayDescriptoroperator= (const DecayDescriptor &)=default
 Want the default assignment operator.
 
std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected ()
 Function to get hierarchy of selected particles and their names (for python use)
 
std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected (const std::vector< std::pair< int, std::string > > &currentPath)
 Helper function to get hierarchy of selected particles and their names.
 
bool init (const std::string &str)
 Initialise the DecayDescriptor from given string.
 
bool init (const DecayString &s)
 Initialise the DecayDescriptor from a given DecayString.
 
int match (const Particle *p)
 Check if the DecayDescriptor matches with the given Particle.
 
int match (const MCParticle *p)
 See match(const Particle* p).
 
int getMatchedDaughter ()
 Particle daughter ID set by previous call of match(const Particle*) function.
 
void resetMatch ()
 Reset results from previous call of the match() function.
 
std::vector< const Particle * > getSelectionParticles (const Particle *particle)
 Get a vector of pointers with selected daughters in the decay tree.
 
std::vector< std::string > getSelectionNames ()
 Return list of human readable names of selected particles.
 
std::vector< int > getSelectionPDGCodes ()
 Return list of PDG codes of selected particles.
 
const DecayDescriptorParticlegetMother () const
 return mother.
 
int getNDaughters () const
 return number of direct daughters.
 
const DecayDescriptorgetDaughter (int i) const
 return i-th daughter (0 based index).
 
int getProperty () const
 return property of the particle.
 
bool isIgnoreRadiatedPhotons () const
 Check if additional radiated photons shall be ignored.
 
bool isIgnoreIntermediate () const
 Check if intermediate resonances/particles shall be ignored.
 
bool isIgnoreMassive () const
 Check if missing massive final state particles shall be ignored.
 
bool isIgnoreNeutrino () const
 Check if missing neutrinos shall be ignored.
 
bool isIgnoreGamma () const
 Check if missing gammas shall be ignored.
 
bool isIgnoreBrems () const
 Check if added Brems gammas shall be ignored.
 
bool isSelfConjugated () const
 Is the decay or the particle self conjugated.
 
bool isInitOK () const
 Check if the object initialized correctly.
 
bool getSelectionParticlesAndNames (const Particle *particle, std::vector< const Particle * > &selparticles, std::vector< std::string > &selnames)
 Takes as input argument a (reconstructed) Particle, tries to match with this DecayDescriptorElement and returns true when matched.
 

Private Member Functions

template<class T>
int match (const T *p, int iDaughter_p)
 Internally called by match(Particle*) and match(MCParticle*) function.
 

Private Attributes

DecayDescriptorParticle m_mother
 Mother of the decay ('left side').
 
int m_iDaughter_p
 ID of the Daughter Particle* matched to this DecayDescriptor.
 
std::vector< DecayDescriptorm_daughters
 Direct daughters of the decaying particle.
 
int m_properties
 Particle property.
 
bool m_isNULL
 Is this the NULL object?
 
std::vector< std::vector< std::pair< int, std::string > > > m_hierarchy
 Collection of hierarchy paths of selected particles.
 
bool m_isInitOK
 Is this object initialized correctly?
 

Detailed Description

The DecayDescriptor stores information about a decay tree or parts of a decay tree.

It contains the mother <-> daughter relations.

User documentation is located at analysis/doc/DecayDescriptor.rst Please modify in accordingly to introduced changes.

Definition at line 32 of file DecayDescriptor.h.

Constructor & Destructor Documentation

◆ DecayDescriptor()

Default ctor.

Definition at line 34 of file DecayDescriptor.cc.

34 :
35 m_mother(),
36 m_iDaughter_p(-1),
38 m_properties(0),
39 m_isNULL(false),
40 m_isInitOK(false)
41{
42}
DecayDescriptorParticle m_mother
Mother of the decay ('left side').
bool m_isInitOK
Is this object initialized correctly?
bool m_isNULL
Is this the NULL object?
std::vector< DecayDescriptor > m_daughters
Direct daughters of the decaying particle.
int m_iDaughter_p
ID of the Daughter Particle* matched to this DecayDescriptor.
int m_properties
Particle property.

Member Function Documentation

◆ getDaughter()

const DecayDescriptor * getDaughter ( int i) const
inline

return i-th daughter (0 based index).

Definition at line 136 of file DecayDescriptor.h.

137 {
138 return (i < getNDaughters()) ? &(m_daughters[i]) : nullptr;
139 }

◆ getHierarchyOfSelected() [1/2]

std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected ( )

Function to get hierarchy of selected particles and their names (for python use)

Definition at line 403 of file DecayDescriptor.cc.

404{
405 if (not m_hierarchy.empty()) {
406 std::vector<std::vector<std::pair<int, std::string>>> hierarchy = m_hierarchy;
407 return hierarchy;
408 }
409 std::vector<std::pair<int, std::string>> currentPath;
410 currentPath.emplace_back(0, m_mother.getNameSimple());
411 return getHierarchyOfSelected(currentPath);
412}
std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected()
Function to get hierarchy of selected particles and their names (for python use)
std::vector< std::vector< std::pair< int, std::string > > > m_hierarchy
Collection of hierarchy paths of selected particles.

◆ getHierarchyOfSelected() [2/2]

std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected ( const std::vector< std::pair< int, std::string > > & currentPath)

Helper function to get hierarchy of selected particles and their names.

Called iteratively and get hierarchy path of a particle as an argument

Definition at line 414 of file DecayDescriptor.cc.

416{
417 if (m_mother.isSelected()) m_hierarchy.push_back(currentPath);
418 for (std::size_t i = 0; i < m_daughters.size(); i++) {
419 std::vector<std::pair<int, std::string>> newPath = currentPath;
420 newPath.emplace_back(i, m_daughters[i].getMother()->getNameSimple());
421 std::vector<std::vector<std::pair<int, std::string>>> foundPathes = m_daughters[i].getHierarchyOfSelected(newPath);
422 for (auto& path : foundPathes) m_hierarchy.push_back(path);
423 }
424 std::vector<std::vector<std::pair<int, std::string>>> hierarchy = m_hierarchy;
425 return hierarchy;
426}
const DecayDescriptorParticle * getMother() const
return mother.

◆ getMatchedDaughter()

int getMatchedDaughter ( )
inline

Particle daughter ID set by previous call of match(const Particle*) function.

Definition at line 111 of file DecayDescriptor.h.

111{return m_iDaughter_p;}

◆ getMother()

const DecayDescriptorParticle * getMother ( ) const
inline

return mother.

Definition at line 126 of file DecayDescriptor.h.

127 {
128 return &m_mother;
129 }

◆ getNDaughters()

int getNDaughters ( ) const
inline

return number of direct daughters.

Definition at line 131 of file DecayDescriptor.h.

132 {
133 return m_daughters.size();
134 }

◆ getProperty()

int getProperty ( ) const
inline

return property of the particle.

Definition at line 141 of file DecayDescriptor.h.

142 {
143 return m_properties;
144 }

◆ getSelectionNames()

vector< string > getSelectionNames ( )

Return list of human readable names of selected particles.

Example for the case that all particles are selected in B+ -> (anti-D0 -> K^- pi^+) pi^+: ["B", "D0", "D0_K", "D_pi", "pi"]

Definition at line 340 of file DecayDescriptor.cc.

341{
342 vector<string> strNames;
343 if (m_mother.isSelected()) strNames.push_back(m_mother.getNameSimple());
344 for (auto& daughter : m_daughters) {
345 vector<string> strDaughterNames = daughter.getSelectionNames();
346 int nDaughters = strDaughterNames.size();
347 for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
348 // Checking variable naming scheme from AnalysisConfiguratin
349 // For example, effect of possible schemes for PX variable
350 // of pi0 from D in decay B->(D->pi0 pi) pi0:
351 // default: B_D_pi0_PX
352 // semidefault: D_pi0_PX
353 // laconic: pi01_PX
354 if (AnalysisConfiguration::instance()->getTupleStyle() == "laconic") continue;
355 if ((AnalysisConfiguration::instance()->getTupleStyle() == "semilaconic") && (iDaughter == nDaughters)) continue;
356 strDaughterNames[iDaughter] = m_mother.getNameSimple() + "_" + strDaughterNames[iDaughter];
357 }
358 strNames.insert(strNames.end(), strDaughterNames.begin(), strDaughterNames.end());
359 }
360
361 // search for multiple occurrence of the same name and then distinguish by attaching a number
362
363 for (auto itName = strNames.begin(); itName != strNames.end(); ++itName) {
364 if (count(itName, strNames.end(), *itName) == 1) continue;
365 // multiple occurrence found!
366 string strNameOld = *itName;
367 auto itOccurrence = strNames.begin();
368 int iOccurrence = 0;
369 while (iOccurrence <= 10) {
370 // find next occurrence of the identical particle name defined in DecayDescriptor
371 itOccurrence = find(itOccurrence, strNames.end(), strNameOld);
372 // stop, if nothing found
373 if (itOccurrence == strNames.end()) break;
374 // create new particle name by attaching a number
375 string strNameNew = strNameOld + std::to_string(iOccurrence);
376 // check if the new particle name exists already, if not, then it is OK to use it
377 if (count(strNames.begin(), strNames.end(), strNameNew) == 0) {
378 *itOccurrence = strNameNew;
379 ++itOccurrence;
380 }
381 iOccurrence++;
382 }
383 if (iOccurrence == 10) {
384 B2ERROR("DecayDescriptor::getSelectionNames - Something is wrong! More than 10x the same name!");
385 break;
386 }
387 }
388 return strNames;
389}
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.

◆ getSelectionParticles()

vector< const Particle * > getSelectionParticles ( const Particle * particle)

Get a vector of pointers with selected daughters in the decay tree.

Definition at line 281 of file DecayDescriptor.cc.

282{
283 // Create vector for output
284 vector<const Particle*> selparticles;
285 if (m_mother.isSelected()) {
286 int motherPDG = abs(particle->getPDGCode());
287 int decayDescriptorMotherPDG = abs(m_mother.getPDGCode());
288 if (motherPDG != decayDescriptorMotherPDG)
289 B2ERROR("The PDG code of the mother particle (" << motherPDG <<
290 ") does not match the PDG code of the DecayDescriptor mother (" << decayDescriptorMotherPDG <<
291 ")! Check the order of the decay string is the same you expect in the reconstructed Particles.");
292 selparticles.push_back(particle);
293 }
294 int nDaughters_d = getNDaughters();
295 for (int iDaughter_d = 0; iDaughter_d < nDaughters_d; ++iDaughter_d) {
296 // retrieve the particle daughter ID from this DecayDescriptor daughter
297 int iDaughter_p = m_daughters[iDaughter_d].getMatchedDaughter();
298 // If the particle daughter ID is below one, the match function was not called before
299 // or the match was ambiguous. In this case try to use the daughter ID of the DecayDescriptor.
300 // This corresponds to using the particle order in the decay string.
301 if (iDaughter_p < 0) iDaughter_p = iDaughter_d;
302 const Particle* daughter = particle->getDaughter(iDaughter_p);
303 if (!daughter) {
304 B2WARNING("Could not find daughter!");
305 continue;
306 }
307 // check if the daughter has the correct PDG code
308 int daughterPDG = abs(daughter->getPDGCode());
309 int decayDescriptorDaughterPDG = abs(m_daughters[iDaughter_d].getMother()->getPDGCode());
310 if (daughterPDG != decayDescriptorDaughterPDG) {
311 B2ERROR("The PDG code of the particle daughter (" << daughterPDG <<
312 ") does not match the PDG code of the DecayDescriptor daughter (" << decayDescriptorDaughterPDG <<
313 ")! Check the order of the decay string is the same you expect in the reconstructed Particles.");
314 break;
315 }
316 vector<const Particle*> seldaughters = m_daughters[iDaughter_d].getSelectionParticles(daughter);
317 selparticles.insert(selparticles.end(), seldaughters.begin(), seldaughters.end());
318 }
319 return selparticles;
320}
int getNDaughters() const
return number of direct daughters.

◆ getSelectionPDGCodes()

vector< int > getSelectionPDGCodes ( )

Return list of PDG codes of selected particles.

Definition at line 391 of file DecayDescriptor.cc.

392{
393 vector<int> listPDG;
394 if (m_mother.isSelected()) listPDG.push_back(m_mother.getPDGCode());
395 for (auto& daughter : m_daughters) {
396 vector<int> listPDGDaughters = daughter.getSelectionPDGCodes();
397 listPDG.insert(listPDG.end(), listPDGDaughters.begin(), listPDGDaughters.end());
398 }
399 return listPDG;
400}

◆ init() [1/2]

bool init ( const DecayString & s)

Initialise the DecayDescriptor from a given DecayString.

The DecayString struct is obtained from the parser called in the init(const std::string) function.

Definition at line 56 of file DecayDescriptor.cc.

57{
58 // The DecayString is a hybrid, it can be
59 // a) DecayStringParticleList
60 // b) DecayStringDecay
61
62 if (const DecayStringParticle* p = boost::get< DecayStringParticle >(&s)) {
63 m_isInitOK = m_mother.init(*p);
64 if (!m_isInitOK) {
65 B2WARNING("Could not initialise mother particle " << p->m_strName);
66 return false;
67 }
68 return true;
69 } else if (const DecayStringDecay* d = boost::get< DecayStringDecay > (&s)) {
70 // Initialise list of mother particles
71 m_isInitOK = m_mother.init(d->m_mother);
72 if (!m_isInitOK) {
73 B2WARNING("Could not initialise mother particle " << d->m_mother.m_strName);
74 return false;
75 }
76
77 // Identify arrow type
78 if (d->m_strArrow == "->") {
81 } else if (d->m_strArrow == "=norad=>") {
83 } else if (d->m_strArrow == "=direct=>") {
85 } else if (d->m_strArrow == "=exact=>") {
86 // do nothing
87 } else {
88 B2WARNING("Unknown arrow: " << d->m_strArrow);
89 m_isInitOK = false;
90 return false;
91 }
92
93 // Initialise list of daughters
94 if (d->m_daughters.empty()) {
95 m_isInitOK = false;
96 return false;
97 }
98 int nDaughters = d->m_daughters.size();
99 for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
100 DecayDescriptor daughter;
101 m_isInitOK = daughter.init(d->m_daughters[iDaughter]);
102 if (!m_isInitOK) {
103 B2WARNING("Could not initialise daughter!");
104 return false;
105 }
106 m_daughters.push_back(daughter);
107 }
108
109 // Initialise list of keywords
110 // For neutrino
111 if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), "?nu")) != d->m_keywords.end()) {
113 }
114 // For gamma
115 if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), "?gamma")) != d->m_keywords.end()) {
117 }
118 // For massive FSP
119 if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), "...")) != d->m_keywords.end()) {
121 }
122 // For brems photons
123 if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), "?addbrems")) != d->m_keywords.end()) {
125 }
126
127 return true;
128 }
129 m_isInitOK = false;
130 return false;
131}
DecayDescriptor()
Default ctor.
@ c_IsIgnoreNeutrino
Is the particle MC matched with the ignore missing neutrino flag set?
Definition Particle.h:124
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
Definition Particle.h:121
@ c_IsIgnoreGamma
Is the particle MC matched with the ignore missing gamma flag set?
Definition Particle.h:125
@ c_IsIgnoreBrems
Is the particle MC matched with the ignore added Brems gamma flag set?
Definition Particle.h:126
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
Definition Particle.h:122
@ c_IsIgnoreMassive
Is the particle MC matched with the ignore missing massive particle flag set?
Definition Particle.h:123

◆ init() [2/2]

bool init ( const std::string & str)

Initialise the DecayDescriptor from given string.

Typically, the string is a parameter of an analysis module.

Definition at line 44 of file DecayDescriptor.cc.

45{
46 // The decay string grammar
47 DecayStringGrammar<std::string::const_iterator> g;
49 std::string::const_iterator iter = str.begin();
50 std::string::const_iterator end = str.end();
51 bool r = phrase_parse(iter, end, g, boost::spirit::unicode::space, s);
52 if (!r || iter != end) return false;
53 return init(s);
54}
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
boost::variant< boost::recursive_wrapper< DecayStringDecay >, DecayStringParticle > DecayString
The DecayStringElement can be either a DecayStringDecay or a vector of mother particles.
Definition DecayString.h:23

◆ isIgnoreBrems()

bool isIgnoreBrems ( ) const
inline

Check if added Brems gammas shall be ignored.

Definition at line 171 of file DecayDescriptor.h.

172 {
173 return (m_properties & Particle::PropertyFlags::c_IsIgnoreBrems) > 0;
174 }

◆ isIgnoreGamma()

bool isIgnoreGamma ( ) const
inline

Check if missing gammas shall be ignored.

Definition at line 166 of file DecayDescriptor.h.

167 {
168 return (m_properties & Particle::PropertyFlags::c_IsIgnoreGamma) > 0;
169 }

◆ isIgnoreIntermediate()

bool isIgnoreIntermediate ( ) const
inline

Check if intermediate resonances/particles shall be ignored.

Definition at line 151 of file DecayDescriptor.h.

152 {
153 return (m_properties & Particle::PropertyFlags::c_IsIgnoreIntermediate) > 0;
154 }

◆ isIgnoreMassive()

bool isIgnoreMassive ( ) const
inline

Check if missing massive final state particles shall be ignored.

Definition at line 156 of file DecayDescriptor.h.

157 {
158 return (m_properties & Particle::PropertyFlags::c_IsIgnoreMassive) > 0;
159 }

◆ isIgnoreNeutrino()

bool isIgnoreNeutrino ( ) const
inline

Check if missing neutrinos shall be ignored.

Definition at line 161 of file DecayDescriptor.h.

162 {
163 return (m_properties & Particle::PropertyFlags::c_IsIgnoreNeutrino) > 0;
164 }

◆ isIgnoreRadiatedPhotons()

bool isIgnoreRadiatedPhotons ( ) const
inline

Check if additional radiated photons shall be ignored.

Definition at line 146 of file DecayDescriptor.h.

147 {
148 return (m_properties & Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons) > 0;
149 }

◆ isInitOK()

bool isInitOK ( ) const
inline

Check if the object initialized correctly.

Definition at line 180 of file DecayDescriptor.h.

181 {
182 return m_isInitOK;
183 }

◆ isSelfConjugated()

bool isSelfConjugated ( ) const

Is the decay or the particle self conjugated.

Definition at line 322 of file DecayDescriptor.cc.

323{
324
325 std::vector<int> decay, decaybar;
326 for (int i = 0; i < getNDaughters(); ++i) {
327 const DecayDescriptorParticle* daughter = getDaughter(i)->getMother();
328 int pdg = daughter->getPDGCode();
329 decay.push_back(pdg);
330 decaybar.push_back(Belle2::EvtPDLUtil::hasAntiParticle(pdg) ? -pdg : pdg);
331 }
332
333 std::sort(decay.begin(), decay.end());
334 std::sort(decaybar.begin(), decaybar.end());
335
336 return (not Belle2::EvtPDLUtil::hasAntiParticle(getMother()->getPDGCode())) || (decay == decaybar);
337
338}
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
bool hasAntiParticle(int pdgCode)
Checks if the particle with given pdg code has an anti-particle or not.
Definition EvtPDLUtil.cc:12

◆ match() [1/3]

int match ( const MCParticle * p)
inline

See match(const Particle* p).

Definition at line 108 of file DecayDescriptor.h.

108{return match<MCParticle>(p, -1);}

◆ match() [2/3]

int match ( const Particle * p)
inline

Check if the DecayDescriptor matches with the given Particle.

0 = no match 1 = matches DecayDescriptor 2 = matches charge conjugated DecayDescriptor 3 = matches DeacyDescriptor AND charge conjugated DecayDescriptor -1, -2, -3 : same, but match is not unambiguous.

Definition at line 105 of file DecayDescriptor.h.

105{return match<Particle>(p, -1);}

◆ match() [3/3]

template<class T>
int match ( const T * p,
int iDaughter_p )
private

Internally called by match(Particle*) and match(MCParticle*) function.

Definition at line 134 of file DecayDescriptor.cc.

135{
136 // this DecayDescriptor was not matched or
137 // it is not the daughter of another DecayDescriptor
138 m_iDaughter_p = -1;
139
140 if (!p) {
141 B2WARNING("NULL pointer provided instead of particle.");
142 return 0;
143 }
144
145 int iPDGCode_p = 0;
146 if (const auto* part_test = dynamic_cast<const Particle*>(p))
147 iPDGCode_p = part_test->getPDGCode();
148 else if (const auto* mc_test = dynamic_cast<const MCParticle*>(p))
149 iPDGCode_p = mc_test->getPDG();
150 else {
151 B2WARNING("Template type not supported!");
152 return 0;
153 }
154
155 int iPDGCodeCC_p = TDatabasePDG::Instance()->GetParticle(iPDGCode_p)->AntiParticle()->PdgCode();
156 int iPDGCode_d = m_mother.getPDGCode();
157 if (abs(iPDGCode_d) != abs(iPDGCode_p)) return 0;
158 int iCC = 0;
159 if (iPDGCode_p == iPDGCodeCC_p) iCC = 3;
160 else if (iPDGCode_d == iPDGCode_p) iCC = 1;
161 else if (iPDGCode_d == iPDGCodeCC_p) iCC = 2;
162
163 const std::vector<T*> daughterList = p->getDaughters();
164 int nDaughters_p = daughterList.size();
165
166 // 1st case: the descriptor has no daughters => nothing to check
167 if (getNDaughters() == 0) {
168 m_iDaughter_p = iDaughter_p;
169 return iCC;
170 }
171
172 // 2nd case: the descriptor has daughters, but not the particle
173 // => that is not allowed!
174 if (nDaughters_p == 0) return 0;
175
176 // 3rd case: the descriptor and the particle have daughters
177 // There are two cases that can happen when matching the
178 // DecayDescriptor daughters to the particle daughters:
179 // 1. The match is unambiguous -> no problem
180 // 2. Multiple particle daughters match the same DecayDescriptor daughter
181 // -> in the latter case the ambiguity is resolved later
182
183 // 1. DecayDescriptor -> Particle relation for the cases where only one particle matches
184 vector< pair< int, int > > singlematch;
185 // 2. DecayDescriptor -> Particle relation for the cases where multiple particles match
186 vector< pair< int, set<int> > > multimatch;
187 // Are there ambiguities in the match?
188 bool isAmbiguities = false;
189 // The particle daughters that have been matched
190 set<int> matches_global;
191
192 // check if the daughters match
193 for (int iDaughter_d = 0; iDaughter_d < getNDaughters(); iDaughter_d++) {
194 set<int> matches;
195 for (int jDaughter_p = 0; jDaughter_p < nDaughters_p; jDaughter_p++) {
196 const T* daughter = daughterList[jDaughter_p];
197 int iPDGCode_daughter_p = 0;
198 if (const auto* part_test = dynamic_cast<const Particle*>(daughter))
199 iPDGCode_daughter_p = part_test->getPDGCode();
200 else if (const auto* mc_test = dynamic_cast<const MCParticle*>(daughter))
201 iPDGCode_daughter_p = mc_test->getPDG();
202
203 if (iDaughter_d == 0 && (this->isIgnoreRadiatedPhotons() or this->isIgnoreGamma() or this->isIgnoreBrems())
204 && iPDGCode_daughter_p == Const::photon.getPDGCode())
205 matches_global.insert(jDaughter_p);
206
207 int iMatchResult = m_daughters[iDaughter_d].match(daughter, jDaughter_p);
208 if (iMatchResult < 0) isAmbiguities = true;
209 if (abs(iMatchResult) == 2 && iCC == 1) continue;
210 if (abs(iMatchResult) == 1 && iCC == 2) continue;
211 if (abs(iMatchResult) == 2 && iCC == 3) continue;
212 matches.insert(jDaughter_p);
213 matches_global.insert(jDaughter_p);
214 }
215 if (matches.empty()) return 0;
216 if (matches.size() == 1) {
217 int jDaughter_p = *(matches.begin());
218 singlematch.emplace_back(iDaughter_d, jDaughter_p);
219 } else multimatch.emplace_back(iDaughter_d, matches);
220 }
221
222 // Now, all daughters of the particles should be matched to at least one DecayDescriptor daughter
223 if (!(this->isIgnoreIntermediate() or this->isIgnoreMassive() or this->isIgnoreNeutrino())
224 && int(matches_global.size()) != nDaughters_p) return 0;
225
226 // In case that there are DecayDescriptor daughters with multiple matches, try to solve the problem
227 // by removing the daughter candidates which are already used in other unambiguous relations.
228 // This is done iteratively. We limit the maximum number of attempts to 20 to avoid an infinite loop.
229 bool isModified = true;
230 for (int iTry = 0; iTry < 20; iTry++) {
231 if (int(singlematch.size()) == getNDaughters()) break;
232 if (!isModified) break;
233 isModified = false;
234 for (auto& itMulti : multimatch) {
235 for (auto& itSingle : singlematch) {
236 // try to remove particle from the multimatch list
237 if (itMulti.second.erase(itSingle.second)) {
238 B2FATAL("Trying to execute part of the code with known bug, which is not fixed yet! Send email to anze.zupanc@ijs.si with notification that this happens!");
239 /*
240 This part of the code is commented, because of the following error:
241 Iterator 'itMulti' used after element has been erased.
242
243 // if multimatch list contains only one particle candidate, move the entry to the singlematch list
244 if (itMulti->second.size() == 1) {
245 int iDaughter_d = itMulti->first;
246 int iDaughter_p = *(itMulti->second.begin());
247 singlematch.push_back(make_pair(iDaughter_d, iDaughter_p));
248 multimatch.erase(itMulti);
249 // call match function again to set the correct daughter
250 if (!isAmbiguities) {
251 const T* daughter = daughterList[iDaughter_p];
252 if (!daughter) continue;
253 m_daughters[iDaughter_d].match(daughter, iDaughter_p);
254 }
255 --itMulti;
256 isModified = true;
257 break;
258 }
259 */
260 }
261 }
262 }
263 }
264
265 if (!multimatch.empty()) isAmbiguities = true;
266 if (isAmbiguities) return -iCC;
267 else {
268 m_iDaughter_p = iDaughter_p;
269 return iCC;
270 }
271 return 0;
272}
static const ParticleType photon
photon particle
Definition Const.h:673
bool isIgnoreBrems() const
Check if added Brems gammas shall be ignored.
bool isIgnoreRadiatedPhotons() const
Check if additional radiated photons shall be ignored.
bool isIgnoreNeutrino() const
Check if missing neutrinos shall be ignored.
bool isIgnoreMassive() const
Check if missing massive final state particles shall be ignored.
bool isIgnoreGamma() const
Check if missing gammas shall be ignored.
bool isIgnoreIntermediate() const
Check if intermediate resonances/particles shall be ignored.

◆ operator DecayDescriptor *()

operator DecayDescriptor * ( )
inline

Dereference operator.

Definition at line 70 of file DecayDescriptor.h.

71 {
72 return m_isNULL ? nullptr : this;
73 }

◆ resetMatch()

void resetMatch ( )

Reset results from previous call of the match() function.

Definition at line 274 of file DecayDescriptor.cc.

275{
276 m_iDaughter_p = -1;
277 int nDaughters = m_daughters.size();
278 for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) m_daughters[iDaughter].resetMatch();
279}
void resetMatch()
Reset results from previous call of the match() function.

Member Data Documentation

◆ m_daughters

std::vector<DecayDescriptor> m_daughters
private

Direct daughters of the decaying particle.

Definition at line 40 of file DecayDescriptor.h.

◆ m_hierarchy

std::vector<std::vector<std::pair<int, std::string> > > m_hierarchy
private

Collection of hierarchy paths of selected particles.

Hierarchy path is vector of pairs of relative daughter numbers and particle names. For instance, in decay B+ -> [ D+ -> ^K+ pi0 ] pi0 decay path of K+ is [(0, B), (0, D), (0 K)] Every selected particle has its own hierarchy path and they are stored as a vector in this variable: For the decayString B+ -> [ D+ -> ^K+ pi0 ] ^pi0 m_hierarchy, once filled, is [[(0, B), (0, D), (0, K)], [(0, B), (1, pi0)]]

Definition at line 62 of file DecayDescriptor.h.

◆ m_iDaughter_p

int m_iDaughter_p
private

ID of the Daughter Particle* matched to this DecayDescriptor.

If this DecayDescriptor was not matched, the value is -1.

Definition at line 38 of file DecayDescriptor.h.

◆ m_isInitOK

bool m_isInitOK
private

Is this object initialized correctly?

Definition at line 65 of file DecayDescriptor.h.

◆ m_isNULL

bool m_isNULL
private

Is this the NULL object?

Definition at line 44 of file DecayDescriptor.h.

◆ m_mother

DecayDescriptorParticle m_mother
private

Mother of the decay ('left side').

Definition at line 35 of file DecayDescriptor.h.

◆ m_properties

int m_properties
private

Particle property.

Flags are defined in Particle::PropertyFlags

Definition at line 42 of file DecayDescriptor.h.


The documentation for this class was generated from the following files: