Belle II Software  release-06-02-00
combiner.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <analysis/ParticleCombiner/ParticleCombiner.h>
9 
10 #include <mdst/dataobjects/ECLCluster.h>
11 
12 #include <analysis/dataobjects/Particle.h>
13 #include <analysis/dataobjects/ParticleList.h>
14 
15 #include <analysis/DecayDescriptor/DecayDescriptor.h>
16 #include <analysis/utility/EvtPDLUtil.h>
17 
18 #include <framework/datastore/StoreArray.h>
19 #include <framework/datastore/StoreObjPtr.h>
20 #include <framework/gearbox/Const.h>
21 
22 #include <utility>
23 #include <algorithm>
24 
25 #include <gtest/gtest.h>
26 #include <set>
27 
28 //using namespace std;
29 using namespace Belle2;
30 
31 namespace {
33  class ParticleCombinerTest : public ::testing::Test {
34  protected:
36  void SetUp() override
37  {
39  StoreArray<Particle> particles;
40  particles.registerInDataStore();
41  StoreArray<ECLCluster> eclClusters;
42  eclClusters.registerInDataStore();
44  }
45 
47  void TearDown() override
48  {
50  }
51  };
52 
53  TEST_F(ParticleCombinerTest, ListIndexGeneratorTest)
54  {
55  {
56  ListIndexGenerator listIndexGenerator;
57  listIndexGenerator.init(0);
58  EXPECT_FALSE(listIndexGenerator.loadNext());
59  }
60 
61  {
62  ListIndexGenerator listIndexGenerator;
63  listIndexGenerator.init(1);
64  EXPECT_TRUE(listIndexGenerator.loadNext());
65  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle}),
66  listIndexGenerator.getCurrentIndices());
67  EXPECT_FALSE(listIndexGenerator.loadNext());
68  }
69 
70  {
71  ListIndexGenerator listIndexGenerator;
72  listIndexGenerator.init(2);
73  EXPECT_TRUE(listIndexGenerator.loadNext());
74  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_FlavorSpecificParticle }),
75  listIndexGenerator.getCurrentIndices());
76  EXPECT_TRUE(listIndexGenerator.loadNext());
77  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_SelfConjugatedParticle, ParticleList::c_FlavorSpecificParticle }),
78  listIndexGenerator.getCurrentIndices());
79  EXPECT_TRUE(listIndexGenerator.loadNext());
80  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_SelfConjugatedParticle }),
81  listIndexGenerator.getCurrentIndices());
82  EXPECT_FALSE(listIndexGenerator.loadNext());
83  }
84 
85  {
86  ListIndexGenerator listIndexGenerator;
87  listIndexGenerator.init(3);
88  EXPECT_TRUE(listIndexGenerator.loadNext());
89  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_FlavorSpecificParticle, ParticleList::c_FlavorSpecificParticle }),
90  listIndexGenerator.getCurrentIndices());
91  EXPECT_TRUE(listIndexGenerator.loadNext());
92  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_SelfConjugatedParticle, ParticleList::c_FlavorSpecificParticle, ParticleList::c_FlavorSpecificParticle }),
93  listIndexGenerator.getCurrentIndices());
94  EXPECT_TRUE(listIndexGenerator.loadNext());
95  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_SelfConjugatedParticle, ParticleList::c_FlavorSpecificParticle }),
96  listIndexGenerator.getCurrentIndices());
97  EXPECT_TRUE(listIndexGenerator.loadNext());
98  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_SelfConjugatedParticle, ParticleList::c_SelfConjugatedParticle, ParticleList::c_FlavorSpecificParticle }),
99  listIndexGenerator.getCurrentIndices());
100  EXPECT_TRUE(listIndexGenerator.loadNext());
101  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_FlavorSpecificParticle, ParticleList::c_SelfConjugatedParticle }),
102  listIndexGenerator.getCurrentIndices());
103  EXPECT_TRUE(listIndexGenerator.loadNext());
104  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_SelfConjugatedParticle, ParticleList::c_FlavorSpecificParticle, ParticleList::c_SelfConjugatedParticle }),
105  listIndexGenerator.getCurrentIndices());
106  EXPECT_TRUE(listIndexGenerator.loadNext());
107  EXPECT_EQ(std::vector<ParticleList::EParticleType>({ ParticleList::c_FlavorSpecificParticle, ParticleList::c_SelfConjugatedParticle, ParticleList::c_SelfConjugatedParticle}),
108  listIndexGenerator.getCurrentIndices());
109  EXPECT_FALSE(listIndexGenerator.loadNext());
110  }
111 
112  }
113 
114  TEST_F(ParticleCombinerTest, particleIndexGeneratorTest)
115  {
116  {
117  ParticleIndexGenerator particleIndexGenerator;
118  particleIndexGenerator.init(std::vector<unsigned int>({}));
119  EXPECT_FALSE(particleIndexGenerator.loadNext());
120  }
121 
122  {
123  ParticleIndexGenerator particleIndexGenerator;
124  particleIndexGenerator.init(std::vector<unsigned int>({0}));
125  EXPECT_FALSE(particleIndexGenerator.loadNext());
126  particleIndexGenerator.init(std::vector<unsigned int>({3}));
127  EXPECT_TRUE(particleIndexGenerator.loadNext());
128  EXPECT_EQ(std::vector<unsigned int>({0}), particleIndexGenerator.getCurrentIndices());
129  EXPECT_TRUE(particleIndexGenerator.loadNext());
130  EXPECT_EQ(std::vector<unsigned int>({1}), particleIndexGenerator.getCurrentIndices());
131  EXPECT_TRUE(particleIndexGenerator.loadNext());
132  EXPECT_EQ(std::vector<unsigned int>({2}), particleIndexGenerator.getCurrentIndices());
133  EXPECT_FALSE(particleIndexGenerator.loadNext());
134  }
135 
136  {
137  ParticleIndexGenerator particleIndexGenerator;
138  particleIndexGenerator.init(std::vector<unsigned int>({2, 0}));
139  EXPECT_FALSE(particleIndexGenerator.loadNext());
140 
141  particleIndexGenerator.init(std::vector<unsigned int>({1, 3}));
142  EXPECT_TRUE(particleIndexGenerator.loadNext());
143  EXPECT_EQ(std::vector<unsigned int>({0, 0}), particleIndexGenerator.getCurrentIndices());
144  EXPECT_TRUE(particleIndexGenerator.loadNext());
145  EXPECT_EQ(std::vector<unsigned int>({0, 1}), particleIndexGenerator.getCurrentIndices());
146  EXPECT_TRUE(particleIndexGenerator.loadNext());
147  EXPECT_EQ(std::vector<unsigned int>({0, 2}), particleIndexGenerator.getCurrentIndices());
148  EXPECT_FALSE(particleIndexGenerator.loadNext());
149 
150  particleIndexGenerator.init(std::vector<unsigned int>({2, 3}));
151  EXPECT_TRUE(particleIndexGenerator.loadNext());
152  EXPECT_EQ(std::vector<unsigned int>({0, 0}), particleIndexGenerator.getCurrentIndices());
153  EXPECT_TRUE(particleIndexGenerator.loadNext());
154  EXPECT_EQ(std::vector<unsigned int>({1, 0}), particleIndexGenerator.getCurrentIndices());
155  EXPECT_TRUE(particleIndexGenerator.loadNext());
156  EXPECT_EQ(std::vector<unsigned int>({0, 1}), particleIndexGenerator.getCurrentIndices());
157  EXPECT_TRUE(particleIndexGenerator.loadNext());
158  EXPECT_EQ(std::vector<unsigned int>({1, 1}), particleIndexGenerator.getCurrentIndices());
159  EXPECT_TRUE(particleIndexGenerator.loadNext());
160  EXPECT_EQ(std::vector<unsigned int>({0, 2}), particleIndexGenerator.getCurrentIndices());
161  EXPECT_TRUE(particleIndexGenerator.loadNext());
162  EXPECT_EQ(std::vector<unsigned int>({1, 2}), particleIndexGenerator.getCurrentIndices());
163  EXPECT_FALSE(particleIndexGenerator.loadNext());
164  }
165 
166  {
167  ParticleIndexGenerator particleIndexGenerator;
168  particleIndexGenerator.init(std::vector<unsigned int>({2, 4, 3}));
169  EXPECT_TRUE(particleIndexGenerator.loadNext());
170  EXPECT_EQ(std::vector<unsigned int>({0, 0, 0}), particleIndexGenerator.getCurrentIndices());
171  EXPECT_TRUE(particleIndexGenerator.loadNext());
172  EXPECT_EQ(std::vector<unsigned int>({1, 0, 0}), particleIndexGenerator.getCurrentIndices());
173  EXPECT_TRUE(particleIndexGenerator.loadNext());
174  EXPECT_EQ(std::vector<unsigned int>({0, 1, 0}), particleIndexGenerator.getCurrentIndices());
175  EXPECT_TRUE(particleIndexGenerator.loadNext());
176  EXPECT_EQ(std::vector<unsigned int>({1, 1, 0}), particleIndexGenerator.getCurrentIndices());
177  EXPECT_TRUE(particleIndexGenerator.loadNext());
178  EXPECT_EQ(std::vector<unsigned int>({0, 2, 0}), particleIndexGenerator.getCurrentIndices());
179  EXPECT_TRUE(particleIndexGenerator.loadNext());
180  EXPECT_EQ(std::vector<unsigned int>({1, 2, 0}), particleIndexGenerator.getCurrentIndices());
181  EXPECT_TRUE(particleIndexGenerator.loadNext());
182  EXPECT_EQ(std::vector<unsigned int>({0, 3, 0}), particleIndexGenerator.getCurrentIndices());
183  EXPECT_TRUE(particleIndexGenerator.loadNext());
184  EXPECT_EQ(std::vector<unsigned int>({1, 3, 0}), particleIndexGenerator.getCurrentIndices());
185  EXPECT_TRUE(particleIndexGenerator.loadNext());
186  EXPECT_EQ(std::vector<unsigned int>({0, 0, 1}), particleIndexGenerator.getCurrentIndices());
187  EXPECT_TRUE(particleIndexGenerator.loadNext());
188  EXPECT_EQ(std::vector<unsigned int>({1, 0, 1}), particleIndexGenerator.getCurrentIndices());
189  EXPECT_TRUE(particleIndexGenerator.loadNext());
190  EXPECT_EQ(std::vector<unsigned int>({0, 1, 1}), particleIndexGenerator.getCurrentIndices());
191  EXPECT_TRUE(particleIndexGenerator.loadNext());
192  EXPECT_EQ(std::vector<unsigned int>({1, 1, 1}), particleIndexGenerator.getCurrentIndices());
193  EXPECT_TRUE(particleIndexGenerator.loadNext());
194  EXPECT_EQ(std::vector<unsigned int>({0, 2, 1}), particleIndexGenerator.getCurrentIndices());
195  EXPECT_TRUE(particleIndexGenerator.loadNext());
196  EXPECT_EQ(std::vector<unsigned int>({1, 2, 1}), particleIndexGenerator.getCurrentIndices());
197  EXPECT_TRUE(particleIndexGenerator.loadNext());
198  EXPECT_EQ(std::vector<unsigned int>({0, 3, 1}), particleIndexGenerator.getCurrentIndices());
199  EXPECT_TRUE(particleIndexGenerator.loadNext());
200  EXPECT_EQ(std::vector<unsigned int>({1, 3, 1}), particleIndexGenerator.getCurrentIndices());
201  EXPECT_TRUE(particleIndexGenerator.loadNext());
202  EXPECT_EQ(std::vector<unsigned int>({0, 0, 2}), particleIndexGenerator.getCurrentIndices());
203  EXPECT_TRUE(particleIndexGenerator.loadNext());
204  EXPECT_EQ(std::vector<unsigned int>({1, 0, 2}), particleIndexGenerator.getCurrentIndices());
205  EXPECT_TRUE(particleIndexGenerator.loadNext());
206  EXPECT_EQ(std::vector<unsigned int>({0, 1, 2}), particleIndexGenerator.getCurrentIndices());
207  EXPECT_TRUE(particleIndexGenerator.loadNext());
208  EXPECT_EQ(std::vector<unsigned int>({1, 1, 2}), particleIndexGenerator.getCurrentIndices());
209  EXPECT_TRUE(particleIndexGenerator.loadNext());
210  EXPECT_EQ(std::vector<unsigned int>({0, 2, 2}), particleIndexGenerator.getCurrentIndices());
211  EXPECT_TRUE(particleIndexGenerator.loadNext());
212  EXPECT_EQ(std::vector<unsigned int>({1, 2, 2}), particleIndexGenerator.getCurrentIndices());
213  EXPECT_TRUE(particleIndexGenerator.loadNext());
214  EXPECT_EQ(std::vector<unsigned int>({0, 3, 2}), particleIndexGenerator.getCurrentIndices());
215  EXPECT_TRUE(particleIndexGenerator.loadNext());
216  EXPECT_EQ(std::vector<unsigned int>({1, 3, 2}), particleIndexGenerator.getCurrentIndices());
217  EXPECT_FALSE(particleIndexGenerator.loadNext());
218 
219  }
220 
221  }
222 
223 
224  class TestParticleList {
225 
226  typedef std::tuple<Particle::EFlavorType, int, std::set<int>> MockParticle;
227 
228  public:
229  static std::string printable(const MockParticle& m)
230  {
231  std::string s = "MockParticle with PDG " + std::to_string(std::get<1>(m));
232  s += ", type " + std::to_string(std::get<0>(m)) + ", daughter indices: ";
233  for (int idx : std::get<2>(m))
234  s += std::to_string(idx) + " ";
235  return s;
236  }
237 
238  explicit TestParticleList(const std::string& _decayString) : decayString(_decayString)
239  {
240 
241  DecayDescriptor decaydescriptor;
242  decaydescriptor.init(decayString);
243  const DecayDescriptorParticle* mother = decaydescriptor.getMother();
244 
245  pdgCode = mother->getPDGCode();
246  listName = mother->getFullName();
247 
248  isSelfConjugatedParticle = !(Belle2::EvtPDLUtil::hasAntiParticle(pdgCode));
249 
250  StoreObjPtr<ParticleList> list(listName);
252  list.registerInDataStore();
254 
255  if (not list.isValid())
256  list.create();
257  list->initialize(pdgCode, listName);
258 
259  if (not isSelfConjugatedParticle) {
260  antiListName = Belle2::EvtPDLUtil::antiParticleListName(pdgCode, mother->getLabel());
261  StoreObjPtr<ParticleList> antiList(antiListName);
263  antiList.registerInDataStore();
265  if (not antiList.isValid())
266  antiList.create();
267  antiList->initialize(-pdgCode, antiListName);
268  list->bindAntiParticleList(*(antiList));
269  }
270  }
271 
272  void addParticle(unsigned int mdstSource)
273  {
274  StoreObjPtr<ParticleList> list(listName);
275  StoreArray<Particle> particles;
276  Particle* part = particles.appendNew(TLorentzVector(), pdgCode,
277  isSelfConjugatedParticle ? Particle::c_Unflavored : Particle::c_Flavored, Particle::c_MCParticle, mdstSource);
278  list->addParticle(part);
279  }
280 
281  void addAntiParticle(unsigned int mdstSource)
282  {
283  StoreObjPtr<ParticleList> list(antiListName);
284  StoreArray<Particle> particles;
285  Particle* part = particles.appendNew(TLorentzVector(), -pdgCode,
286  isSelfConjugatedParticle ? Particle::c_Unflavored : Particle::c_Flavored, Particle::c_MCParticle, mdstSource);
287  list->addParticle(part);
288  }
289 
290  void addExpectedParticle(Particle::EFlavorType flavourType, int pdg_code, std::vector<int> daughter_indices)
291  {
292  expected_particles.emplace_back(flavourType, pdg_code, std::set<int>(daughter_indices.begin(),
293  daughter_indices.end()));
294  }
295 
296  void addAndCheckParticlesFromGenerator()
297  {
298 
299  StoreObjPtr<ParticleList> list(listName);
300  StoreArray<Particle> particles;
301 
302  ParticleGenerator generator(decayString);
303  generator.init();
304 
305  std::vector<MockParticle> received_particles;
306  std::vector<Particle*> added_particles;
307  for (unsigned int i = 0; i < expected_particles.size(); ++i) {
308  bool next = generator.loadNext();
309  EXPECT_TRUE(next);
310  if (next) {
311  const Particle& particle = generator.getCurrentParticle();
312  Particle* part = particles.appendNew(particle);
313  added_particles.push_back(part);
314  auto daughter_indices = part->getDaughterIndices();
315  received_particles.emplace_back(part->getFlavorType(), part->getPDGCode(), std::set<int>(daughter_indices.begin(),
316  daughter_indices.end()));
317  }
318  }
319  EXPECT_FALSE(generator.loadNext());
320 
321  for (const auto& p : received_particles) {
322  EXPECT_EQ(std::count(expected_particles.begin(), expected_particles.end(), p), 1) << "check failed for " << printable(p);
323  }
324 
325  for (const auto& p : expected_particles) {
326  EXPECT_EQ(std::count(received_particles.begin(), received_particles.end(), p), 1) << "check failed for " << printable(p);
327  auto it = std::find(received_particles.begin(), received_particles.end(), p);
328  if (it != received_particles.end()) {
329  auto index = std::distance(received_particles.begin(), it);
330  list->addParticle(added_particles[index]);
331  }
332  }
333 
334  }
335 
336  int operator*(int index)
337  {
338  StoreObjPtr<ParticleList> list(listName);
339  // Check if index is smaller than FlavorSpecific+SelfConjugatedList
340  // There's not possibility to check only SelfConjugated, so this has to do for the moment
341  EXPECT_LT(index, list->getListSize());
342  return list->getList(ParticleList::c_SelfConjugatedParticle)[index];
343  }
344 
345  int operator+(int index)
346  {
347  StoreObjPtr<ParticleList> list(listName);
348  // Check if index is smaller than FlavorSpecific+SelfConjugatedList
349  // There's not possibility to check only SelfConjugated, so this has to do for the moment
350  EXPECT_LT(index, list->getListSize());
351  return list->getList(ParticleList::c_FlavorSpecificParticle)[index];
352  }
353 
354  int operator-(int index)
355  {
356  StoreObjPtr<ParticleList> list(antiListName);
357  // Check if index is smaller than FlavorSpecific+SelfConjugatedList
358  // There's not possibility to check only SelfConjugated, so this has to do for the moment
359  EXPECT_LT(index, list->getListSize());
360  return list->getList(ParticleList::c_FlavorSpecificParticle)[index];
361  }
362 
363  private:
364  int pdgCode;
365  std::string decayString;
366  std::string listName;
367  std::string antiListName;
368  bool isSelfConjugatedParticle;
369  std::vector<MockParticle> expected_particles;
370 
371  };
372 
373  TEST_F(ParticleCombinerTest, DStar)
374  {
375  TestParticleList K("K+");
376  K.addParticle(1);
377  K.addAntiParticle(2);
378  K.addAntiParticle(3);
379 
380  TestParticleList pi("pi+");
381  pi.addParticle(4);
382  pi.addParticle(5);
383  pi.addAntiParticle(6);
384 
385  {
386  TestParticleList D0("D0 -> K- pi+");
387  D0.addExpectedParticle(Particle::c_Flavored, 421, {K - 0, pi + 0});
388  D0.addExpectedParticle(Particle::c_Flavored, 421, {K - 0, pi + 1});
389  D0.addExpectedParticle(Particle::c_Flavored, 421, {K - 1, pi + 0});
390  D0.addExpectedParticle(Particle::c_Flavored, 421, {K - 1, pi + 1});
391  D0.addExpectedParticle(Particle::c_Flavored, -421, {K + 0, pi - 0});
392  D0.addAndCheckParticlesFromGenerator();
393  }
394 
395  {
396  TestParticleList D0("D0 -> K- K+");
397  D0.addExpectedParticle(Particle::c_Unflavored, 421, {K - 0, K + 0});
398  D0.addExpectedParticle(Particle::c_Unflavored, 421, {K - 1, K + 0});
399  D0.addAndCheckParticlesFromGenerator();
400  }
401 
402  TestParticleList D0("D0");
403 
404  TestParticleList DS("D*+ -> D0 pi+");
405  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 + 0, pi + 1});
406  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 + 1, pi + 0});
407  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 + 2, pi + 1});
408  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 + 3, pi + 0});
409  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 * 0, pi + 0});
410  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 * 0, pi + 1});
411  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 * 1, pi + 0});
412  DS.addExpectedParticle(Particle::c_Flavored, 413, {D0 * 1, pi + 1});
413 
414  DS.addExpectedParticle(Particle::c_Flavored, -413, {D0 * 0, pi - 0});
415  DS.addExpectedParticle(Particle::c_Flavored, -413, {D0 * 1, pi - 0});
416 
417  DS.addAndCheckParticlesFromGenerator();
418 
419  }
420 
421  TEST_F(ParticleCombinerTest, RareBDecay)
422  {
423  TestParticleList e("e+");
424  e.addParticle(1);
425  e.addAntiParticle(2);
426  e.addParticle(3);
427  e.addAntiParticle(4);
428 
429  TestParticleList gamma("gamma");
430  gamma.addParticle(5);
431  gamma.addParticle(6);
432  gamma.addParticle(7);
433 
434  TestParticleList mu("mu+");
435  for (int i = 0; i < 100; ++i) {
436  mu.addParticle(7 + 2 * i + 1);
437  mu.addAntiParticle(7 + 2 * i + 2);
438  }
439 
440  {
441  TestParticleList BP("B+ -> e+");
442  BP.addExpectedParticle(Particle::c_Flavored, 521, {e + 0});
443  BP.addExpectedParticle(Particle::c_Flavored, 521, {e + 1});
444  BP.addExpectedParticle(Particle::c_Flavored, -521, {e - 0});
445  BP.addExpectedParticle(Particle::c_Flavored, -521, {e - 1});
446  BP.addAndCheckParticlesFromGenerator();
447 
448  TestParticleList BP2("B+:eg -> e+ gamma");
449  for (int j = 0; j < 3; ++j) {
450  BP2.addExpectedParticle(Particle::c_Flavored, 521, {e + 0, gamma * j});
451  BP2.addExpectedParticle(Particle::c_Flavored, 521, {e + 1, gamma * j});
452  BP2.addExpectedParticle(Particle::c_Flavored, -521, {e - 0, gamma * j});
453  BP2.addExpectedParticle(Particle::c_Flavored, -521, {e - 1, gamma * j});
454  }
455  BP2.addAndCheckParticlesFromGenerator();
456 
457  // Here we expect "few" combinations, because we combine the same list
458  TestParticleList Y("Upsilon(4S) -> B+ B-");
459  Y.addExpectedParticle(Particle::c_Unflavored, 300553, {BP + 0, BP - 0});
460  Y.addExpectedParticle(Particle::c_Unflavored, 300553, {BP + 0, BP - 1});
461  Y.addExpectedParticle(Particle::c_Unflavored, 300553, {BP + 1, BP - 0});
462  Y.addExpectedParticle(Particle::c_Unflavored, 300553, {BP + 1, BP - 1});
463  Y.addAndCheckParticlesFromGenerator();
464 
465  // Here we expect "more" combinations, because we combine the different list
466  TestParticleList Y2("Upsilon(4S):eg -> B+:eg B-");
467  for (int j = 0; j < 3; ++j) {
468  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 + (0 + 2 * j), BP - 0});
469  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 + (0 + 2 * j), BP - 1});
470  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 + (1 + 2 * j), BP - 0});
471  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 + (1 + 2 * j), BP - 1});
472 
473  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 - (0 + 2 * j), BP + 0});
474  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 - (0 + 2 * j), BP + 1});
475  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 - (1 + 2 * j), BP + 0});
476  Y2.addExpectedParticle(Particle::c_Unflavored, 300553, {BP2 - (1 + 2 * j), BP + 1});
477  }
478  Y2.addAndCheckParticlesFromGenerator();
479 
480  }
481 
482  {
483  TestParticleList BP("B+:mu -> mu+");
484  for (int i = 0; i < 100; ++i) {
485  BP.addExpectedParticle(Particle::c_Flavored, 521, {mu + i});
486  BP.addExpectedParticle(Particle::c_Flavored, -521, {mu - i});
487  }
488  BP.addAndCheckParticlesFromGenerator();
489  }
490  {
491  TestParticleList BP("B+:mg -> mu+ gamma");
492  for (int j = 0; j < 3; ++j) {
493  for (int i = 0; i < 100; ++i) {
494  BP.addExpectedParticle(Particle::c_Flavored, 521, {mu + i, gamma * j});
495  BP.addExpectedParticle(Particle::c_Flavored, -521, {mu - i, gamma * j});
496  }
497  }
498  BP.addAndCheckParticlesFromGenerator();
499  }
500 
501  }
502 
503  TEST_F(ParticleCombinerTest, PsiTo2D0_to2MuPlus2MuMinus)
504  {
505  TestParticleList mu("mu+");
506  mu.addParticle(1);
507  mu.addParticle(2);
508  mu.addAntiParticle(3);
509  mu.addAntiParticle(4);
510 
511  TestParticleList D0("D0 -> mu+ mu-");
512  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 0, mu - 0});
513  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 0, mu - 1});
514  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 1, mu - 1});
515  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 1, mu - 0});
516  D0.addAndCheckParticlesFromGenerator();
517 
518  TestParticleList Psi("psi(3770) -> D0 anti-D0");
519  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0 * 0, D0 * 2});
520  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0 * 1, D0 * 3});
521  Psi.addAndCheckParticlesFromGenerator();
522 
523  TestParticleList PsiMixed("psi(3770):mixeed -> D0 D0");
524  PsiMixed.addExpectedParticle(Particle::c_Unflavored, 30443, {D0 * 0, D0 * 2});
525  PsiMixed.addExpectedParticle(Particle::c_Unflavored, 30443, {D0 * 1, D0 * 3});
526  PsiMixed.addAndCheckParticlesFromGenerator();
527 
528  }
529 
530  TEST_F(ParticleCombinerTest, PsiToD0D0sig)
531  {
532  TestParticleList mu("mu+");
533  mu.addParticle(1);
534  mu.addParticle(2);
535  mu.addAntiParticle(3);
536  mu.addAntiParticle(4);
537 
538  TestParticleList K("K+");
539  K.addParticle(5);
540  K.addAntiParticle(6);
541  TestParticleList pi("pi+");
542  pi.addParticle(7);
543  pi.addAntiParticle(8);
544 
545  TestParticleList D0("D0 -> mu+ mu-");
546  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 0, mu - 0});
547  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 0, mu - 1});
548  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 1, mu - 1});
549  D0.addExpectedParticle(Particle::c_Unflavored, 421, {mu + 1, mu - 0});
550  D0.addAndCheckParticlesFromGenerator();
551 
552  TestParticleList D0sig("D0:sig -> K+ pi-");
553  D0sig.addExpectedParticle(Particle::c_Flavored, 421, {K + 0, pi - 0});
554  D0sig.addExpectedParticle(Particle::c_Flavored, -421, {K - 0, pi + 0});
555  D0sig.addAndCheckParticlesFromGenerator();
556 
557  TestParticleList Psi("psi(3770) -> D0:sig anti-D0");
558  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig + 0, D0 * 0});
559  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig + 0, D0 * 1});
560  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig + 0, D0 * 2});
561  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig + 0, D0 * 3});
562  //also use anti-D0:sig in combination!
563  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig - 0, D0 * 0});
564  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig - 0, D0 * 1});
565  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig - 0, D0 * 2});
566  Psi.addExpectedParticle(Particle::c_Unflavored, 30443, {D0sig - 0, D0 * 3});
567  Psi.addAndCheckParticlesFromGenerator();
568  }
569 
570  TEST_F(ParticleCombinerTest, InputListCollisions)
571  {
572  // create Particle Lists
573  // pi+:all
574  StoreObjPtr<ParticleList> pipAll("pi+:all");
575  StoreObjPtr<ParticleList> pimAll("pi-:all");
577  pipAll.registerInDataStore();
578  pimAll.registerInDataStore();
580 
581  pipAll.create();
582  pimAll.create();
583  pipAll->initialize(211, "pi+:all");
584  pimAll->initialize(-211, "pi-:all");
585  pipAll->bindAntiParticleList(*(pimAll));
586 
587 
588  // pi+:good
589  StoreObjPtr<ParticleList> pipGood("pi+:good");
590  StoreObjPtr<ParticleList> pimGood("pi-:good");
592  pipGood.registerInDataStore();
593  pimGood.registerInDataStore();
595 
596  pipGood.create();
597  pimGood.create();
598  pipGood->initialize(211, "pi+:good");
599  pimGood->initialize(-211, "pi-:good");
600  pipGood->bindAntiParticleList(*(pimGood));
601 
602  // K+:all
603  StoreObjPtr<ParticleList> kpAll("K+:all");
604  StoreObjPtr<ParticleList> kmAll("K-:all");
606  kpAll.registerInDataStore();
607  kmAll.registerInDataStore();
609 
610  kpAll.create();
611  kmAll.create();
612  kpAll->initialize(321, "K+:all");
613  kmAll->initialize(-321, "K-:all");
614  kpAll->bindAntiParticleList(*(kmAll));
615 
616 
617  // K+:good
618  StoreObjPtr<ParticleList> kpGood("K+:good");
619  StoreObjPtr<ParticleList> kmGood("K-:good");
621  kpGood.registerInDataStore();
622  kmGood.registerInDataStore();
624 
625  kpGood.create();
626  kmGood.create();
627  kpGood->initialize(321, "K+:good");
628  kmGood->initialize(-321, "K-:good");
629  kpGood->bindAntiParticleList(*(kmGood));
630 
631  // K+:good2
632  StoreObjPtr<ParticleList> kpGood2("K+:good2");
633  StoreObjPtr<ParticleList> kmGood2("K-:good2");
635  kpGood2.registerInDataStore();
636  kmGood2.registerInDataStore();
638 
639  kpGood2.create();
640  kmGood2.create();
641  kpGood2->initialize(321, "K+:good2");
642  kmGood2->initialize(-321, "K-:good2");
643  kpGood2->bindAntiParticleList(*(kmGood2));
644 
645  // create Particle Lists
646  // gamma:1
647  StoreObjPtr<ParticleList> gamma_1("gamma:1");
648  StoreObjPtr<ParticleList> gamma_2("gamma:2");
650  gamma_1.registerInDataStore();
651  gamma_2.registerInDataStore();
653 
654  gamma_1.create();
655  gamma_2.create();
656  gamma_1->initialize(22, "gamma:1");
657  gamma_2->initialize(22, "gamma:2");
658 
659  // Do Tests
660  ParticleGenerator comb1("D0:1 -> K-:all K+:all");
661  EXPECT_FALSE(comb1.inputListsCollide());
662  EXPECT_FALSE(comb1.inputListsCollide(std::make_pair(0, 1)));
663 
664  ParticleGenerator comb2("D0:2 -> K-:all K+:good");
665  EXPECT_TRUE(comb2.inputListsCollide());
666  EXPECT_TRUE(comb2.inputListsCollide(std::make_pair(0, 1)));
667 
668  ParticleGenerator comb3("D0:3 -> K-:all K+:all pi-:all pi+:all");
669  EXPECT_FALSE(comb3.inputListsCollide());
670  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(0, 1)));
671  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(0, 2)));
672  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(0, 3)));
673  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(1, 2)));
674  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(1, 3)));
675  EXPECT_FALSE(comb3.inputListsCollide(std::make_pair(2, 3)));
676 
677  ParticleGenerator comb4("D0:4 -> K-:all K+:good pi-:good pi+:all");
678  EXPECT_TRUE(comb4.inputListsCollide());
679  EXPECT_TRUE(comb4.inputListsCollide(std::make_pair(0, 1)));
680  EXPECT_FALSE(comb4.inputListsCollide(std::make_pair(0, 2)));
681  EXPECT_FALSE(comb4.inputListsCollide(std::make_pair(0, 3)));
682  EXPECT_FALSE(comb4.inputListsCollide(std::make_pair(1, 2)));
683  EXPECT_FALSE(comb4.inputListsCollide(std::make_pair(1, 3)));
684  EXPECT_TRUE(comb4.inputListsCollide(std::make_pair(2, 3)));
685 
686  ParticleGenerator comb5("D+:1 -> K-:all pi+:all pi+:all");
687  EXPECT_FALSE(comb5.inputListsCollide());
688  EXPECT_FALSE(comb5.inputListsCollide(std::make_pair(0, 1)));
689  EXPECT_FALSE(comb5.inputListsCollide(std::make_pair(0, 2)));
690  EXPECT_FALSE(comb5.inputListsCollide(std::make_pair(1, 2)));
691 
692  ParticleGenerator comb6("D+:2 -> K-:all pi+:good pi+:all");
693  EXPECT_TRUE(comb6.inputListsCollide());
694  EXPECT_FALSE(comb6.inputListsCollide(std::make_pair(0, 1)));
695  EXPECT_FALSE(comb6.inputListsCollide(std::make_pair(0, 2)));
696  EXPECT_TRUE(comb6.inputListsCollide(std::make_pair(1, 2)));
697 
698  ParticleGenerator comb7("D+:3 -> K-:all K+:good K-:good2 pi+:good pi+:all");
699  EXPECT_TRUE(comb7.inputListsCollide());
700  EXPECT_TRUE(comb7.inputListsCollide(std::make_pair(0, 1)));
701  EXPECT_TRUE(comb7.inputListsCollide(std::make_pair(0, 2)));
702  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(0, 3)));
703  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(0, 4)));
704  EXPECT_TRUE(comb7.inputListsCollide(std::make_pair(1, 2)));
705  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(1, 3)));
706  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(1, 4)));
707  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(2, 3)));
708  EXPECT_FALSE(comb7.inputListsCollide(std::make_pair(2, 4)));
709  EXPECT_TRUE(comb7.inputListsCollide(std::make_pair(3, 4)));
710  }
711 
712  TEST_F(ParticleCombinerTest, ECLCombinationsTest)
713  {
727  // create particles
728  StoreArray<Particle> particles;
729  StoreArray<ECLCluster> eclClusters;
730 
731  // mock up the clusters
732  ECLCluster* eclGamma1 = eclClusters. appendNew(ECLCluster());
733  eclGamma1->setConnectedRegionId(1);
734  eclGamma1->setClusterId(1);
736  ECLCluster* eclGamma2 = eclClusters. appendNew(ECLCluster());
737  eclGamma2->setConnectedRegionId(1);
738  eclGamma2->setClusterId(2);
740  ECLCluster* eclGamma3 = eclClusters. appendNew(ECLCluster());
741  eclGamma3->setConnectedRegionId(2);
742  eclGamma3->setClusterId(3);
744  ECLCluster* eclGamma4 = eclClusters. appendNew(ECLCluster());
745  eclGamma4->setConnectedRegionId(3);
746  eclGamma4->setClusterId(4);
748  ECLCluster* eclKL = eclClusters. appendNew(ECLCluster());
749  eclKL->setConnectedRegionId(3);
750  eclKL->setClusterId(5);
752 
753  // particles
754  Particle* g_1 = particles.appendNew(Particle(eclGamma1, Const::photon));
755  Particle* g_2 = particles.appendNew(Particle(eclGamma2, Const::photon));
756  Particle* g_3 = particles.appendNew(Particle(eclGamma3, Const::photon));
757  Particle* g_4 = particles.appendNew(Particle(eclGamma4, Const::photon));
758  Particle* KL = particles.appendNew(Particle(eclKL, Const::Klong));
759 
760  // create Particle Lists
761  StoreObjPtr<ParticleList> gamma("gamma:test");
762  StoreObjPtr<ParticleList> klong("K_L0:test");
763  StoreObjPtr<ParticleList> vpho("vpho:test"); // dummy particle list
764 
765  // datastore initialization
767  gamma.registerInDataStore();
768  klong.registerInDataStore();
769  vpho.registerInDataStore();
771 
772  // create and initialize the lists
773  gamma.create();
774  gamma->initialize(Const::photon.getPDGCode(), "gamma:test");
775  klong.create();
776  klong->initialize(Const::Klong.getPDGCode(), "K_L0:test");
777  vpho.create();
778  vpho->initialize(10022, "vpho:test");
779 
780  gamma->addParticle(g_1);
781  gamma->addParticle(g_2);
782  gamma->addParticle(g_3);
783  gamma->addParticle(g_4);
784  // --
785  klong->addParticle(KL);
786 
787  // the photon (particle array index #3) from CR 3 must not be combined with the
788  // KLong (particle index #4) but the Klong can be combined with all others
789  auto isForbidden = [](std::vector<int> v) -> bool {
790  if (std::find(v.begin(), v.end(), 3) != v.end())
791  if (std::find(v.begin(), v.end(), 4) != v.end())
792  return true;
793  return false;
794  };
795 
796  // check lists
797  EXPECT_EQ(4, gamma->getListSize());
798  EXPECT_EQ(1, klong->getListSize());
799  EXPECT_EQ(0, vpho->getListSize());
800 
801  // now test the combiner functions and functionality
802  ParticleGenerator combiner3("vpho:test -> gamma:test gamma:test K_L0:test");
803  combiner3.init();
804  while (combiner3.loadNext()) {
805  const Particle& particle = combiner3.getCurrentParticle();
806 
807  const std::vector<int>& indices = particle.getDaughterIndices();
808  EXPECT_FALSE(isForbidden(indices)); // check we don't have particles 3 and 4
809 
810  particles.appendNew(particle);
811  int iparticle = particles.getEntries() - 1;
812 
813  vpho->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
814  }
815  // a somewhat redundant check, but there are only 3 acceptable combinations in this test.
816  EXPECT_EQ(3, vpho->getListSize());
817 
818  // similar test but with two bodies
819  ParticleGenerator combiner2("vpho:test -> gamma:test K_L0:test");
820  combiner2.init();
821  while (combiner2.loadNext()) {
822  const Particle& particle = combiner2.getCurrentParticle();
823 
824  const std::vector<int>& indices = particle.getDaughterIndices();
825  EXPECT_FALSE(isForbidden(indices)); // check we don't have particles 3 and 4
826 
827  particles.appendNew(particle);
828  int iparticle = particles.getEntries() - 1;
829 
830  vpho->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
831  }
832  // there are another 3 acceptable combinations
833  EXPECT_EQ(6, vpho->getListSize());
834  }
835 
836  TEST_F(ParticleCombinerTest, FSPCopies)
837  {
838  // create particles
839  StoreArray<Particle> particles;
840  StoreArray<ECLCluster> eclClusters;
841 
842  ECLCluster* eclGamma1 = eclClusters. appendNew(ECLCluster());
843  eclGamma1->setConnectedRegionId(1);
844  eclGamma1->setClusterId(1);
846  ECLCluster* eclGamma2 = eclClusters. appendNew(ECLCluster());
847  eclGamma2->setConnectedRegionId(1);
848  eclGamma2->setClusterId(2);
850  ECLCluster* eclGamma3 = eclClusters. appendNew(ECLCluster());
851  eclGamma3->setConnectedRegionId(2);
852  eclGamma3->setClusterId(1);
854  ECLCluster* eclGamma4 = eclClusters. appendNew(ECLCluster());
855  eclGamma4->setConnectedRegionId(3);
856  eclGamma4->setClusterId(1);
858  ECLCluster* eclKL = eclClusters. appendNew(ECLCluster());
859  eclKL->setConnectedRegionId(3);
860  eclKL->setClusterId(1);
862 
863  Particle* pip_1 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 211, Particle::c_Flavored, Particle::c_Track, 2));
864  Particle* pip_2 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 211, Particle::c_Flavored, Particle::c_Track, 4));
865  Particle* pip_3 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 211, Particle::c_Flavored, Particle::c_Track, 6));
866 
867  Particle* pim_1 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -211, Particle::c_Flavored, Particle::c_Track, 1));
868  Particle* pim_2 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -211, Particle::c_Flavored, Particle::c_Track, 3));
869  Particle* pim_3 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -211, Particle::c_Flavored, Particle::c_Track, 5));
870 
871  Particle* kp_1 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 321, Particle::c_Flavored, Particle::c_Track, 2));
872  Particle* kp_2 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 321, Particle::c_Flavored, Particle::c_Track, 4));
873  Particle* kp_3 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 321, Particle::c_Flavored, Particle::c_Track, 6));
874 
875  Particle* km_1 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -321, Particle::c_Flavored, Particle::c_Track, 1));
876  Particle* km_2 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -321, Particle::c_Flavored, Particle::c_Track, 3));
877  Particle* km_3 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -321, Particle::c_Flavored, Particle::c_Track, 5));
878 
879  //copies of FS particles
880  Particle* pim_1_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -211, Particle::c_Flavored, Particle::c_Track, 1));
881  Particle* pip_1_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 211, Particle::c_Flavored, Particle::c_Track, 2));
882 
883  Particle* km_1_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), -321, Particle::c_Flavored, Particle::c_Track, 1));
884  Particle* kp_1_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 321, Particle::c_Flavored, Particle::c_Track, 2));
885 
886  Particle* g_1 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster, 0));
887  Particle* g_2 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster, 1));
888  Particle* g_3 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster, 2));
889  Particle* g_4 = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster, 3));
890  Particle* KL = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), Const::Klong.getPDGCode(), Particle::c_Unflavored,
891  Particle::c_ECLCluster, 4));
892 
893 
894  Particle* g_1_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster,
895  0));
896  Particle* g_2_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster,
897  1));
898  Particle* g_3_copy = particles.appendNew(Particle(TLorentzVector(0, 0, 0, 0), 22, Particle::c_Unflavored, Particle::c_ECLCluster,
899  2));
900 
901  // create Particle Lists
902  // pi+:all
903  StoreObjPtr<ParticleList> pipAll("pi+:all");
904  StoreObjPtr<ParticleList> pimAll("pi-:all");
906  pipAll.registerInDataStore();
907  pimAll.registerInDataStore();
909 
910  pipAll.create();
911  pimAll.create();
912  pipAll->initialize(211, "pi+:all");
913  pimAll->initialize(-211, "pi-:all");
914  pipAll->bindAntiParticleList(*(pimAll));
915 
916 
917  // pi+:good
918  StoreObjPtr<ParticleList> pipGood("pi+:good");
919  StoreObjPtr<ParticleList> pimGood("pi-:good");
921  pipGood.registerInDataStore();
922  pimGood.registerInDataStore();
924 
925  pipGood.create();
926  pimGood.create();
927  pipGood->initialize(211, "pi+:good");
928  pimGood->initialize(-211, "pi-:good");
929  pipGood->bindAntiParticleList(*(pimGood));
930 
931  // K+:all
932  StoreObjPtr<ParticleList> kpAll("K+:all");
933  StoreObjPtr<ParticleList> kmAll("K-:all");
935  kpAll.registerInDataStore();
936  kmAll.registerInDataStore();
938 
939  kpAll.create();
940  kmAll.create();
941  kpAll->initialize(321, "K+:all");
942  kmAll->initialize(-321, "K-:all");
943  kpAll->bindAntiParticleList(*(kmAll));
944 
945 
946  // K+:good
947  StoreObjPtr<ParticleList> kpGood("K+:good");
948  StoreObjPtr<ParticleList> kmGood("K-:good");
950  kpGood.registerInDataStore();
951  kmGood.registerInDataStore();
953 
954  kpGood.create();
955  kmGood.create();
956  kpGood->initialize(321, "K+:good");
957  kmGood->initialize(-321, "K-:good");
958  kpGood->bindAntiParticleList(*(kmGood));
959 
960  // K+:good2
961  StoreObjPtr<ParticleList> kpGood2("K+:good2");
962  StoreObjPtr<ParticleList> kmGood2("K-:good2");
964  kpGood2.registerInDataStore();
965  kmGood2.registerInDataStore();
967 
968  kpGood2.create();
969  kmGood2.create();
970  kpGood2->initialize(321, "K+:good2");
971  kmGood2->initialize(-321, "K-:good2");
972  kpGood2->bindAntiParticleList(*(kmGood2));
973 
974  // create Particle Lists
975  // gamma:1
976  StoreObjPtr<ParticleList> gamma_1("gamma:1");
977  StoreObjPtr<ParticleList> gamma_2("gamma:2");
979  gamma_1.registerInDataStore();
980  gamma_2.registerInDataStore();
982 
983  gamma_1.create();
984  gamma_2.create();
985  gamma_1->initialize(22, "gamma:1");
986  gamma_2->initialize(22, "gamma:2");
987 
988  // Klong
989  StoreObjPtr<ParticleList> klong_1("K_L0:1");
991  klong_1.registerInDataStore();
993 
994  klong_1.create();
995  klong_1->initialize(Const::Klong.getPDGCode(), "K_L0:1");
996 
997  // add particles to lists
998  pipAll->addParticle(pip_1);
999  pipAll->addParticle(pip_2);
1000  pipAll->addParticle(pip_3);
1001 
1002  pipAll->addParticle(pim_1);
1003  pipAll->addParticle(pim_2);
1004  pipAll->addParticle(pim_3);
1005 
1006  kpAll->addParticle(kp_1);
1007  kpAll->addParticle(kp_2);
1008  kpAll->addParticle(kp_3);
1009 
1010  kpAll->addParticle(km_1);
1011  kpAll->addParticle(km_2);
1012  kpAll->addParticle(km_3);
1013 
1014  pipGood->addParticle(pip_1_copy);
1015  pipGood->addParticle(pim_1_copy);
1016 
1017  kpGood->addParticle(kp_1_copy);
1018  kpGood->addParticle(km_1_copy);
1019 
1020  kpGood2->addParticle(kp_1);
1021  kpGood2->addParticle(km_1);
1022  kpGood2->addParticle(kp_2);
1023  kpGood2->addParticle(km_2);
1024  kpGood2->addParticle(kp_3);
1025  kpGood2->addParticle(km_3);
1026 
1027  gamma_1->addParticle(g_1);
1028  gamma_1->addParticle(g_2);
1029  gamma_1->addParticle(g_3);
1030 
1031  gamma_2->addParticle(g_1_copy);
1032  gamma_2->addParticle(g_2_copy);
1033  gamma_2->addParticle(g_3_copy);
1034  gamma_2->addParticle(g_4);
1035 
1036  klong_1->addParticle(KL);
1037 
1038  // Check consistency
1039  EXPECT_EQ(6, pipAll->getListSize());
1040  EXPECT_EQ(6, pimAll->getListSize());
1041  EXPECT_EQ(6, kpAll->getListSize());
1042  EXPECT_EQ(6, kmAll->getListSize());
1043  EXPECT_EQ(2, pipGood->getListSize());
1044  EXPECT_EQ(2, kpGood->getListSize());
1045  EXPECT_EQ(3, gamma_1->getListSize());
1046  EXPECT_EQ(4, gamma_2->getListSize());
1047  EXPECT_EQ(1, klong_1->getListSize());
1048 
1049  // check if indexToUniqueID map is properly initialized
1050  ParticleGenerator comb7("D+:3 -> K-:all K+:good K-:good2 pi+:good pi+:all gamma:1 gamma:2");
1051  comb7.init();
1052  std::vector<StoreObjPtr<ParticleList>> comb7PLists;
1053  comb7PLists.push_back(kmAll);
1054  comb7PLists.push_back(kpGood);
1055  comb7PLists.push_back(kmGood2);
1056  comb7PLists.push_back(pipGood);
1057  comb7PLists.push_back(pipAll);
1058  comb7PLists.push_back(gamma_1);
1059  comb7PLists.push_back(gamma_2);
1060  // each and every particle within these lists should have unique ID assigned
1061  // unique IDs of copies of particles should be the same
1062  for (unsigned i = 0; i < comb7PLists.size(); i++) {
1063  StoreObjPtr<ParticleList> list_i = comb7PLists[i];
1064  std::vector<int> iAll;
1065  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_FlavorSpecificParticle, false)).begin(),
1066  (list_i->getList(ParticleList::c_FlavorSpecificParticle, false)).end());
1067  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_FlavorSpecificParticle, true)).begin(),
1068  (list_i->getList(ParticleList::c_FlavorSpecificParticle, true)).end());
1069  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_SelfConjugatedParticle)).begin(),
1070  (list_i->getList(ParticleList::c_SelfConjugatedParticle)).end());
1071 
1072  for (unsigned int j = i + 1; j < comb7PLists.size(); j++) {
1073  //B2DEBUG(19, "**** List " << i << " vs " << j );
1074 
1075  StoreObjPtr<ParticleList> list_j = comb7PLists[j];
1076  std::vector<int> jAll;
1077  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_FlavorSpecificParticle, false)).begin(),
1078  (list_j->getList(ParticleList::c_FlavorSpecificParticle, false)).end());
1079  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_FlavorSpecificParticle, true)).begin(),
1080  (list_j->getList(ParticleList::c_FlavorSpecificParticle, true)).end());
1081  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_SelfConjugatedParticle)).begin(),
1082  (list_j->getList(ParticleList::c_SelfConjugatedParticle)).end());
1083 
1084  // loop over all pairs of particles within these two lists
1085  // this is overkill (not optimal), but for testing purposes
1086  // the execution time is not a concern
1087  for (int k : iAll) {
1088  for (int m : jAll) {
1089  const Particle* iP = particles[k];
1090  const Particle* jP = particles[m];
1091 
1092  bool copies = iP->isCopyOf(jP);
1093 
1094  int iID = comb7.getUniqueID(k);
1095  int jID = comb7.getUniqueID(m);
1096 
1097  EXPECT_TRUE(iID > 0);
1098  EXPECT_TRUE(jID > 0);
1099 
1100  //B2DEBUG(19, " - iP/jP = " << iP->getPDGCode() << " (" << iP->getMdstSource() << ") / " << jP->getPDGCode() << " (" << jP->getMdstSource() << ") : " << iID << "/" << jID << " " << copies );
1101 
1102  if (copies)
1103  EXPECT_TRUE(iID == jID);
1104  else
1105  EXPECT_FALSE(iID == jID);
1106  }
1107  }
1108  }
1109  }
1110 
1111  // create D0 lists
1112  StoreObjPtr<ParticleList> D02Kpi_1("D0:kpi1");
1113  StoreObjPtr<ParticleList> anti_D02Kpi_1("anti-D0:kpi1");
1114  StoreObjPtr<ParticleList> D02Kpi_2("D0:kpi2");
1115  StoreObjPtr<ParticleList> anti_D02Kpi_2("anti-D0:kpi2");
1116  StoreObjPtr<ParticleList> D02KK_1("D0:kk1");
1117  StoreObjPtr<ParticleList> anti_D02KK_1("anti-D0:kk1");
1118  StoreObjPtr<ParticleList> D02KK_2("D0:kk2");
1119  StoreObjPtr<ParticleList> anti_D02KK_2("anti-D0:kk2");
1120  StoreObjPtr<ParticleList> D02KK_3("D0:kk3");
1121  StoreObjPtr<ParticleList> anti_D02KK_3("anti-D0:kk3");
1122  StoreObjPtr<ParticleList> D0KLg_1("D0:klg1");
1123  StoreObjPtr<ParticleList> D0KLg_2("D0:klg2");
1124  StoreObjPtr<ParticleList> anti_D0KLg_1("anti-D0:klg1");
1125  StoreObjPtr<ParticleList> anti_D0KLg_2("anti-D0:klg2");
1127  D02Kpi_1.registerInDataStore();
1128  anti_D02Kpi_1.registerInDataStore();
1129  D02Kpi_2.registerInDataStore();
1130  anti_D02Kpi_2.registerInDataStore();
1131  D02KK_1.registerInDataStore();
1132  anti_D02KK_1.registerInDataStore();
1133  D02KK_2.registerInDataStore();
1134  anti_D02KK_2.registerInDataStore();
1135  D02KK_3.registerInDataStore();
1136  anti_D02KK_3.registerInDataStore();
1137  D0KLg_1.registerInDataStore();
1138  D0KLg_2.registerInDataStore();
1139  anti_D0KLg_1.registerInDataStore();
1140  anti_D0KLg_2.registerInDataStore();
1142 
1143  D02Kpi_1.create();
1144  anti_D02Kpi_1.create();
1145  D02Kpi_1->initialize(421, "D0:kpi1");
1146  anti_D02Kpi_1->initialize(-421, "anti-D0:kpi1");
1147  D02Kpi_1->bindAntiParticleList(*(anti_D02Kpi_1));
1148 
1149  D02Kpi_2.create();
1150  anti_D02Kpi_2.create();
1151  D02Kpi_2->initialize(421, "D0:kpi2");
1152  anti_D02Kpi_2->initialize(-421, "anti-D0:kpi2");
1153  D02Kpi_2->bindAntiParticleList(*(anti_D02Kpi_2));
1154 
1155  D02KK_1.create();
1156  anti_D02KK_1.create();
1157  D02KK_1->initialize(421, "D0:kk1");
1158  anti_D02KK_1->initialize(-421, "anti-D0:kk1");
1159  D02KK_1->bindAntiParticleList(*(anti_D02KK_1));
1160 
1161  D02KK_2.create();
1162  anti_D02KK_2.create();
1163  D02KK_2->initialize(421, "D0:kk2");
1164  anti_D02KK_2->initialize(-421, "anti-D0:kk2");
1165  D02KK_2->bindAntiParticleList(*(anti_D02KK_2));
1166 
1167  D02KK_3.create();
1168  anti_D02KK_3.create();
1169  D02KK_3->initialize(421, "D0:kk3");
1170  anti_D02KK_3->initialize(-421, "anti-D0:kk3");
1171  D02KK_3->bindAntiParticleList(*(anti_D02KK_3));
1172 
1173  D0KLg_1.create();
1174  D0KLg_2.create();
1175  anti_D0KLg_1.create();
1176  anti_D0KLg_2.create();
1177  D0KLg_1->initialize(421, "D0:klg1");
1178  D0KLg_2->initialize(421, "D0:klg2");
1179  anti_D0KLg_1->initialize(-421, "anti-D0:klg1");
1180  anti_D0KLg_2->initialize(-421, "anti-D0:klg2");
1181  D0KLg_1->bindAntiParticleList(*(anti_D0KLg_1));
1182  D0KLg_2->bindAntiParticleList(*(anti_D0KLg_2));
1183  // make combinations
1184  ParticleGenerator combiner_D02Kpi_1("D0:kpi1 -> K-:all pi+:all");
1185  combiner_D02Kpi_1.init();
1186  while (combiner_D02Kpi_1.loadNext()) {
1187  const Particle& particle = combiner_D02Kpi_1.getCurrentParticle();
1188 
1189  particles.appendNew(particle);
1190  int iparticle = particles.getEntries() - 1;
1191 
1192  D02Kpi_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1193  }
1194  EXPECT_EQ(18, D02Kpi_1->getListSize());
1195  EXPECT_EQ(9 , D02Kpi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1196  EXPECT_EQ(9 , D02Kpi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1197  EXPECT_EQ(0 , D02Kpi_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1198 
1199  ParticleGenerator combiner_D02Kpi_2("D0:kpi2 -> K-:all pi+:good");
1200  combiner_D02Kpi_2.init();
1201  while (combiner_D02Kpi_2.loadNext()) {
1202  const Particle& particle = combiner_D02Kpi_2.getCurrentParticle();
1203 
1204  particles.appendNew(particle);
1205  int iparticle = particles.getEntries() - 1;
1206 
1207  D02Kpi_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1208  }
1209  EXPECT_EQ(6, D02Kpi_2->getListSize());
1210  EXPECT_EQ(3 , D02Kpi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1211  EXPECT_EQ(3 , D02Kpi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1212  EXPECT_EQ(0 , D02Kpi_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1213 
1214  ParticleGenerator combiner_D02KK_1("D0:kk1 -> K-:all K+:all");
1215  combiner_D02KK_1.init();
1216  while (combiner_D02KK_1.loadNext()) {
1217  const Particle& particle = combiner_D02KK_1.getCurrentParticle();
1218 
1219  particles.appendNew(particle);
1220  int iparticle = particles.getEntries() - 1;
1221 
1222  D02KK_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1223  }
1224  EXPECT_EQ(9, D02KK_1->getListSize());
1225  EXPECT_EQ(0 , D02KK_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1226  EXPECT_EQ(0 , D02KK_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1227  EXPECT_EQ(9 , D02KK_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1228  EXPECT_EQ(9 , D02KK_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1229 
1230  ParticleGenerator combiner_D02KK_2("D0:kk2 -> K-:all K+:good");
1231  combiner_D02KK_2.init();
1232  while (combiner_D02KK_2.loadNext()) {
1233  const Particle& particle = combiner_D02KK_2.getCurrentParticle();
1234 
1235  particles.appendNew(particle);
1236  int iparticle = particles.getEntries() - 1;
1237 
1238  D02KK_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1239  }
1240  EXPECT_EQ(5, D02KK_2->getListSize());
1241  EXPECT_EQ(0 , D02KK_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1242  EXPECT_EQ(0 , D02KK_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1243  EXPECT_EQ(5 , D02KK_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1244  EXPECT_EQ(5 , D02KK_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1245 
1246  ParticleGenerator combiner_D02KK_3("D0:kk3 -> K-:all K+:good2");
1247  combiner_D02KK_3.init();
1248  while (combiner_D02KK_3.loadNext()) {
1249  const Particle& particle = combiner_D02KK_3.getCurrentParticle();
1250 
1251  particles.appendNew(particle);
1252  int iparticle = particles.getEntries() - 1;
1253 
1254  D02KK_3->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1255  }
1256  EXPECT_EQ(9, D02KK_3->getListSize());
1257  EXPECT_EQ(0 , D02KK_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1258  EXPECT_EQ(0 , D02KK_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1259  EXPECT_EQ(9 , D02KK_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1260  EXPECT_EQ(9 , D02KK_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1261 
1262 
1263  ParticleGenerator combiner_D02KLg1("D0:klg1 -> K_L0:1 gamma:1");
1264  ParticleGenerator combiner_D02KLg2("D0:klg2 -> K_L0:1 gamma:2");
1265  combiner_D02KLg1.init();
1266  while (combiner_D02KLg1.loadNext()) {
1267  const Particle& particle = combiner_D02KLg1.getCurrentParticle();
1268 
1269  particles.appendNew(particle);
1270  int iparticle = particles.getEntries() - 1;
1271 
1272  D0KLg_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1273  }
1274  EXPECT_EQ(3, D0KLg_1->getListSize());
1275  EXPECT_EQ(0 , D0KLg_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1276  EXPECT_EQ(0 , D0KLg_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1277  EXPECT_EQ(3 , D0KLg_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1278 
1279  combiner_D02KLg2.init();
1280  while (combiner_D02KLg2.loadNext()) {
1281  const Particle& particle = combiner_D02KLg2.getCurrentParticle();
1282 
1283  particles.appendNew(particle);
1284  int iparticle = particles.getEntries() - 1;
1285 
1286  D0KLg_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1287  }
1288  EXPECT_EQ(3, D0KLg_2->getListSize());
1289  EXPECT_EQ(0 , D0KLg_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1290  EXPECT_EQ(0 , D0KLg_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1291  EXPECT_EQ(3 , D0KLg_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1292 
1293  // more examples
1294  // D+ -> K- pi+ pi+
1295  StoreObjPtr<ParticleList> DpKpipi_1("D+:kpipi1");
1296  StoreObjPtr<ParticleList> DmKpipi_1("D-:kpipi1");
1297  StoreObjPtr<ParticleList> DpKpipi_2("D+:kpipi2");
1298  StoreObjPtr<ParticleList> DmKpipi_2("D-:kpipi2");
1300  DpKpipi_1.registerInDataStore();
1301  DmKpipi_1.registerInDataStore();
1302  DpKpipi_2.registerInDataStore();
1303  DmKpipi_2.registerInDataStore();
1305 
1306  DpKpipi_1.create();
1307  DmKpipi_1.create();
1308  DpKpipi_2.create();
1309  DmKpipi_2.create();
1310 
1311  DpKpipi_1->initialize(411, "D+:kpipi1");
1312  DmKpipi_1->initialize(-411, "D-:kpipi1");
1313  DpKpipi_1->bindAntiParticleList(*(DmKpipi_1));
1314 
1315  DpKpipi_2->initialize(411, "D+:kpipi2");
1316  DmKpipi_2->initialize(-411, "D-:kpipi2");
1317  DpKpipi_2->bindAntiParticleList(*(DmKpipi_2));
1318 
1319  // make combinations
1320  ParticleGenerator combiner_DpKpipi_1("D+:kpipi1 -> K-:all pi+:all pi+:all");
1321  combiner_DpKpipi_1.init();
1322  while (combiner_DpKpipi_1.loadNext()) {
1323  const Particle& particle = combiner_DpKpipi_1.getCurrentParticle();
1324 
1325  particles.appendNew(particle);
1326  int iparticle = particles.getEntries() - 1;
1327 
1328  DpKpipi_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1329  }
1330  EXPECT_EQ(18, DpKpipi_1->getListSize());
1331  EXPECT_EQ(9 , DpKpipi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1332  EXPECT_EQ(9 , DpKpipi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1333  EXPECT_EQ(0 , DpKpipi_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1334 
1335  ParticleGenerator combiner_DpKpipi_2("D+:kpipi1 -> K-:all pi+:all pi+:good");
1336  combiner_DpKpipi_2.init();
1337  while (combiner_DpKpipi_2.loadNext()) {
1338  const Particle& particle = combiner_DpKpipi_2.getCurrentParticle();
1339 
1340  particles.appendNew(particle);
1341  int iparticle = particles.getEntries() - 1;
1342 
1343  DpKpipi_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1344  }
1345  EXPECT_EQ(12, DpKpipi_2->getListSize());
1346  EXPECT_EQ(6 , DpKpipi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1347  EXPECT_EQ(6 , DpKpipi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1348  EXPECT_EQ(0 , DpKpipi_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1349 
1350  // D*+ -> D0 pi+
1351  StoreObjPtr<ParticleList> DSTp_1("D*+:D0kpi1pi");
1352  StoreObjPtr<ParticleList> DSTm_1("D*-:D0kpi1pi");
1353  StoreObjPtr<ParticleList> DSTp_2("D*+:D0kk2pi");
1354  StoreObjPtr<ParticleList> DSTm_2("D*-:D0kk2pi");
1356  DSTp_1.registerInDataStore();
1357  DSTm_1.registerInDataStore();
1358  DSTp_2.registerInDataStore();
1359  DSTm_2.registerInDataStore();
1361 
1362  DSTp_1.create();
1363  DSTm_1.create();
1364  DSTp_2.create();
1365  DSTm_2.create();
1366 
1367  DSTp_1->initialize(413, "D*+:D0kpi1pi");
1368  DSTm_1->initialize(-413, "D*-:D0kpi1pi");
1369  DSTp_1->bindAntiParticleList(*(DSTm_1));
1370 
1371  DSTp_2->initialize(413, "D*+:D0kk2pi");
1372  DSTm_2->initialize(-413, "D*-:D0kk2pi");
1373  DSTp_2->bindAntiParticleList(*(DSTm_2));
1374 
1375  // make combinations
1376  ParticleGenerator combiner_DSTp_1("D*+:D0kpi1pi -> D0:kpi1 pi+:good");
1377  combiner_DSTp_1.init();
1378  while (combiner_DSTp_1.loadNext()) {
1379  const Particle& particle = combiner_DSTp_1.getCurrentParticle();
1380 
1381  particles.appendNew(particle);
1382  int iparticle = particles.getEntries() - 1;
1383 
1384  DSTp_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1385  }
1386  EXPECT_EQ(12, DSTp_1->getListSize());
1387  EXPECT_EQ(6 , DSTp_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1388  EXPECT_EQ(6 , DSTp_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1389  EXPECT_EQ(0 , DSTp_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1390 
1391  ParticleGenerator combiner_DSTp_2("D*+:D0kk2pi -> D0:kk2 pi+:good");
1392  combiner_DSTp_2.init();
1393  while (combiner_DSTp_2.loadNext()) {
1394  const Particle& particle = combiner_DSTp_2.getCurrentParticle();
1395 
1396  particles.appendNew(particle);
1397  int iparticle = particles.getEntries() - 1;
1398 
1399  DSTp_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1400  }
1401  EXPECT_EQ(4, DSTp_2->getListSize());
1402  EXPECT_EQ(2 , DSTp_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1403  EXPECT_EQ(2 , DSTp_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1404  EXPECT_EQ(0 , DSTp_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1405 
1406  // pi0:1 -> gamma:1 gamma:1
1407  StoreObjPtr<ParticleList> pi0_1("pi0:1");
1409  pi0_1.registerInDataStore();
1411 
1412  pi0_1.create();
1413 
1414  pi0_1->initialize(111, "pi0:1");
1415 
1416  // make combinations
1417  ParticleGenerator combiner_pi0_1("pi0:1 -> gamma:1 gamma:1");
1418  combiner_pi0_1.init();
1419  while (combiner_pi0_1.loadNext()) {
1420  const Particle& particle = combiner_pi0_1.getCurrentParticle();
1421 
1422  particles.appendNew(particle);
1423  int iparticle = particles.getEntries() - 1;
1424 
1425  pi0_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1426  }
1427  EXPECT_EQ(3, pi0_1->getListSize());
1428  EXPECT_EQ(0 , pi0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1429  EXPECT_EQ(0 , pi0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1430  EXPECT_EQ(3 , pi0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1431 
1432  // pi0:1copy -> gamma:1 gamma:1
1433  StoreObjPtr<ParticleList> pi0_1copy("pi0:1copy");
1435  pi0_1copy.registerInDataStore();
1437 
1438  pi0_1copy.create();
1439 
1440  pi0_1copy->initialize(111, "pi0:1");
1441 
1442  // make combinations
1443  ParticleGenerator combiner_pi0_1copy("pi0:1copy -> gamma:1 gamma:1");
1444  combiner_pi0_1copy.init();
1445  while (combiner_pi0_1copy.loadNext()) {
1446  const Particle& particle = combiner_pi0_1copy.getCurrentParticle();
1447 
1448  particles.appendNew(particle);
1449  int iparticle = particles.getEntries() - 1;
1450 
1451  pi0_1copy->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1452  }
1453 
1454  // pi0:2 -> gamma:1 gamma:2
1455  StoreObjPtr<ParticleList> pi0_2("pi0:2");
1457  pi0_2.registerInDataStore();
1459 
1460  pi0_2.create();
1461 
1462  pi0_2->initialize(111, "pi0:2");
1463 
1464  // make combinations
1465  ParticleGenerator combiner_pi0_2("pi0:2 -> gamma:1 gamma:2");
1466  combiner_pi0_2.init();
1467  while (combiner_pi0_2.loadNext()) {
1468  const Particle& particle = combiner_pi0_2.getCurrentParticle();
1469 
1470  particles.appendNew(particle);
1471  int iparticle = particles.getEntries() - 1;
1472 
1473  pi0_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1474  }
1475  EXPECT_EQ(6, pi0_2->getListSize());
1476  EXPECT_EQ(0 , pi0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1477  EXPECT_EQ(0 , pi0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1478  EXPECT_EQ(6 , pi0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1479 
1480  // eta:1 -> gamma:2 gamma:2
1481  StoreObjPtr<ParticleList> eta_1("eta:1");
1483  eta_1.registerInDataStore();
1485 
1486  eta_1.create();
1487 
1488  eta_1->initialize(221, "eta:1");
1489 
1490  // make combinations
1491  ParticleGenerator combiner_eta_1("eta:1 -> gamma:2 gamma:2");
1492  combiner_eta_1.init();
1493  while (combiner_eta_1.loadNext()) {
1494  const Particle& particle = combiner_eta_1.getCurrentParticle();
1495 
1496  particles.appendNew(particle);
1497  int iparticle = particles.getEntries() - 1;
1498 
1499  eta_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1500  }
1501  EXPECT_EQ(6, eta_1->getListSize());
1502  EXPECT_EQ(0 , eta_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1503  EXPECT_EQ(0 , eta_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1504  EXPECT_EQ(6 , eta_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1505 
1506  // eta:1copy -> gamma:2 gamma:2
1507  StoreObjPtr<ParticleList> eta_1copy("eta:1copy");
1509  eta_1copy.registerInDataStore();
1511 
1512  eta_1copy.create();
1513 
1514  eta_1copy->initialize(221, "eta:1copy");
1515 
1516  // make combinations
1517  ParticleGenerator combiner_eta_1copy("eta:1copy -> gamma:2 gamma:2");
1518  combiner_eta_1copy.init();
1519  while (combiner_eta_1copy.loadNext()) {
1520  const Particle& particle = combiner_eta_1copy.getCurrentParticle();
1521 
1522  particles.appendNew(particle);
1523  int iparticle = particles.getEntries() - 1;
1524 
1525  eta_1copy->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1526  }
1527 
1528  // B0:1 -> pi0:1 eta:1
1529  StoreObjPtr<ParticleList> B0_1("B0:1");
1530  StoreObjPtr<ParticleList> aB0_1("anti-B0:1");
1532  B0_1.registerInDataStore();
1533  aB0_1.registerInDataStore();
1535 
1536  B0_1.create();
1537  aB0_1.create();
1538 
1539  B0_1->initialize(511, "B0:1");
1540  aB0_1->initialize(-511, "anti-B0:1");
1541  B0_1->bindAntiParticleList(*(aB0_1));
1542 
1543  ParticleGenerator combiner_B0_1("B0:1 -> pi0:1 eta:1");
1544  combiner_B0_1.init();
1545  while (combiner_B0_1.loadNext()) {
1546  const Particle& particle = combiner_B0_1.getCurrentParticle();
1547 
1548  particles.appendNew(particle);
1549  int iparticle = particles.getEntries() - 1;
1550 
1551  B0_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1552  }
1553  EXPECT_EQ(3, B0_1->getListSize());
1554  EXPECT_EQ(0 , B0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1555  EXPECT_EQ(0 , B0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1556  EXPECT_EQ(3 , B0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1557  EXPECT_EQ(3 , aB0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1558 
1559  // B0:2 -> pi0:1 pi0:1copy
1560  StoreObjPtr<ParticleList> B0_2("B0:2");
1561  StoreObjPtr<ParticleList> aB0_2("anti-B0:2");
1563  B0_2.registerInDataStore();
1564  aB0_2.registerInDataStore();
1566 
1567  B0_2.create();
1568  aB0_2.create();
1569 
1570  B0_2->initialize(511, "B0:2");
1571  aB0_2->initialize(-511, "anti-B0:2");
1572  B0_2->bindAntiParticleList(*(aB0_2));
1573 
1574  ParticleGenerator combiner_B0_2("B0:2 -> pi0:1 pi0:1copy");
1575  combiner_B0_2.init();
1576  while (combiner_B0_2.loadNext()) {
1577  const Particle& particle = combiner_B0_2.getCurrentParticle();
1578 
1579  particles.appendNew(particle);
1580  int iparticle = particles.getEntries() - 1;
1581 
1582  B0_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1583  }
1584  EXPECT_EQ(0, B0_2->getListSize());
1585  EXPECT_EQ(0 , B0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1586  EXPECT_EQ(0 , B0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1587  EXPECT_EQ(0 , B0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1588  EXPECT_EQ(0 , aB0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1589 
1590  // B0:3 -> eta:1 eta:1copy
1591  StoreObjPtr<ParticleList> B0_3("B0:3");
1592  StoreObjPtr<ParticleList> aB0_3("anti-B0:3");
1594  B0_3.registerInDataStore();
1595  aB0_3.registerInDataStore();
1597 
1598  B0_3.create();
1599  aB0_3.create();
1600 
1601  B0_3->initialize(511, "B0:3");
1602  aB0_3->initialize(-511, "anti-B0:3");
1603  B0_3->bindAntiParticleList(*(aB0_3));
1604 
1605  ParticleGenerator combiner_B0_3("B0:3 -> eta:1 eta:1copy");
1606  combiner_B0_3.init();
1607  while (combiner_B0_3.loadNext()) {
1608  const Particle& particle = combiner_B0_3.getCurrentParticle();
1609 
1610  particles.appendNew(particle);
1611  int iparticle = particles.getEntries() - 1;
1612 
1613  B0_3->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1614  }
1615  EXPECT_EQ(3, B0_3->getListSize());
1616  EXPECT_EQ(0 , B0_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1617  EXPECT_EQ(0 , B0_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1618  EXPECT_EQ(3 , B0_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1619  EXPECT_EQ(3 , aB0_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1620 
1621  // B0:4 -> pi0:2 eta:1
1622  StoreObjPtr<ParticleList> B0_4("B0:4");
1623  StoreObjPtr<ParticleList> aB0_4("anti-B0:4");
1625  B0_4.registerInDataStore();
1626  aB0_4.registerInDataStore();
1628 
1629  B0_4.create();
1630  aB0_4.create();
1631 
1632  B0_4->initialize(511, "B0:4");
1633  aB0_4->initialize(-511, "anti-B0:4");
1634  B0_4->bindAntiParticleList(*(aB0_4));
1635 
1636  ParticleGenerator combiner_B0_4("B0:4 -> pi0:2 eta:1");
1637  combiner_B0_4.init();
1638  while (combiner_B0_4.loadNext()) {
1639  const Particle& particle = combiner_B0_4.getCurrentParticle();
1640 
1641  particles.appendNew(particle);
1642  int iparticle = particles.getEntries() - 1;
1643 
1644  B0_4->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1645  }
1646  EXPECT_EQ(6, B0_4->getListSize());
1647  EXPECT_EQ(0 , B0_4->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1648  EXPECT_EQ(0 , B0_4->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1649  EXPECT_EQ(6 , B0_4->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1650  EXPECT_EQ(6 , aB0_4->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1651 
1652  }
1653 } // namespace
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:558
static const ParticleType photon
photon particle
Definition: Const.h:554
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:52
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:92
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:84
Represents a particle in the DecayDescriptor.
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 DecayDescriptorParticle * getMother() const
return mother.
ECL cluster data.
Definition: ECLCluster.h:27
void setConnectedRegionId(int crid)
Set connected region id.
Definition: ECLCluster.h:142
void setClusterId(int clusterid)
Set cluster id.
Definition: ECLCluster.h:145
void setHypothesis(EHypothesisBit hypothesis)
Set hypotheses.
Definition: ECLCluster.h:123
@ c_nPhotons
CR is split into n photons (N1)
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
ListIndexGenerator is a generator for all the combinations of the sublists (FlavorSpecificParticle = ...
ParticleGenerator is a generator for all the particles combined from the given ParticleLists.
ParticleIndexGenerator is a generator for all the combinations of the particle indices stored in the ...
Class to store reconstructed particles.
Definition: Particle.h:74
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
Definition: Particle.cc:721
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:92
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:93
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:94
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
void init(const std::vector< unsigned int > &_sizes)
Initialises the generator to produce combinations with the given sizes of each particle list.
const std::vector< unsigned int > & getCurrentIndices() const
Returns theindices of the current loaded combination.
const std::vector< ParticleList::EParticleType > & getCurrentIndices() const
Returns the type of the sublist of the current loaded combination.
void init(unsigned int _numberOfLists)
Initialises the generator to produce the given type of sublist.
bool loadNext()
Loads the next combination.
B2Vector3< DataType > operator*(DataType a, const B2Vector3< DataType > &p)
non-memberfunction Scaling of 3-vectors with a real number
Definition: B2Vector3.h:514
B2Vector3< DataType > operator-(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for substracting a TVector3 from a B2Vector3
Definition: B2Vector3.h:528
B2Vector3< DataType > operator+(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for adding a TVector3 to a B2Vector3
Definition: B2Vector3.h:521
std::string antiParticleListName(int pdgCode, const std::string &label)
Returns the name of the anti-particle ParticleList for particles with given pdg code and with given l...
Definition: EvtPDLUtil.cc:30
bool hasAntiParticle(int pdgCode)
Checks if the particle with given pdg code has an anti-particle or not.
Definition: EvtPDLUtil.cc:12
Abstract base class for different kinds of events.