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