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