Belle II Software  release-05-01-25
ParticleCombiner.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014-2019 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Thomas Keck, Anze Zupanc *
7  * Sam Cunliffe, Torben Ferber *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <analysis/ParticleCombiner/ParticleCombiner.h>
13 
14 #include <analysis/DecayDescriptor/DecayDescriptor.h>
15 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
16 
17 #include <framework/logging/Logger.h>
18 
19 #include <mdst/dataobjects/ECLCluster.h>
20 
21 #include <algorithm>
22 
23 namespace Belle2 {
29  void ParticleIndexGenerator::init(const std::vector<unsigned>& _sizes)
30  {
31 
32  m_numberOfLists = _sizes.size();
33  sizes = _sizes;
34 
35  m_iCombination = 0;
36 
37  indices.resize(m_numberOfLists);
38  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
39  indices[i] = 0;
40  }
41 
42  m_nCombinations = 1;
43  for (unsigned int i = 0; i < m_numberOfLists; ++i)
44  m_nCombinations *= sizes[i];
45 
46  if (m_numberOfLists == 0) {
47  m_nCombinations = 0;
48  }
49 
50  }
51 
53  {
54 
56  return false;
57  }
58 
59  if (m_iCombination > 0) {
60 
61  // TF SC this does not yet account for double counting so will produce:
62  // { 000, 100, 200, ... 010, 110, .... } even if the first and second
63  // place are the same particle list
64  for (unsigned int i = 0; i < m_numberOfLists; i++) {
65  indices[i]++;
66  if (indices[i] < sizes[i]) break;
67  indices[i] = 0;
68  }
69 
70  }
71 
73  return true;
74  }
75 
76  const std::vector<unsigned int>& ParticleIndexGenerator::getCurrentIndices() const
77  {
78  return indices;
79  }
80 
81  void ListIndexGenerator::init(unsigned int _numberOfLists)
82  {
83  m_numberOfLists = _numberOfLists;
84  m_types.resize(m_numberOfLists);
85 
86  m_iCombination = 0;
87  m_nCombinations = (1 << m_numberOfLists) - 1;
88 
89  }
90 
92  {
93 
95  return false;
96 
97  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
98  bool useSelfConjugatedDaughterList = (m_iCombination & (1 << i));
99  m_types[i] = useSelfConjugatedDaughterList ? ParticleList::c_SelfConjugatedParticle : ParticleList::c_FlavorSpecificParticle;
100  }
101 
102  ++m_iCombination;
103  return true;
104  }
105 
106  const std::vector<ParticleList::EParticleType>& ListIndexGenerator::getCurrentIndices() const
107  {
108  return m_types;
109  }
110 
111  ParticleGenerator::ParticleGenerator(const std::string& decayString, const std::string& cutParameter) : m_iParticleType(0),
112  m_listIndexGenerator(),
113  m_particleIndexGenerator()
114  {
115 
116  DecayDescriptor decaydescriptor;
117  bool valid = decaydescriptor.init(decayString);
118  if (!valid)
119  B2ERROR("Invalid input DecayString: " << decayString);
120 
121  m_properties = decaydescriptor.getProperty();
122 
123  // Mother particle
124  const DecayDescriptorParticle* mother = decaydescriptor.getMother();
125  m_pdgCode = mother->getPDGCode();
126  m_properties |= mother->getProperty();
127 
128  // Daughters
129  m_numberOfLists = decaydescriptor.getNDaughters();
130  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
131  // Get the mother of the subdecaystring of the ith daughter
132  // eg. "B -> [D -> K pi] [tau -> pi pi pi]". The 0th daughter is the
133  // *decaystring* D -> K pi whose mother is the D.
134  const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
135  StoreObjPtr<ParticleList> list(daughter->getFullName());
136  m_plists.push_back(list);
137 
138  int daughterProperty = daughter->getProperty();
139  m_daughterProperties.push_back(daughterProperty);
140  }
141 
142  m_cut = Variable::Cut::compile(cutParameter);
143 
144  m_isSelfConjugated = decaydescriptor.isSelfConjugated();
145 
146  // check if input lists can contain copies
147  // remember (list_i, list_j) pairs, where list_i and list_j can contain copies
148  m_inputListsCollide = false;
149  m_collidingLists.clear();
150  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
151  const DecayDescriptorParticle* daughter_i = decaydescriptor.getDaughter(i)->getMother();
152  for (unsigned int j = i + 1; j < m_numberOfLists; ++j) {
153  const DecayDescriptorParticle* daughter_j = decaydescriptor.getDaughter(j)->getMother();
154 
155  if (abs(daughter_i->getPDGCode()) != abs(daughter_j->getPDGCode()))
156  continue;
157 
158  if (daughter_i->getLabel() != daughter_j->getLabel()) {
159  m_inputListsCollide = true;
160  m_collidingLists.emplace_back(i, j);
161  }
162  }
163  }
164 
165  }
166 
167 
168  ParticleGenerator::ParticleGenerator(const DecayDescriptor& decaydescriptor, const std::string& cutParameter) : m_iParticleType(0),
169  m_listIndexGenerator(),
170  m_particleIndexGenerator()
171  {
172  bool valid = decaydescriptor.isInitOK();
173  if (!valid)
174  B2ERROR("Given decaydescriptor failed to initialized");
175 
176  m_properties = decaydescriptor.getProperty();
177 
178  // Mother particle
179  const DecayDescriptorParticle* mother = decaydescriptor.getMother();
180  m_pdgCode = mother->getPDGCode();
181  m_properties |= mother->getProperty();
182 
183  // Daughters
184  m_numberOfLists = decaydescriptor.getNDaughters();
185  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
186  // Get the mother of the subdecaystring of the ith daughter
187  // eg. "B -> [D -> K pi] [tau -> pi pi pi]". The 0th daughter is the
188  // *decaystring* D -> K pi whose mother is the D.
189  const DecayDescriptorParticle* daughter = decaydescriptor.getDaughter(i)->getMother();
190  StoreObjPtr<ParticleList> list(daughter->getFullName());
191  m_plists.push_back(list);
192 
193  int daughterProperty = daughter->getProperty();
194  m_daughterProperties.push_back(daughterProperty);
195  }
196 
197  m_cut = Variable::Cut::compile(cutParameter);
198 
199  m_isSelfConjugated = decaydescriptor.isSelfConjugated();
200 
201  // check if input lists can contain copies
202  // remember (list_i, list_j) pairs, where list_i and list_j can contain copies
203  m_inputListsCollide = false;
204  m_collidingLists.clear();
205  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
206  const DecayDescriptorParticle* daughter_i = decaydescriptor.getDaughter(i)->getMother();
207  for (unsigned int j = i + 1; j < m_numberOfLists; ++j) {
208  const DecayDescriptorParticle* daughter_j = decaydescriptor.getDaughter(j)->getMother();
209 
210  if (abs(daughter_i->getPDGCode()) != abs(daughter_j->getPDGCode()))
211  continue;
212 
213  if (daughter_i->getLabel() != daughter_j->getLabel()) {
214  m_inputListsCollide = true;
215  m_collidingLists.emplace_back(i, j);
216  }
217  }
218  }
219 
220  }
221 
223  {
224  m_iParticleType = 0;
225 
226  m_particleIndexGenerator.init(std::vector<unsigned int> {}); // ParticleIndexGenerator will be initialised on first call
227  m_listIndexGenerator.init(m_numberOfLists); // ListIndexGenerator must be initialised here!
228  m_usedCombinations.clear();
229  m_indices.resize(m_numberOfLists);
231 
234  }
235 
237  {
238  m_indicesToUniqueIDs.clear();
239 
240  unsigned inputParticlesCount = 0;
241  for (unsigned int i = 0; i < m_numberOfLists; ++i)
242  inputParticlesCount += m_plists[i]->getListSize();
243 
244  m_indicesToUniqueIDs.reserve(inputParticlesCount);
245 
246  int uniqueID = 1;
247 
248  for (auto& collidingList : m_collidingLists) {
249  StoreObjPtr<ParticleList> listA = m_plists[collidingList.first];
250  StoreObjPtr<ParticleList> listB = m_plists[collidingList.second];
251 
252  bool sameSign = (listA->getPDGCode() == listB->getPDGCode());
253 
254  // if sameSign == true then
255  // 1. compare FS to FS particles in lists A and B
256  // 2. compare anti-FS to anti-FS particles in lists A and B
257  // else
258  // 1. compare FS to anti-FS particles in lists A and B
259  // 2. compare anti-FS to FS particles in lists A and B
260  // and in either case compare
261  // 3. compare SC to SC particles in lists A and B
262  if (sameSign) {
263  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, false),
264  listB->getList(ParticleList::c_FlavorSpecificParticle, false), uniqueID);
265  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, true),
266  listB->getList(ParticleList::c_FlavorSpecificParticle, true), uniqueID);
267  } else {
268  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, false),
269  listB->getList(ParticleList::c_FlavorSpecificParticle, true), uniqueID);
270  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, true),
271  listB->getList(ParticleList::c_FlavorSpecificParticle, false), uniqueID);
272  }
273 
274  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_SelfConjugatedParticle),
275  listB->getList(ParticleList::c_SelfConjugatedParticle), uniqueID);
276  }
277 
278  // assign unique ids to others as well
279  for (unsigned i = 0; i < m_numberOfLists; i++) {
281 
282  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, true), uniqueID);
283  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_FlavorSpecificParticle, false), uniqueID);
284  fillIndicesToUniqueIDMap(listA->getList(ParticleList::c_SelfConjugatedParticle), uniqueID);
285  }
286  }
287 
288  void ParticleGenerator::fillIndicesToUniqueIDMap(const std::vector<int>& listA, const std::vector<int>& listB, int& uniqueID)
289  {
290  const Particle* A, *B;
291  bool copies = false;
292  for (int i : listA) {
293  bool aIsAlreadyIn = m_indicesToUniqueIDs.count(i) ? true : false;
294 
295  if (not aIsAlreadyIn)
296  m_indicesToUniqueIDs[ i ] = uniqueID++;
297 
298  for (int j : listB) {
299  bool bIsAlreadyIn = m_indicesToUniqueIDs.count(j) ? true : false;
300 
301  if (bIsAlreadyIn)
302  continue;
303 
304  // are these two particles copies
305  A = m_particleArray[ i ];
306  B = m_particleArray[ j ];
307  copies = B->isCopyOf(A);
308 
309  if (copies)
311  }
312  }
313  }
314 
315 
316  void ParticleGenerator::fillIndicesToUniqueIDMap(const std::vector<int>& listA, int& uniqueID)
317  {
318  for (int i : listA) {
319  bool aIsAlreadyIn = m_indicesToUniqueIDs.count(i) ? true : false;
320 
321  if (not aIsAlreadyIn)
322  m_indicesToUniqueIDs[ i ] = uniqueID++;
323  }
324  }
325 
326 
327  bool ParticleGenerator::loadNext(bool loadAntiParticle)
328  {
329 
330  bool loadedNext = false;
337  while (true) {
338  if (m_iParticleType == 0) {
339  loadedNext = loadNextParticle(false);
340  } else if (m_iParticleType == 1 and loadAntiParticle) {
341  loadedNext = loadNextParticle(true);
342  } else if (m_iParticleType == 2) {
343  loadedNext = loadNextSelfConjugatedParticle();
344  } else {
345  return false;
346  }
347 
348  if (loadedNext) return true;
349  else ++m_iParticleType;
350 
351  if (m_iParticleType == 2) {
352  std::vector<unsigned int> sizes(m_numberOfLists);
353  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
354  sizes[i] = m_plists[i]->getList(ParticleList::c_SelfConjugatedParticle, false).size();
355  }
357  } else {
359  }
360 
361  }
362  }
363 
364  bool ParticleGenerator::loadNextParticle(bool useAntiParticle)
365  {
366  while (true) {
367 
368  // Load next index combination if available
370 
371  const auto& m_types = m_listIndexGenerator.getCurrentIndices();
372  const auto& indices = m_particleIndexGenerator.getCurrentIndices();
373 
374  for (unsigned int i = 0; i < m_numberOfLists; i++) {
375  const auto& list = m_plists[i]->getList(m_types[i], m_types[i] == ParticleList::c_FlavorSpecificParticle ? useAntiParticle : false);
376  m_indices[i] = list[ indices[i] ];
378  }
379 
380  if (not currentCombinationHasDifferentSources()) continue;
381 
383  if (!m_cut->check(&m_current_particle))
384  continue;
385 
386  if (not currentCombinationIsUnique()) continue;
387 
388  if (not currentCombinationIsECLCRUnique()) continue;
389 
390  return true;
391  }
392 
393  // Load next list combination if available and reset indexCombiner
395  const auto& m_types = m_listIndexGenerator.getCurrentIndices();
396  std::vector<unsigned int> sizes(m_numberOfLists);
397  for (unsigned int i = 0; i < m_numberOfLists; ++i) {
398  sizes[i] = m_plists[i]->getList(m_types[i], m_types[i] == ParticleList::c_FlavorSpecificParticle ? useAntiParticle : false).size();
399  }
401  continue;
402  }
403  return false;
404  }
405 
406  }
407 
409  {
410  while (true) {
411 
412  // Load next index combination if available
414 
415  const auto& indices = m_particleIndexGenerator.getCurrentIndices();
416 
417  for (unsigned int i = 0; i < m_numberOfLists; i++) {
418  m_indices[i] = m_plists[i]->getList(ParticleList::c_SelfConjugatedParticle, false) [ indices[i] ];
420  }
421 
422  if (not currentCombinationHasDifferentSources()) continue;
423 
425  if (!m_cut->check(&m_current_particle))
426  continue;
427 
428  if (not currentCombinationIsUnique()) continue;
429 
430  if (not currentCombinationIsECLCRUnique()) continue;
431 
432  return true;
433  }
434 
435  return false;
436  }
437 
438  }
439 
441  {
442  //TLorentzVector performance is quite horrible, do it ourselves.
443  double px = 0;
444  double py = 0;
445  double pz = 0;
446  double E = 0;
447  for (const Particle* d : m_particles) {
448  px += d->getPx();
449  py += d->getPy();
450  pz += d->getPz();
451  E += d->getEnergy();
452  }
453  const TLorentzVector vec(px, py, pz, E);
454 
455  switch (m_iParticleType) {
462  case 2: return Particle(vec, m_pdgCode, Particle::c_Unflavored, m_indices,
465  default: B2FATAL("You called getCurrentParticle although loadNext should have returned false!");
466  }
467 
468  return Particle(); // This should never happen
469  }
470 
472  {
473  return m_current_particle;
474  }
475 
477  {
478  std::vector<Particle*> stack = m_particles;
479  static std::vector<int> sources; // stack for particle sources
480  sources.clear();
481 
482  // recursively check all daughters and daughters of daughters
483  while (!stack.empty()) {
484  Particle* p = stack.back();
485  stack.pop_back();
486  const std::vector<int>& daughters = p->getDaughterIndices();
487 
488  if (daughters.empty()) {
489  int source = p->getMdstSource();
490  for (int i : sources) {
491  if (source == i) return false;
492  }
493  sources.push_back(source);
494  } else {
495  for (int daughter : daughters) stack.push_back(m_particleArray[daughter]);
496  }
497  }
498  return true;
499  }
500 
501 
503  {
504  std::set<int> indexSet;
505  if (not m_inputListsCollide)
506  indexSet.insert(m_indices.begin(), m_indices.end());
507  else
508  for (unsigned int i = 0; i < m_numberOfLists; i++)
509  indexSet.insert(m_indicesToUniqueIDs.at(m_indices[i]));
510 
511  bool elementInserted = m_usedCombinations.insert(indexSet).second;
512  return elementInserted;
513  }
514 
515  bool ParticleGenerator::inputListsCollide(const std::pair<unsigned, unsigned>& pair) const
516  {
517  for (const auto& collidingList : m_collidingLists)
518  if (pair == collidingList)
519  return true;
520 
521  return false;
522  }
523 
525  {
526  unsigned nECLSource = 0;
527  std::vector<Particle*> stack = m_particles;
528  static std::vector<int> connectedregions;
529  static std::vector<ECLCluster::EHypothesisBit> hypotheses;
530  connectedregions.clear();
531  hypotheses.clear();
532 
533  // recursively check all daughters and daughters of daughters
534  while (!stack.empty()) {
535  Particle* p = stack.back();
536  stack.pop_back();
537  const std::vector<int>& daughters = p->getDaughterIndices();
538 
539  if (daughters.empty()) {
540  // Only test if the particle was created from an ECLCluster at source.
541  // This CAN CHANGE if we change the cluster <--> track matching,
542  // (currently we match nPhotons clusters to all track type particles,
543  // i.e. electrons, pions, kaons etc. We might gain by matching
544  // neutralHadron hypothesis clusters to kaons, for example).
545  //
546  // In the above case one would need to extend the check to ALL
547  // particles with an associated ECLCluster. Then replace the following
548  // active line with two lines...
549  //
550  // auto cluster = p->getECLCluster();
551  // if (cluster) { // then do stuff
552  if (p->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster) {
553  nECLSource++;
554  auto* cluster = p->getECLCluster();
555  connectedregions.push_back(cluster->getConnectedRegionId());
556  hypotheses.push_back(p->getECLClusterEHypothesisBit());
557  }
558  } else {
559  for (int daughter : daughters) stack.push_back(m_particleArray[daughter]);
560  }
561  }
562 
563  // less than two particles from an ECL source is fine
564  // (unless cluster <--> track matching changes)
565  if (nECLSource < 2) return true;
566 
567  // yes this is a nested for loop but it's fast, we promise
568  for (unsigned icr = 0; icr < connectedregions.size(); ++icr)
569  for (unsigned jcr = icr + 1; jcr < connectedregions.size(); ++jcr)
570  if (connectedregions[icr] == connectedregions[jcr])
571  if (hypotheses[icr] != hypotheses[jcr]) return false;
572 
573  return true;
574  }
575 
576  int ParticleGenerator::getUniqueID(int index) const
577  {
578  if (not m_inputListsCollide)
579  return 0;
580 
581  if (not m_indicesToUniqueIDs.count(index))
582  return -1;
583 
584  return m_indicesToUniqueIDs.at(index);
585  }
587 }
Belle2::ParticleGenerator::m_indices
std::vector< int > m_indices
Indices stored in the ParticleLists of the current combination.
Definition: ParticleCombiner.h:275
Belle2::GeneralCut::compile
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
Definition: GeneralCut.h:114
Belle2::ParticleIndexGenerator::indices
std::vector< unsigned int > indices
The indices of the current loaded combination.
Definition: ParticleCombiner.h:82
Belle2::ParticleGenerator::m_listIndexGenerator
ListIndexGenerator m_listIndexGenerator
listIndexGenerator makes the combinations of the types of sublists of the ParticleLists
Definition: ParticleCombiner.h:269
Belle2::ParticleGenerator::initIndicesToUniqueIDMap
void initIndicesToUniqueIDMap()
In the case input daughter particle lists collide (two or more lists contain copies of Particles) the...
Definition: ParticleCombiner.cc:245
Belle2::ParticleGenerator::init
void init()
Initialises the generator to produce the given type of sublist.
Definition: ParticleCombiner.cc:231
Belle2::ParticleGenerator::getUniqueID
int getUniqueID(int index) const
Returns the unique ID assigned to Particle with given index from the IndicesToUniqueID map.
Definition: ParticleCombiner.cc:585
Belle2::ParticleGenerator::m_pdgCode
int m_pdgCode
PDG Code of the particle which is combined.
Definition: ParticleCombiner.h:259
Belle2::ParticleGenerator::loadNextParticle
bool loadNextParticle(bool useAntiParticle)
Loads the next combination.
Definition: ParticleCombiner.cc:373
Belle2::ListIndexGenerator::getCurrentIndices
const std::vector< ParticleList::EParticleType > & getCurrentIndices() const
Returns the type of the sublist of the current loaded combination.
Definition: ParticleCombiner.cc:115
Belle2::ParticleGenerator::loadNext
bool loadNext(bool loadAntiParticle=true)
Loads the next combination.
Definition: ParticleCombiner.cc:336
Belle2::DecayDescriptorParticle::getPDGCode
int getPDGCode() const
Return PDG code.
Definition: DecayDescriptorParticle.h:89
Belle2::DecayDescriptorParticle
Represents a particle in the DecayDescriptor.
Definition: DecayDescriptorParticle.h:37
Belle2::ParticleGenerator::m_isSelfConjugated
bool m_isSelfConjugated
True if the combined particle is self-conjugated.
Definition: ParticleCombiner.h:260
Belle2::ParticleGenerator::m_particleArray
const StoreArray< Particle > m_particleArray
Global list of particles.
Definition: ParticleCombiner.h:273
Belle2::ParticleGenerator::m_cut
std::unique_ptr< Variable::Cut > m_cut
cut object which performs the cuts
Definition: ParticleCombiner.h:283
Belle2::DecayDescriptor::init
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
Definition: DecayDescriptor.cc:47
Belle2::ParticleGenerator::fillIndicesToUniqueIDMap
void fillIndicesToUniqueIDMap(const std::vector< int > &listA, const std::vector< int > &listB, int &uniqueID)
Assignes unique IDs to all particles in list A, which do not have the unique ID already assigned.
Definition: ParticleCombiner.cc:297
Belle2::ParticleGenerator::m_collidingLists
std::vector< std::pair< unsigned, unsigned > > m_collidingLists
pairs of lists that can contain copies.
Definition: ParticleCombiner.h:279
Belle2::ListIndexGenerator::m_types
std::vector< ParticleList::EParticleType > m_types
The current types of sublist of the ParticleLists for this combination.
Definition: ParticleCombiner.h:122
Belle2::ParticleGenerator::m_numberOfLists
unsigned int m_numberOfLists
Number of lists which are combined.
Definition: ParticleCombiner.h:265
Belle2::ParticleGenerator::m_particleIndexGenerator
ParticleIndexGenerator m_particleIndexGenerator
particleIndexGenerator makes the combinations of indices stored in the sublists of the ParticleLists
Definition: ParticleCombiner.h:271
Belle2::ParticleGenerator::inputListsCollide
bool inputListsCollide() const
True if input lists collide (can contain copies of particles in the input lists).
Definition: ParticleCombiner.h:169
Belle2::ParticleIndexGenerator::init
void init(const std::vector< unsigned int > &_sizes)
Initialises the generator to produce combinations with the given sizes of each particle list.
Definition: ParticleCombiner.cc:38
Belle2::Particle::c_Flavored
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:97
Belle2::DecayDescriptorParticle::getLabel
std::string getLabel() const
The label of this particle, "default" returned, when no label set.
Definition: DecayDescriptorParticle.h:84
Belle2::ParticleGenerator::m_particles
std::vector< Particle * > m_particles
Pointers to the particle objects of the current combination.
Definition: ParticleCombiner.h:274
Belle2::ParticleGenerator::currentCombinationHasDifferentSources
bool currentCombinationHasDifferentSources()
Check that all FS particles of a combination differ.
Definition: ParticleCombiner.cc:485
Belle2::ParticleGenerator::ParticleGenerator
ParticleGenerator(const std::string &decayString, const std::string &cutParameter="")
Initialises the generator to produce the given type of sublist.
Definition: ParticleCombiner.cc:120
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::ParticleIndexGenerator::m_numberOfLists
unsigned int m_numberOfLists
Number of lists which are combined.
Definition: ParticleCombiner.h:79
Belle2::ParticleGenerator::m_indicesToUniqueIDs
std::unordered_map< int, int > m_indicesToUniqueIDs
map of store array indices of input Particles to their unique IDs.
Definition: ParticleCombiner.h:281
Belle2::ParticleGenerator::getCurrentParticle
Particle getCurrentParticle() const
Returns the particle.
Definition: ParticleCombiner.cc:480
Belle2::ParticleIndexGenerator::loadNext
bool loadNext()
Loads the next combination.
Definition: ParticleCombiner.cc:61
Belle2::Particle::c_Unflavored
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:96
Belle2::ListIndexGenerator::m_nCombinations
unsigned int m_nCombinations
The total amount of combinations.
Definition: ParticleCombiner.h:121
Belle2::DecayDescriptor::getDaughter
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
Definition: DecayDescriptor.h:146
Belle2::ParticleGenerator::m_daughterProperties
std::vector< int > m_daughterProperties
Daughter's particle properties.
Definition: ParticleCombiner.h:263
Belle2::ListIndexGenerator::m_iCombination
unsigned int m_iCombination
The current position of the combination.
Definition: ParticleCombiner.h:120
Belle2::ParticleGenerator::m_iParticleType
unsigned int m_iParticleType
The type of particle which is currently generated.
Definition: ParticleCombiner.h:261
Belle2::DecayDescriptor::getNDaughters
int getNDaughters() const
return number of direct daughters.
Definition: DecayDescriptor.h:141
Belle2::ParticleIndexGenerator::m_iCombination
unsigned int m_iCombination
The current position of the combination.
Definition: ParticleCombiner.h:80
Belle2::ParticleGenerator::m_usedCombinations
std::unordered_set< std::set< int > > m_usedCombinations
already used combinations (as sets of indices or unique IDs).
Definition: ParticleCombiner.h:276
Belle2::ListIndexGenerator::init
void init(unsigned int _numberOfLists)
Initialises the generator to produce the given type of sublist.
Definition: ParticleCombiner.cc:90
Belle2::StoreArray::getPtr
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:321
Belle2::ParticleIndexGenerator::getCurrentIndices
const std::vector< unsigned int > & getCurrentIndices() const
Returns theindices of the current loaded combination.
Definition: ParticleCombiner.cc:85
Belle2::ParticleGenerator::m_inputListsCollide
bool m_inputListsCollide
True if the daughter lists can contain copies of Particles.
Definition: ParticleCombiner.h:278
Belle2::ParticleGenerator::m_current_particle
Particle m_current_particle
The current Particle object generated by this combiner.
Definition: ParticleCombiner.h:285
Belle2::Particle
Class to store reconstructed particles.
Definition: Particle.h:77
Belle2::ParticleGenerator::m_plists
std::vector< StoreObjPtr< ParticleList > > m_plists
particle lists
Definition: ParticleCombiner.h:266
Belle2::ParticleIndexGenerator::m_nCombinations
unsigned int m_nCombinations
The total amount of combinations.
Definition: ParticleCombiner.h:81
Belle2::ParticleGenerator::currentCombinationIsECLCRUnique
bool currentCombinationIsECLCRUnique()
Check that: if the current combination has at least two particles from an ECL source,...
Definition: ParticleCombiner.cc:533
Belle2::ListIndexGenerator::m_numberOfLists
unsigned int m_numberOfLists
Number of lists which are combined.
Definition: ParticleCombiner.h:119
Belle2::DecayDescriptor
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
Definition: DecayDescriptor.h:43
Belle2::ParticleGenerator::currentCombinationIsUnique
bool currentCombinationIsUnique()
Check that the combination is unique.
Definition: ParticleCombiner.cc:511
Belle2::DecayDescriptor::getProperty
int getProperty() const
return property of the particle.
Definition: DecayDescriptor.h:151
Belle2::ParticleIndexGenerator::sizes
std::vector< unsigned int > sizes
The sizes of the particle lists which are combined.
Definition: ParticleCombiner.h:83
Belle2::ParticleGenerator::createCurrentParticle
Particle createCurrentParticle() const
Create current particle object.
Definition: ParticleCombiner.cc:449
Belle2::ParticleGenerator::m_properties
int m_properties
Particle property.
Definition: ParticleCombiner.h:262
Belle2::DecayDescriptor::getMother
const DecayDescriptorParticle * getMother() const
return mother.
Definition: DecayDescriptor.h:136
Belle2::DecayDescriptor::isSelfConjugated
bool isSelfConjugated() const
Is the decay or the particle self conjugated.
Definition: DecayDescriptor.cc:325
Belle2::ParticleGenerator::loadNextSelfConjugatedParticle
bool loadNextSelfConjugatedParticle()
Loads the next combination.
Definition: ParticleCombiner.cc:417