Belle II Software  release-08-01-10
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->setEditable(true);
1025 
1026  pipAll->addParticle(pip_1);
1027  pipAll->addParticle(pip_2);
1028  pipAll->addParticle(pip_3);
1029 
1030  pipAll->addParticle(pim_1);
1031  pipAll->addParticle(pim_2);
1032  pipAll->addParticle(pim_3);
1033 
1034  pipAll->setEditable(false);
1035 
1036  kpAll->setEditable(true);
1037 
1038  kpAll->addParticle(kp_1);
1039  kpAll->addParticle(kp_2);
1040  kpAll->addParticle(kp_3);
1041 
1042  kpAll->addParticle(km_1);
1043  kpAll->addParticle(km_2);
1044  kpAll->addParticle(km_3);
1045 
1046  kpAll->setEditable(false);
1047 
1048  pipGood->addParticle(pip_1_copy);
1049  pipGood->addParticle(pim_1_copy);
1050 
1051  kpGood->addParticle(kp_1_copy);
1052  kpGood->addParticle(km_1_copy);
1053 
1054  kpGood2->addParticle(kp_1);
1055  kpGood2->addParticle(km_1);
1056  kpGood2->addParticle(kp_2);
1057  kpGood2->addParticle(km_2);
1058  kpGood2->addParticle(kp_3);
1059  kpGood2->addParticle(km_3);
1060 
1061  gamma_1->addParticle(g_1);
1062  gamma_1->addParticle(g_2);
1063  gamma_1->addParticle(g_3);
1064 
1065  gamma_2->addParticle(g_1_copy);
1066  gamma_2->addParticle(g_2_copy);
1067  gamma_2->addParticle(g_3_copy);
1068  gamma_2->addParticle(g_4);
1069 
1070  klong_1->addParticle(KL);
1071 
1072  // Check consistency
1073  EXPECT_EQ(6, pipAll->getListSize());
1074  EXPECT_EQ(6, pimAll->getListSize());
1075  EXPECT_EQ(6, kpAll->getListSize());
1076  EXPECT_EQ(6, kmAll->getListSize());
1077  EXPECT_EQ(2, pipGood->getListSize());
1078  EXPECT_EQ(2, kpGood->getListSize());
1079  EXPECT_EQ(3, gamma_1->getListSize());
1080  EXPECT_EQ(4, gamma_2->getListSize());
1081  EXPECT_EQ(1, klong_1->getListSize());
1082 
1083  // check if indexToUniqueID map is properly initialized
1084  ParticleGenerator comb7("D+:3 -> K-:all K+:good K-:good2 pi+:good pi+:all gamma:1 gamma:2");
1085  comb7.init();
1086  std::vector<StoreObjPtr<ParticleList>> comb7PLists;
1087  comb7PLists.push_back(kmAll);
1088  comb7PLists.push_back(kpGood);
1089  comb7PLists.push_back(kmGood2);
1090  comb7PLists.push_back(pipGood);
1091  comb7PLists.push_back(pipAll);
1092  comb7PLists.push_back(gamma_1);
1093  comb7PLists.push_back(gamma_2);
1094  // each and every particle within these lists should have unique ID assigned
1095  // unique IDs of copies of particles should be the same
1096  for (unsigned i = 0; i < comb7PLists.size(); i++) {
1097  StoreObjPtr<ParticleList> list_i = comb7PLists[i];
1098  std::vector<int> iAll;
1099  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_FlavorSpecificParticle, false)).begin(),
1100  (list_i->getList(ParticleList::c_FlavorSpecificParticle, false)).end());
1101  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_FlavorSpecificParticle, true)).begin(),
1102  (list_i->getList(ParticleList::c_FlavorSpecificParticle, true)).end());
1103  iAll.insert(iAll.begin(), (list_i->getList(ParticleList::c_SelfConjugatedParticle)).begin(),
1104  (list_i->getList(ParticleList::c_SelfConjugatedParticle)).end());
1105 
1106  for (unsigned int j = i + 1; j < comb7PLists.size(); j++) {
1107  //B2DEBUG(19, "**** List " << i << " vs " << j );
1108 
1109  StoreObjPtr<ParticleList> list_j = comb7PLists[j];
1110  std::vector<int> jAll;
1111  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_FlavorSpecificParticle, false)).begin(),
1112  (list_j->getList(ParticleList::c_FlavorSpecificParticle, false)).end());
1113  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_FlavorSpecificParticle, true)).begin(),
1114  (list_j->getList(ParticleList::c_FlavorSpecificParticle, true)).end());
1115  jAll.insert(jAll.begin(), (list_j->getList(ParticleList::c_SelfConjugatedParticle)).begin(),
1116  (list_j->getList(ParticleList::c_SelfConjugatedParticle)).end());
1117 
1118  // loop over all pairs of particles within these two lists
1119  // this is overkill (not optimal), but for testing purposes
1120  // the execution time is not a concern
1121  for (int k : iAll) {
1122  for (int m : jAll) {
1123  const Particle* iP = particles[k];
1124  const Particle* jP = particles[m];
1125 
1126  bool copies = iP->isCopyOf(jP);
1127 
1128  int iID = comb7.getUniqueID(k);
1129  int jID = comb7.getUniqueID(m);
1130 
1131  EXPECT_TRUE(iID > 0);
1132  EXPECT_TRUE(jID > 0);
1133 
1134  //B2DEBUG(19, " - iP/jP = " << iP->getPDGCode() << " (" << iP->getMdstSource() << ") / " << jP->getPDGCode() << " (" << jP->getMdstSource() << ") : " << iID << "/" << jID << " " << copies );
1135 
1136  if (copies)
1137  EXPECT_TRUE(iID == jID);
1138  else
1139  EXPECT_FALSE(iID == jID);
1140  }
1141  }
1142  }
1143  }
1144 
1145  // create D0 lists
1146  StoreObjPtr<ParticleList> D02Kpi_1("D0:kpi1");
1147  StoreObjPtr<ParticleList> anti_D02Kpi_1("anti-D0:kpi1");
1148  StoreObjPtr<ParticleList> D02Kpi_2("D0:kpi2");
1149  StoreObjPtr<ParticleList> anti_D02Kpi_2("anti-D0:kpi2");
1150  StoreObjPtr<ParticleList> D02KK_1("D0:kk1");
1151  StoreObjPtr<ParticleList> anti_D02KK_1("anti-D0:kk1");
1152  StoreObjPtr<ParticleList> D02KK_2("D0:kk2");
1153  StoreObjPtr<ParticleList> anti_D02KK_2("anti-D0:kk2");
1154  StoreObjPtr<ParticleList> D02KK_3("D0:kk3");
1155  StoreObjPtr<ParticleList> anti_D02KK_3("anti-D0:kk3");
1156  StoreObjPtr<ParticleList> D0KLg_1("D0:klg1");
1157  StoreObjPtr<ParticleList> D0KLg_2("D0:klg2");
1158  StoreObjPtr<ParticleList> anti_D0KLg_1("anti-D0:klg1");
1159  StoreObjPtr<ParticleList> anti_D0KLg_2("anti-D0:klg2");
1161  D02Kpi_1.registerInDataStore();
1162  anti_D02Kpi_1.registerInDataStore();
1163  D02Kpi_2.registerInDataStore();
1164  anti_D02Kpi_2.registerInDataStore();
1165  D02KK_1.registerInDataStore();
1166  anti_D02KK_1.registerInDataStore();
1167  D02KK_2.registerInDataStore();
1168  anti_D02KK_2.registerInDataStore();
1169  D02KK_3.registerInDataStore();
1170  anti_D02KK_3.registerInDataStore();
1171  D0KLg_1.registerInDataStore();
1172  D0KLg_2.registerInDataStore();
1173  anti_D0KLg_1.registerInDataStore();
1174  anti_D0KLg_2.registerInDataStore();
1176 
1177  D02Kpi_1.create();
1178  anti_D02Kpi_1.create();
1179  D02Kpi_1->initialize(421, "D0:kpi1");
1180  anti_D02Kpi_1->initialize(-421, "anti-D0:kpi1");
1181  D02Kpi_1->bindAntiParticleList(*(anti_D02Kpi_1));
1182 
1183  D02Kpi_2.create();
1184  anti_D02Kpi_2.create();
1185  D02Kpi_2->initialize(421, "D0:kpi2");
1186  anti_D02Kpi_2->initialize(-421, "anti-D0:kpi2");
1187  D02Kpi_2->bindAntiParticleList(*(anti_D02Kpi_2));
1188 
1189  D02KK_1.create();
1190  anti_D02KK_1.create();
1191  D02KK_1->initialize(421, "D0:kk1");
1192  anti_D02KK_1->initialize(-421, "anti-D0:kk1");
1193  D02KK_1->bindAntiParticleList(*(anti_D02KK_1));
1194 
1195  D02KK_2.create();
1196  anti_D02KK_2.create();
1197  D02KK_2->initialize(421, "D0:kk2");
1198  anti_D02KK_2->initialize(-421, "anti-D0:kk2");
1199  D02KK_2->bindAntiParticleList(*(anti_D02KK_2));
1200 
1201  D02KK_3.create();
1202  anti_D02KK_3.create();
1203  D02KK_3->initialize(421, "D0:kk3");
1204  anti_D02KK_3->initialize(-421, "anti-D0:kk3");
1205  D02KK_3->bindAntiParticleList(*(anti_D02KK_3));
1206 
1207  D0KLg_1.create();
1208  D0KLg_2.create();
1209  anti_D0KLg_1.create();
1210  anti_D0KLg_2.create();
1211  D0KLg_1->initialize(421, "D0:klg1");
1212  D0KLg_2->initialize(421, "D0:klg2");
1213  anti_D0KLg_1->initialize(-421, "anti-D0:klg1");
1214  anti_D0KLg_2->initialize(-421, "anti-D0:klg2");
1215  D0KLg_1->bindAntiParticleList(*(anti_D0KLg_1));
1216  D0KLg_2->bindAntiParticleList(*(anti_D0KLg_2));
1217  // make combinations
1218  ParticleGenerator combiner_D02Kpi_1("D0:kpi1 -> K-:all pi+:all");
1219  combiner_D02Kpi_1.init();
1220  while (combiner_D02Kpi_1.loadNext()) {
1221  const Particle& particle = combiner_D02Kpi_1.getCurrentParticle();
1222 
1223  particles.appendNew(particle);
1224  int iparticle = particles.getEntries() - 1;
1225 
1226  D02Kpi_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1227  }
1228  EXPECT_EQ(18, D02Kpi_1->getListSize());
1229  EXPECT_EQ(9, D02Kpi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1230  EXPECT_EQ(9, D02Kpi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1231  EXPECT_EQ(0, D02Kpi_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1232 
1233  ParticleGenerator combiner_D02Kpi_2("D0:kpi2 -> K-:all pi+:good");
1234  combiner_D02Kpi_2.init();
1235  while (combiner_D02Kpi_2.loadNext()) {
1236  const Particle& particle = combiner_D02Kpi_2.getCurrentParticle();
1237 
1238  particles.appendNew(particle);
1239  int iparticle = particles.getEntries() - 1;
1240 
1241  D02Kpi_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1242  }
1243  EXPECT_EQ(6, D02Kpi_2->getListSize());
1244  EXPECT_EQ(3, D02Kpi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1245  EXPECT_EQ(3, D02Kpi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1246  EXPECT_EQ(0, D02Kpi_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1247 
1248  ParticleGenerator combiner_D02KK_1("D0:kk1 -> K-:all K+:all");
1249  combiner_D02KK_1.init();
1250  while (combiner_D02KK_1.loadNext()) {
1251  const Particle& particle = combiner_D02KK_1.getCurrentParticle();
1252 
1253  particles.appendNew(particle);
1254  int iparticle = particles.getEntries() - 1;
1255 
1256  D02KK_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1257  }
1258  EXPECT_EQ(9, D02KK_1->getListSize());
1259  EXPECT_EQ(0, D02KK_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1260  EXPECT_EQ(0, D02KK_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1261  EXPECT_EQ(9, D02KK_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1262  EXPECT_EQ(9, D02KK_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1263 
1264  ParticleGenerator combiner_D02KK_2("D0:kk2 -> K-:all K+:good");
1265  combiner_D02KK_2.init();
1266  while (combiner_D02KK_2.loadNext()) {
1267  const Particle& particle = combiner_D02KK_2.getCurrentParticle();
1268 
1269  particles.appendNew(particle);
1270  int iparticle = particles.getEntries() - 1;
1271 
1272  D02KK_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1273  }
1274  EXPECT_EQ(5, D02KK_2->getListSize());
1275  EXPECT_EQ(0, D02KK_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1276  EXPECT_EQ(0, D02KK_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1277  EXPECT_EQ(5, D02KK_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1278  EXPECT_EQ(5, D02KK_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1279 
1280  ParticleGenerator combiner_D02KK_3("D0:kk3 -> K-:all K+:good2");
1281  combiner_D02KK_3.init();
1282  while (combiner_D02KK_3.loadNext()) {
1283  const Particle& particle = combiner_D02KK_3.getCurrentParticle();
1284 
1285  particles.appendNew(particle);
1286  int iparticle = particles.getEntries() - 1;
1287 
1288  D02KK_3->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1289  }
1290  EXPECT_EQ(9, D02KK_3->getListSize());
1291  EXPECT_EQ(0, D02KK_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1292  EXPECT_EQ(0, D02KK_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1293  EXPECT_EQ(9, D02KK_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1294  EXPECT_EQ(9, D02KK_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle, true));
1295 
1296 
1297  ParticleGenerator combiner_D02KLg1("D0:klg1 -> K_L0:1 gamma:1");
1298  ParticleGenerator combiner_D02KLg2("D0:klg2 -> K_L0:1 gamma:2");
1299  combiner_D02KLg1.init();
1300  while (combiner_D02KLg1.loadNext()) {
1301  const Particle& particle = combiner_D02KLg1.getCurrentParticle();
1302 
1303  particles.appendNew(particle);
1304  int iparticle = particles.getEntries() - 1;
1305 
1306  D0KLg_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1307  }
1308  EXPECT_EQ(3, D0KLg_1->getListSize());
1309  EXPECT_EQ(0, D0KLg_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1310  EXPECT_EQ(0, D0KLg_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1311  EXPECT_EQ(3, D0KLg_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1312 
1313  combiner_D02KLg2.init();
1314  while (combiner_D02KLg2.loadNext()) {
1315  const Particle& particle = combiner_D02KLg2.getCurrentParticle();
1316 
1317  particles.appendNew(particle);
1318  int iparticle = particles.getEntries() - 1;
1319 
1320  D0KLg_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1321  }
1322  EXPECT_EQ(3, D0KLg_2->getListSize());
1323  EXPECT_EQ(0, D0KLg_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1324  EXPECT_EQ(0, D0KLg_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1325  EXPECT_EQ(3, D0KLg_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1326 
1327  // more examples
1328  // D+ -> K- pi+ pi+
1329  StoreObjPtr<ParticleList> DpKpipi_1("D+:kpipi1");
1330  StoreObjPtr<ParticleList> DmKpipi_1("D-:kpipi1");
1331  StoreObjPtr<ParticleList> DpKpipi_2("D+:kpipi2");
1332  StoreObjPtr<ParticleList> DmKpipi_2("D-:kpipi2");
1334  DpKpipi_1.registerInDataStore();
1335  DmKpipi_1.registerInDataStore();
1336  DpKpipi_2.registerInDataStore();
1337  DmKpipi_2.registerInDataStore();
1339 
1340  DpKpipi_1.create();
1341  DmKpipi_1.create();
1342  DpKpipi_2.create();
1343  DmKpipi_2.create();
1344 
1345  DpKpipi_1->initialize(411, "D+:kpipi1");
1346  DmKpipi_1->initialize(-411, "D-:kpipi1");
1347  DpKpipi_1->bindAntiParticleList(*(DmKpipi_1));
1348 
1349  DpKpipi_2->initialize(411, "D+:kpipi2");
1350  DmKpipi_2->initialize(-411, "D-:kpipi2");
1351  DpKpipi_2->bindAntiParticleList(*(DmKpipi_2));
1352 
1353  // make combinations
1354  ParticleGenerator combiner_DpKpipi_1("D+:kpipi1 -> K-:all pi+:all pi+:all");
1355  combiner_DpKpipi_1.init();
1356  while (combiner_DpKpipi_1.loadNext()) {
1357  const Particle& particle = combiner_DpKpipi_1.getCurrentParticle();
1358 
1359  particles.appendNew(particle);
1360  int iparticle = particles.getEntries() - 1;
1361 
1362  DpKpipi_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1363  }
1364  EXPECT_EQ(18, DpKpipi_1->getListSize());
1365  EXPECT_EQ(9, DpKpipi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1366  EXPECT_EQ(9, DpKpipi_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1367  EXPECT_EQ(0, DpKpipi_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1368 
1369  ParticleGenerator combiner_DpKpipi_2("D+:kpipi1 -> K-:all pi+:all pi+:good");
1370  combiner_DpKpipi_2.init();
1371  while (combiner_DpKpipi_2.loadNext()) {
1372  const Particle& particle = combiner_DpKpipi_2.getCurrentParticle();
1373 
1374  particles.appendNew(particle);
1375  int iparticle = particles.getEntries() - 1;
1376 
1377  DpKpipi_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1378  }
1379  EXPECT_EQ(12, DpKpipi_2->getListSize());
1380  EXPECT_EQ(6, DpKpipi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1381  EXPECT_EQ(6, DpKpipi_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1382  EXPECT_EQ(0, DpKpipi_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1383 
1384  // D*+ -> D0 pi+
1385  StoreObjPtr<ParticleList> DSTp_1("D*+:D0kpi1pi");
1386  StoreObjPtr<ParticleList> DSTm_1("D*-:D0kpi1pi");
1387  StoreObjPtr<ParticleList> DSTp_2("D*+:D0kk2pi");
1388  StoreObjPtr<ParticleList> DSTm_2("D*-:D0kk2pi");
1390  DSTp_1.registerInDataStore();
1391  DSTm_1.registerInDataStore();
1392  DSTp_2.registerInDataStore();
1393  DSTm_2.registerInDataStore();
1395 
1396  DSTp_1.create();
1397  DSTm_1.create();
1398  DSTp_2.create();
1399  DSTm_2.create();
1400 
1401  DSTp_1->initialize(413, "D*+:D0kpi1pi");
1402  DSTm_1->initialize(-413, "D*-:D0kpi1pi");
1403  DSTp_1->bindAntiParticleList(*(DSTm_1));
1404 
1405  DSTp_2->initialize(413, "D*+:D0kk2pi");
1406  DSTm_2->initialize(-413, "D*-:D0kk2pi");
1407  DSTp_2->bindAntiParticleList(*(DSTm_2));
1408 
1409  // make combinations
1410  ParticleGenerator combiner_DSTp_1("D*+:D0kpi1pi -> D0:kpi1 pi+:good");
1411  combiner_DSTp_1.init();
1412  while (combiner_DSTp_1.loadNext()) {
1413  const Particle& particle = combiner_DSTp_1.getCurrentParticle();
1414 
1415  particles.appendNew(particle);
1416  int iparticle = particles.getEntries() - 1;
1417 
1418  DSTp_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1419  }
1420  EXPECT_EQ(12, DSTp_1->getListSize());
1421  EXPECT_EQ(6, DSTp_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1422  EXPECT_EQ(6, DSTp_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1423  EXPECT_EQ(0, DSTp_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1424 
1425  ParticleGenerator combiner_DSTp_2("D*+:D0kk2pi -> D0:kk2 pi+:good");
1426  combiner_DSTp_2.init();
1427  while (combiner_DSTp_2.loadNext()) {
1428  const Particle& particle = combiner_DSTp_2.getCurrentParticle();
1429 
1430  particles.appendNew(particle);
1431  int iparticle = particles.getEntries() - 1;
1432 
1433  DSTp_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1434  }
1435  EXPECT_EQ(4, DSTp_2->getListSize());
1436  EXPECT_EQ(2, DSTp_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1437  EXPECT_EQ(2, DSTp_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1438  EXPECT_EQ(0, DSTp_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1439 
1440  // pi0:1 -> gamma:1 gamma:1
1441  StoreObjPtr<ParticleList> pi0_1("pi0:1");
1443  pi0_1.registerInDataStore();
1445 
1446  pi0_1.create();
1447 
1448  pi0_1->initialize(111, "pi0:1");
1449 
1450  // make combinations
1451  ParticleGenerator combiner_pi0_1("pi0:1 -> gamma:1 gamma:1");
1452  combiner_pi0_1.init();
1453  while (combiner_pi0_1.loadNext()) {
1454  const Particle& particle = combiner_pi0_1.getCurrentParticle();
1455 
1456  particles.appendNew(particle);
1457  int iparticle = particles.getEntries() - 1;
1458 
1459  pi0_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1460  }
1461  EXPECT_EQ(3, pi0_1->getListSize());
1462  EXPECT_EQ(0, pi0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1463  EXPECT_EQ(0, pi0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1464  EXPECT_EQ(3, pi0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1465 
1466  // pi0:1copy -> gamma:1 gamma:1
1467  StoreObjPtr<ParticleList> pi0_1copy("pi0:1copy");
1469  pi0_1copy.registerInDataStore();
1471 
1472  pi0_1copy.create();
1473 
1474  pi0_1copy->initialize(111, "pi0:1");
1475 
1476  // make combinations
1477  ParticleGenerator combiner_pi0_1copy("pi0:1copy -> gamma:1 gamma:1");
1478  combiner_pi0_1copy.init();
1479  while (combiner_pi0_1copy.loadNext()) {
1480  const Particle& particle = combiner_pi0_1copy.getCurrentParticle();
1481 
1482  particles.appendNew(particle);
1483  int iparticle = particles.getEntries() - 1;
1484 
1485  pi0_1copy->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1486  }
1487 
1488  // pi0:2 -> gamma:1 gamma:2
1489  StoreObjPtr<ParticleList> pi0_2("pi0:2");
1491  pi0_2.registerInDataStore();
1493 
1494  pi0_2.create();
1495 
1496  pi0_2->initialize(111, "pi0:2");
1497 
1498  // make combinations
1499  ParticleGenerator combiner_pi0_2("pi0:2 -> gamma:1 gamma:2");
1500  combiner_pi0_2.init();
1501  while (combiner_pi0_2.loadNext()) {
1502  const Particle& particle = combiner_pi0_2.getCurrentParticle();
1503 
1504  particles.appendNew(particle);
1505  int iparticle = particles.getEntries() - 1;
1506 
1507  pi0_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1508  }
1509  EXPECT_EQ(6, pi0_2->getListSize());
1510  EXPECT_EQ(0, pi0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1511  EXPECT_EQ(0, pi0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1512  EXPECT_EQ(6, pi0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1513 
1514  // eta:1 -> gamma:2 gamma:2
1515  StoreObjPtr<ParticleList> eta_1("eta:1");
1517  eta_1.registerInDataStore();
1519 
1520  eta_1.create();
1521 
1522  eta_1->initialize(221, "eta:1");
1523 
1524  // make combinations
1525  ParticleGenerator combiner_eta_1("eta:1 -> gamma:2 gamma:2");
1526  combiner_eta_1.init();
1527  while (combiner_eta_1.loadNext()) {
1528  const Particle& particle = combiner_eta_1.getCurrentParticle();
1529 
1530  particles.appendNew(particle);
1531  int iparticle = particles.getEntries() - 1;
1532 
1533  eta_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1534  }
1535  EXPECT_EQ(6, eta_1->getListSize());
1536  EXPECT_EQ(0, eta_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1537  EXPECT_EQ(0, eta_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1538  EXPECT_EQ(6, eta_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1539 
1540  // eta:1copy -> gamma:2 gamma:2
1541  StoreObjPtr<ParticleList> eta_1copy("eta:1copy");
1543  eta_1copy.registerInDataStore();
1545 
1546  eta_1copy.create();
1547 
1548  eta_1copy->initialize(221, "eta:1copy");
1549 
1550  // make combinations
1551  ParticleGenerator combiner_eta_1copy("eta:1copy -> gamma:2 gamma:2");
1552  combiner_eta_1copy.init();
1553  while (combiner_eta_1copy.loadNext()) {
1554  const Particle& particle = combiner_eta_1copy.getCurrentParticle();
1555 
1556  particles.appendNew(particle);
1557  int iparticle = particles.getEntries() - 1;
1558 
1559  eta_1copy->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1560  }
1561 
1562  // B0:1 -> pi0:1 eta:1
1563  StoreObjPtr<ParticleList> B0_1("B0:1");
1564  StoreObjPtr<ParticleList> aB0_1("anti-B0:1");
1566  B0_1.registerInDataStore();
1567  aB0_1.registerInDataStore();
1569 
1570  B0_1.create();
1571  aB0_1.create();
1572 
1573  B0_1->initialize(511, "B0:1");
1574  aB0_1->initialize(-511, "anti-B0:1");
1575  B0_1->bindAntiParticleList(*(aB0_1));
1576 
1577  ParticleGenerator combiner_B0_1("B0:1 -> pi0:1 eta:1");
1578  combiner_B0_1.init();
1579  while (combiner_B0_1.loadNext()) {
1580  const Particle& particle = combiner_B0_1.getCurrentParticle();
1581 
1582  particles.appendNew(particle);
1583  int iparticle = particles.getEntries() - 1;
1584 
1585  B0_1->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1586  }
1587  EXPECT_EQ(3, B0_1->getListSize());
1588  EXPECT_EQ(0, B0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1589  EXPECT_EQ(0, B0_1->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1590  EXPECT_EQ(3, B0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1591  EXPECT_EQ(3, aB0_1->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1592 
1593  // B0:2 -> pi0:1 pi0:1copy
1594  StoreObjPtr<ParticleList> B0_2("B0:2");
1595  StoreObjPtr<ParticleList> aB0_2("anti-B0:2");
1597  B0_2.registerInDataStore();
1598  aB0_2.registerInDataStore();
1600 
1601  B0_2.create();
1602  aB0_2.create();
1603 
1604  B0_2->initialize(511, "B0:2");
1605  aB0_2->initialize(-511, "anti-B0:2");
1606  B0_2->bindAntiParticleList(*(aB0_2));
1607 
1608  ParticleGenerator combiner_B0_2("B0:2 -> pi0:1 pi0:1copy");
1609  combiner_B0_2.init();
1610  while (combiner_B0_2.loadNext()) {
1611  const Particle& particle = combiner_B0_2.getCurrentParticle();
1612 
1613  particles.appendNew(particle);
1614  int iparticle = particles.getEntries() - 1;
1615 
1616  B0_2->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1617  }
1618  EXPECT_EQ(0, B0_2->getListSize());
1619  EXPECT_EQ(0, B0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1620  EXPECT_EQ(0, B0_2->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1621  EXPECT_EQ(0, B0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1622  EXPECT_EQ(0, aB0_2->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1623 
1624  // B0:3 -> eta:1 eta:1copy
1625  StoreObjPtr<ParticleList> B0_3("B0:3");
1626  StoreObjPtr<ParticleList> aB0_3("anti-B0:3");
1628  B0_3.registerInDataStore();
1629  aB0_3.registerInDataStore();
1631 
1632  B0_3.create();
1633  aB0_3.create();
1634 
1635  B0_3->initialize(511, "B0:3");
1636  aB0_3->initialize(-511, "anti-B0:3");
1637  B0_3->bindAntiParticleList(*(aB0_3));
1638 
1639  ParticleGenerator combiner_B0_3("B0:3 -> eta:1 eta:1copy");
1640  combiner_B0_3.init();
1641  while (combiner_B0_3.loadNext()) {
1642  const Particle& particle = combiner_B0_3.getCurrentParticle();
1643 
1644  particles.appendNew(particle);
1645  int iparticle = particles.getEntries() - 1;
1646 
1647  B0_3->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1648  }
1649  EXPECT_EQ(3, B0_3->getListSize());
1650  EXPECT_EQ(0, B0_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1651  EXPECT_EQ(0, B0_3->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1652  EXPECT_EQ(3, B0_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1653  EXPECT_EQ(3, aB0_3->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1654 
1655  // B0:4 -> pi0:2 eta:1
1656  StoreObjPtr<ParticleList> B0_4("B0:4");
1657  StoreObjPtr<ParticleList> aB0_4("anti-B0:4");
1659  B0_4.registerInDataStore();
1660  aB0_4.registerInDataStore();
1662 
1663  B0_4.create();
1664  aB0_4.create();
1665 
1666  B0_4->initialize(511, "B0:4");
1667  aB0_4->initialize(-511, "anti-B0:4");
1668  B0_4->bindAntiParticleList(*(aB0_4));
1669 
1670  ParticleGenerator combiner_B0_4("B0:4 -> pi0:2 eta:1");
1671  combiner_B0_4.init();
1672  while (combiner_B0_4.loadNext()) {
1673  const Particle& particle = combiner_B0_4.getCurrentParticle();
1674 
1675  particles.appendNew(particle);
1676  int iparticle = particles.getEntries() - 1;
1677 
1678  B0_4->addParticle(iparticle, particle.getPDGCode(), particle.getFlavorType());
1679  }
1680  EXPECT_EQ(6, B0_4->getListSize());
1681  EXPECT_EQ(0, B0_4->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle));
1682  EXPECT_EQ(0, B0_4->getNParticlesOfType(ParticleList::c_FlavorSpecificParticle, true));
1683  EXPECT_EQ(6, B0_4->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1684  EXPECT_EQ(6, aB0_4->getNParticlesOfType(ParticleList::c_SelfConjugatedParticle));
1685 
1686  }
1687 } // namespace
#define K(x)
macro autogenerated by FFTW
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:669
static const ParticleType photon
photon particle
Definition: Const.h:664
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:86
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:75
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
Definition: Particle.cc:756
EFlavorType
describes flavor type, see getFlavorType().
Definition: Particle.h:94
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
Definition: Particle.h:95
@ c_Flavored
Is either particle or antiparticle.
Definition: Particle.h:96
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:96
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:537
B2Vector3< DataType > operator-(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for substracting a TVector3 from a B2Vector3
Definition: B2Vector3.h:551
B2Vector3< DataType > operator+(const TVector3 &a, const B2Vector3< DataType > &b)
non-memberfunction for adding a TVector3 to a B2Vector3
Definition: B2Vector3.h:544
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.