Belle II Software development
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;
31using namespace Belle2;
32
33namespace {
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);
737 eclGamma1->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
738 ECLCluster* eclGamma2 = eclClusters. appendNew(ECLCluster());
739 eclGamma2->setConnectedRegionId(1);
740 eclGamma2->setClusterId(2);
741 eclGamma2->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
742 ECLCluster* eclGamma3 = eclClusters. appendNew(ECLCluster());
743 eclGamma3->setConnectedRegionId(2);
744 eclGamma3->setClusterId(3);
745 eclGamma3->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
746 ECLCluster* eclGamma4 = eclClusters. appendNew(ECLCluster());
747 eclGamma4->setConnectedRegionId(3);
748 eclGamma4->setClusterId(4);
749 eclGamma4->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
750 ECLCluster* eclKL = eclClusters. appendNew(ECLCluster());
751 eclKL->setConnectedRegionId(3);
752 eclKL->setClusterId(5);
753 eclKL->setHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron);
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);
847 eclGamma1->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
848 ECLCluster* eclGamma2 = eclClusters. appendNew(ECLCluster());
849 eclGamma2->setConnectedRegionId(1);
850 eclGamma2->setClusterId(2);
851 eclGamma2->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
852 ECLCluster* eclGamma3 = eclClusters. appendNew(ECLCluster());
853 eclGamma3->setConnectedRegionId(2);
854 eclGamma3->setClusterId(1);
855 eclGamma3->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
856 ECLCluster* eclGamma4 = eclClusters. appendNew(ECLCluster());
857 eclGamma4->setConnectedRegionId(3);
858 eclGamma4->setClusterId(1);
859 eclGamma4->setHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
860 ECLCluster* eclKL = eclClusters. appendNew(ECLCluster());
861 eclKL->setConnectedRegionId(3);
862 eclKL->setClusterId(1);
863 eclKL->setHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron);
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:678
static const ParticleType photon
photon particle
Definition: Const.h:673
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.
int getPDGCode() const
Return PDG code.
std::string getFullName() const
returns the full name of the particle full_name = name:label
std::string getLabel() const
The label of this particle, "default" returned, when no label set.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
ECL cluster data.
Definition: ECLCluster.h:27
void setConnectedRegionId(int crid)
Set connected region id.
Definition: ECLCluster.h:142
void setClusterId(int clusterid)
Set cluster id.
Definition: ECLCluster.h:145
void setHypothesis(EHypothesisBit hypothesis)
Set hypotheses.
Definition: ECLCluster.h:123
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
const std::vector< int > & getDaughterIndices() const
Returns a vector of store array indices of daughter particles.
Definition: Particle.h:736
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
Definition: Particle.cc:752
EFlavorType getFlavorType() const
Returns flavor type of the decay (for FS particles: flavor type of particle)
Definition: Particle.h:469
int getPDGCode(void) const
Returns PDG code.
Definition: Particle.h:454
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
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.
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.