Belle II Software development
purityCalculatorTools.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
9#include <gtest/gtest.h>
10
11#include <tracking/spacePointCreation/PurityCalculatorTools.h>
12
13#include <algorithm>
14
15#include <framework/logging/Logger.h> // for B2INFO, etc...
16#include <vxd/geometry/SensorInfoBase.h>
17#include <framework/datastore/StoreArray.h>
18#include <framework/datastore/RelationVector.h>
19#include <mdst/dataobjects/MCParticle.h>
20#include <pxd/dataobjects/PXDTrueHit.h>
21#include <pxd/dataobjects/PXDCluster.h>
22#include <svd/dataobjects/SVDTrueHit.h>
23#include <svd/dataobjects/SVDCluster.h>
24#include <tracking/spacePointCreation/SpacePoint.h>
25
26// SpacePointTrackCand is at the moment the only container that gets tested
27#include <tracking/spacePointCreation/SpacePointTrackCand.h>
28
29using namespace std;
30using namespace Belle2;
31
32namespace PurityCalcTests {
33
38 template<typename TrueHitType>
39 TrueHitType createTrueHit(VxdID sensorId, float u = 0.1, float v = 0.2)
40 {
41 float position[3] = { u, v, 0. };
42 float momentum[3] = { 0.1, 0.1, 0.1 };
43
44 return TrueHitType(sensorId, position, position, position, momentum, momentum, momentum, 0.2, 0.1);
45 }
46
51 MCParticle createMCParticle()
52 {
53 return MCParticle();
54 }
55
59 VXD::SensorInfoBase createSensorInfo(VxdID sensorID, VXD::SensorInfoBase::SensorType type)
60 {
61 VXD::SensorInfoBase sensorInfoBase(type, sensorID, 2.3, 4.2, 0.3, 2, 4, -1);
62
63 TGeoRotation r1;
64 r1.SetAngles(45, 20, 30); // rotation defined by Euler angles
65 TGeoTranslation t1(0., 0., -0.);
66 TGeoCombiTrans c1(t1, r1);
67 TGeoHMatrix transform = c1;
68 sensorInfoBase.setTransformation(transform);
69
70 return sensorInfoBase;
71 }
72
78 SpacePoint createSpacePoint(VxdID sensorId, bool pxd, short nClusters = 0, double u = 0.1, double v = 0.2)
79 {
80 if (pxd) {
81 VXD::SensorInfoBase sensorInfo = createSensorInfo(sensorId, VXD::SensorInfoBase::PXD);
82 PXDCluster pxdCluster(sensorId, u, v, 0.1, 0.1, 0, 0, 1, 1, 1, 1, 1, 1);
83 return SpacePoint(&pxdCluster, &sensorInfo);
84 } else {
85 VXD::SensorInfoBase sensorInfo = createSensorInfo(sensorId, VXD::SensorInfoBase::SVD);
86 vector<const SVDCluster*> clusters;
87
88 if (!nClusters) { // if 0 set both
89 clusters.push_back(new SVDCluster(sensorId, true, u, 1.0, 0.1, 0.001, 1, 1, 1, 1.0));
90 clusters.push_back(new SVDCluster(sensorId, false, v, 1.0, 0.1, 0.001, 1, 1, 1, 1.0));
91 } else { // set only one coordinate
92 bool setU = (nClusters > 0);
93 clusters.push_back(new SVDCluster(sensorId, setU, u, 1.0, 0.1, 0.001, 1, 1, 1, 1.0)); // position doesn't actually matter!
94 }
95 return SpacePoint(clusters, &sensorInfo);
96 }
97 return SpacePoint(); // empty SP as default but should not happen!
98 }
99
104 struct compFirst {
105 explicit compFirst(int j) : i(j) { }
106 bool operator()(const pair<int, short>& p)
107 {
108 return p.first == i;
109 }
110 private:
111 int i;
112 };
113
117 struct compMCId {
118 explicit compMCId(int j) : i(j) { }
119 bool operator()(const MCVXDPurityInfo& info)
120 {
121 return info.getParticleID() == i;
122 }
123 private:
124 int i;
125 };
126
130 class PurityCalculatorToolsTest : public ::testing::Test {
131 protected:
132
137 virtual void SetUp()
138 {
140
141 // register everything necessary in the datastore
146
147 // register the needed relations
152
154
155 // populate datastore
156 MCParticle* mcPart1 = m_mcParticles.appendNew(createMCParticle());
157 MCParticle* mcPart2 = m_mcParticles.appendNew(createMCParticle());
158
159 // add a PXD (ideal case: one TrueHit -> one MCParticle)
160 VxdID pxdId(1, 1, 1);
161 PXDTrueHit* pTrueHit = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
162 mcPart1->addRelationTo(pTrueHit);
163 SpacePoint* spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
164 spacePoint->addRelationTo(pTrueHit, 1); // PXD has only one Cluster
165 m_assignedClusters.push_back(1);
166
167 // add a PXD (non-ideal case: no TrueHit)
168 m_spacePoints.appendNew(createSpacePoint(pxdId, true));
169 m_assignedClusters.push_back(1);
170
171 // add a PXD (non-ideal case: more than one (i.e. two for the test) TrueHits -> 2 MCParticles)
172 PXDTrueHit* pTrueHit2 = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
173 mcPart2->addRelationTo(pTrueHit2);
174 spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
175 spacePoint->addRelationTo(pTrueHit, 1);
176 spacePoint->addRelationTo(pTrueHit2, 1);
177 m_assignedClusters.push_back(1);
178
179 // add a PXD (non-ideal case: more than one (i.e. two for the test) TrueHits -> 1 MCParticles)
180 // -> both TrueHits are related with the same MCParticle (probably a very rare corner case, but this is what testing is for)
181 PXDTrueHit* pTrueHit3 = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
182 mcPart2->addRelationTo(pTrueHit3);
183 spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
184 spacePoint->addRelationTo(pTrueHit3, 1);
185 spacePoint->addRelationTo(pTrueHit2, 1);
186 m_assignedClusters.push_back(1);
187
188 // NOTE: SVD only testing two Clusters SpacePoints since single Clusters are essentially the same as PXDs!
189 // SVD: first set up some SVDTrueHits with differing relations to MCParticles
190 VxdID svdId(3, 1, 1);
191 SVDTrueHit* sTH2MC1 = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to mcParticle1
192 mcPart1->addRelationTo(sTH2MC1);
193 SVDTrueHit* sTH2MC2 = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to mcParticle2
194 mcPart2->addRelationTo(sTH2MC2);
195 SVDTrueHit* sTH2None = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to no MCParticle
196
197 // add a SVD (ideal case: two Clusters -> 1 TrueHit -> 1 MCParticle)
198 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
199 spacePoint->addRelationTo(sTH2MC1, 2); // both Clusters to one TrueHit
200 m_assignedClusters.push_back(2);
201
202 // add a SVD (non-ideal case: twoClusters -> 2 TrueHits -> 2 MCParticles)
203 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
204 m_assignedClusters.push_back(2);
205 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
206 spacePoint->addRelationTo(sTH2MC2, 21); // V-Cluster
207
208 // add a SVD (non-ideal case: no related TrueHits)
209 m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
210 m_assignedClusters.push_back(2);
211
212 // add a SVD (non-ideal case: twoClusters -> 2 TrueHits -> 2 MCParticles with different numbers of related Clusters
213 // for TrueHits)
214 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
215 m_assignedClusters.push_back(2);
216 spacePoint->addRelationTo(sTH2MC1, 2); // both Clusters related to this TrueHit
217 spacePoint->addRelationTo(sTH2MC2, 11); // only one Cluster related to TrueHit (U-Cluster in this case)
218
219 // add a SVD (non-ideal case: only one Cluster with relation to ONE TrueHit: V-Cluster related)
220 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
221 m_assignedClusters.push_back(2);
222 spacePoint->addRelationTo(sTH2MC1, 21); // one V-Cluster with relation to TrueHit with relation to MCParticle
223
224 // add a SVD (non-ideal case: only one Cluster with relation to ONE TrueHit: U-Cluster related)
225 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
226 m_assignedClusters.push_back(2);
227 spacePoint->addRelationTo(sTH2MC2, 11); // one U-Cluster with relation to TrueHit with relation to MCParticle
228
229 // add a SVD (non-ideal case: only one TrueHit has a relation to a MCParticle)
230 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
231 m_assignedClusters.push_back(2);
232 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
233 spacePoint->addRelationTo(sTH2None, 21); // V-Cluster without relation to MCParticle
234
235 // add a SVD (non-ideal case: one Cluster has relations to more than one TrueHit, while the other has not)
236 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
237 m_assignedClusters.push_back(2);
238 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
239 spacePoint->addRelationTo(sTH2MC2, 11); // U-Cluster, no relation for V-Cluster
240
241 // add singleCluster SpacePoints for testing the increaseCounterMethod. Do not need any relations!
242 // NOTE: these shall not be included in the testing of the other methods!
243 m_spacePoints.appendNew(createSpacePoint(svdId, false, -1)); // add V-Cluster set only
244 m_assignedClusters.push_back(1);
245 m_spacePoints.appendNew(createSpacePoint(svdId, false, 1)); // add U-Cluster set only
246 m_assignedClusters.push_back(1);
247 }
248
250 virtual void TearDown() { DataStore::Instance().reset(); }
251
252 // members to be used in the tests
258 std::vector<short> m_assignedClusters;
259 };
260
264 TEST_F(PurityCalculatorToolsTest, testSetUp)
265 {
266 B2INFO("Contents of DataStore after SetUp: pxdTrueHits: " << m_pxdTrueHits.getEntries() <<
267 " svdTrueHits: " << m_svdTrueHits.getEntries() << " mcParticles: " << m_mcParticles.getEntries() <<
268 " spacePoints: " << m_spacePoints.getEntries());
269
270 // test if StoreArray has all the entries that should be there
271 EXPECT_EQ(m_pxdTrueHits.getEntries(), 3);
272 EXPECT_EQ(m_svdTrueHits.getEntries(), 3);
273 EXPECT_EQ(m_spacePoints.getEntries(), 14);
274 EXPECT_EQ(m_mcParticles.getEntries(), 2);
275
276 // test if the SpacePoints have the expected number of assigned Clusters
277 for (int i = 0; i < m_spacePoints.getEntries(); ++i) {
278 EXPECT_EQ(m_spacePoints[i]->getNClustersAssigned(), m_assignedClusters[i]);
279 }
280
281 // test if the relations are set according to the set-up (mainly testing if the methods for setting up are working properly)
282 // NOTE: only sampling here, not testing all SpacePoints! (but still tried to cover all important relations (i.e. TH -> MCPart))
283 RelationVector<PXDTrueHit> pxdTrueHits = m_spacePoints[0]->getRelationsTo<PXDTrueHit>("ALL");
284 ASSERT_EQ(pxdTrueHits.size(), 1);
285 EXPECT_EQ(pxdTrueHits[0]->getArrayIndex(), 0);
286 EXPECT_EQ(pxdTrueHits.weight(0), 1);
287
288 pxdTrueHits = m_spacePoints[2]->getRelationsTo<PXDTrueHit>("ALL");
289 ASSERT_EQ(pxdTrueHits.size(), 2);
290 EXPECT_EQ(pxdTrueHits[0]->getArrayIndex(), 0);
291 EXPECT_EQ(pxdTrueHits[0]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 0);
292 EXPECT_EQ(pxdTrueHits.weight(0), 1);
293 EXPECT_EQ(pxdTrueHits[1]->getArrayIndex(), 1);
294 EXPECT_EQ(pxdTrueHits[1]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 1);
295 EXPECT_EQ(pxdTrueHits.weight(1), 1);
296
297 RelationVector<SVDTrueHit> svdTrueHits = m_spacePoints[4]->getRelationsTo<SVDTrueHit>("ALL");
298 ASSERT_EQ(svdTrueHits.size(), 1);
299 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0);
300 EXPECT_EQ(svdTrueHits[0]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 0);
301 EXPECT_EQ(svdTrueHits.weight(0), 2);
302
303 svdTrueHits = m_spacePoints[5]->getRelationsTo<SVDTrueHit>("ALL");
304 ASSERT_EQ(svdTrueHits.size(), 2);
305 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0); // MCParticle relation already tested!
306 EXPECT_EQ(svdTrueHits.weight(0), 11);
307 EXPECT_EQ(svdTrueHits[1]->getArrayIndex(), 1);
308 EXPECT_EQ(svdTrueHits.weight(1), 21);
309 EXPECT_EQ(svdTrueHits[1]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 1);
310
311 svdTrueHits = m_spacePoints[6]->getRelationsTo<SVDTrueHit>("ALL");
312 ASSERT_EQ(svdTrueHits.size(), 0);
313
314 svdTrueHits = m_spacePoints[7]->getRelationsTo<SVDTrueHit>("ALL");
315 ASSERT_EQ(svdTrueHits.size(), 2);
316 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0); // MCParticle relation already tested!
317 EXPECT_EQ(svdTrueHits.weight(0), 2);
318 EXPECT_EQ(svdTrueHits.weight(1), 11); // only related to U-Cluster
319 EXPECT_EQ(svdTrueHits[1]->getArrayIndex(), 1); // MCParticle relation already tested!
320 }
321
325 TEST_F(PurityCalculatorToolsTest, testFindWeightInVector)
326 {
327 std::vector<std::pair<int, double> > vec;
328 vec.push_back(std::make_pair(1, 0));
329 vec.push_back(std::make_pair(1, 1.1));
330 vec.push_back(std::make_pair(1, 2));
331 vec.push_back(std::make_pair(1, 11));
332 vec.push_back(std::make_pair(1, 21));
333 vec.push_back(std::make_pair(1, 11));
334 vec.push_back(std::make_pair(1, 2.5));
335
336 EXPECT_TRUE(findWeightInVector(vec, 1e-4));
337 EXPECT_TRUE(findWeightInVector(vec, 1.1));
338 EXPECT_FALSE(findWeightInVector(vec, 11.1));
339 EXPECT_FALSE(findWeightInVector(vec, 2.501));
340 }
341
345 TEST_F(PurityCalculatorToolsTest, testGetAccessorsFromWeight)
346 {
347 // empty returns first
348 std::vector<size_t> accs = getAccessorsFromWeight(0);
349 EXPECT_TRUE(accs.empty());
350 accs = getAccessorsFromWeight(30);
351 EXPECT_TRUE(accs.empty());
352
353 // cases that occur in "real life"
354 accs = getAccessorsFromWeight(1);
355 EXPECT_EQ(accs[0], 0); // -> PXD
356 EXPECT_EQ(accs.size(), 1);
357 accs = getAccessorsFromWeight(2);
358 EXPECT_EQ(accs.size(), 2);
359 EXPECT_EQ(accs[0], 1);
360 EXPECT_EQ(accs[1], 2);
361 accs = getAccessorsFromWeight(11);
362 EXPECT_EQ(accs[0], 1); // -> SVD U Cluster
363 EXPECT_EQ(accs.size(), 1);
364 accs = getAccessorsFromWeight(21);
365 EXPECT_EQ(accs[0], 2);
366 EXPECT_EQ(accs.size(), 1);
367 }
368
372 TEST_F(PurityCalculatorToolsTest, testIncreaseClusterCounters)
373 {
374 // create Array and test its initialization
375 std::array<unsigned, 3> ctrArray = { {0, 0, 0} };
376 for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(ctrArray[i], 0); }
377
378 increaseClusterCounters(m_spacePoints[0], ctrArray); // PXD
379 EXPECT_EQ(ctrArray[0], 1);
380 increaseClusterCounters(m_spacePoints[1], ctrArray); // PXD
381 EXPECT_EQ(ctrArray[0], 2);
382
383 increaseClusterCounters(m_spacePoints[5], ctrArray); // SVD (two Cluster)
384 EXPECT_EQ(ctrArray[1], 1);
385 EXPECT_EQ(ctrArray[2], 1);
386
387 increaseClusterCounters(m_spacePoints[12], ctrArray); // SVD (only V set)
388 EXPECT_EQ(ctrArray[2], 2);
389 EXPECT_EQ(ctrArray[1], 1);
390 increaseClusterCounters(m_spacePoints[13], ctrArray); // SVD (only U set)
391 EXPECT_EQ(ctrArray[1], 2);
392 EXPECT_EQ(ctrArray[2], 2);
393 }
394
403 TEST_F(PurityCalculatorToolsTest, testGetMCParticlesPXD)
404 {
405 std::vector<std::pair<int, double> > mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[0]); // ideal PXD
406 ASSERT_EQ(mcParts.size(), 1);
407 EXPECT_EQ(mcParts[0].first, 0); // related to MCParticle with Id 0
408 EXPECT_DOUBLE_EQ(mcParts[0].second, 1);
409
410 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[1]); // PXD with no relation to TrueHit
411 ASSERT_EQ(mcParts.size(), 1);
412 EXPECT_EQ(mcParts[0].first, -2); // no TrueHit to Cluster
413 EXPECT_EQ(mcParts[0].second, 1);
414
415 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[2]); // PXD with two different TrueHits (to two different MCParticle Ids
416 ASSERT_EQ(mcParts.size(), 2);
417 auto findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
418 ASSERT_FALSE(findIt == mcParts.end());
419 EXPECT_DOUBLE_EQ(findIt->second, 1);
420 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
421 ASSERT_FALSE(findIt == mcParts.end());
422 EXPECT_DOUBLE_EQ(findIt->second, 1);
423
424 B2INFO("The occurring error message is expected! It is used to discover some corner cases in real usage!");
425 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[3]); // PXD with two TrueHits pointing to one MCParticle
426 ASSERT_EQ(mcParts.size(), 1);
427 EXPECT_EQ(mcParts[0].first, 1); // related to MCParticle 2
428 EXPECT_DOUBLE_EQ(mcParts[0].second, 1);
429 }
430
439 TEST_F(PurityCalculatorToolsTest, testGetMCParticlesSVD)
440 {
441 std::vector<std::pair<int, double> > mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[4]); // ideal SVD
442 ASSERT_EQ(mcParts.size(), 1);
443 EXPECT_EQ(mcParts[0].first, 0);
444 EXPECT_DOUBLE_EQ(mcParts[0].second, 2);
445
446 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[5]); // SVD with two THs to two different MCParticles
447 ASSERT_EQ(mcParts.size(), 2);
448 auto findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
449 ASSERT_FALSE(findIt == mcParts.end());
450 EXPECT_DOUBLE_EQ(findIt->second, 11); // U-Cluster to this MCParticle
451 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
452 ASSERT_FALSE(findIt == mcParts.end());
453 EXPECT_DOUBLE_EQ(findIt->second, 21); // V-Cluster to this MCParticle
454
455 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[6]); // SVD with no TrueHit relations
456 ASSERT_EQ(mcParts.size(), 1);
457 EXPECT_EQ(mcParts[0].first, -2);
458 EXPECT_DOUBLE_EQ(mcParts[0].second, 2);
459
460 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[7]);
461 ASSERT_EQ(mcParts.size(), 2);
462 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
463 ASSERT_FALSE(findIt == mcParts.end());
464 EXPECT_DOUBLE_EQ(findIt->second, 11); // only U-Cluster has connection to this MCParticle
465 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
466 ASSERT_FALSE(findIt == mcParts.end());
467 EXPECT_DOUBLE_EQ(findIt->second, 2); // both Clusters with relation to this MCParticle
468
469 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[8]); // only V-Cluster has relation to TrueHit
470 ASSERT_EQ(mcParts.size(), 2);
471 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
472 ASSERT_FALSE(findIt == mcParts.end());
473 EXPECT_DOUBLE_EQ(findIt->second, 11);
474 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0));
475 ASSERT_FALSE(findIt == mcParts.end());
476 EXPECT_DOUBLE_EQ(findIt->second, 21);
477
478 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[9]); // only U-Cluster has relation to TrueHit
479 ASSERT_EQ(mcParts.size(), 2);
480 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
481 ASSERT_FALSE(findIt == mcParts.end());
482 EXPECT_DOUBLE_EQ(findIt->second, 21);
483 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1));
484 ASSERT_FALSE(findIt == mcParts.end());
485 EXPECT_DOUBLE_EQ(findIt->second, 11);
486
487 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[11]); // U-Cluster has relations to two TrueHits, while V-Cluster has none
488 ASSERT_EQ(mcParts.size(), 3);
489 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0));
490 ASSERT_FALSE(findIt == mcParts.end());
491 EXPECT_DOUBLE_EQ(findIt->second, 11);
492 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1));
493 ASSERT_FALSE(findIt == mcParts.end());
494 EXPECT_DOUBLE_EQ(findIt->second, 11);
495 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
496 ASSERT_FALSE(findIt == mcParts.end());
497 EXPECT_DOUBLE_EQ(findIt->second, 21);
498
499 // NOTE: the rest of the occurring set-up cases should be covered by the above tests!
500 }
501
506 TEST_F(PurityCalculatorToolsTest, testCreatePurityInfos)
507 {
508 // first create a SpacePointTrackCand (as container of SpacePoints) containing all the wanted hits
509 std::vector<const SpacePoint*> spacePoints;
510 for (size_t i = 0; i < 12; ++i) { spacePoints.push_back(m_spacePoints[i]); } // do not use the last two SpacePoints from the setup
511 SpacePointTrackCand sptc(spacePoints);
512 EXPECT_EQ(sptc.getNHits(), 12); // check if the creation worked
513 unsigned totCls = 20;
514 float ndf = 4 * 2 + 8 * 2; // 4 PXD SpacePoints, and 8 two Cluster SVD-SpacePoints
515
516 B2INFO("There will be WARNING and ERROR messages! Those are expected!");
517 std::vector<MCVXDPurityInfo> purities = createPurityInfos(sptc); // create the purityInfos
518
519 EXPECT_EQ(purities.size(), 4); // 4 different Particle Ids: 0, 1, -1, -2
520
521 // check if the vector is sorted from highest to lowest overall purity
522 for (size_t i = 0; i < purities.size() - 1; ++i) {
523 EXPECT_TRUE(purities[i].getPurity().second >= purities[i + 1].getPurity().second);
524 }
525
526 auto findIt = find_if(purities.begin(), purities.end(), compMCId(1)); // get MCParticle with Id 1
527 ASSERT_FALSE(findIt == purities.end());
528 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
529 EXPECT_EQ(findIt->getNPXDClustersTotal(), 4); // 4 PXD Clusters were in container
530 EXPECT_EQ(findIt->getNClustersFound(), 6);
531 EXPECT_EQ(findIt->getNPXDClusters(), 2);
532 EXPECT_EQ(findIt->getNSVDUClusters(), 3);
533 EXPECT_EQ(findIt->getNSVDVClusters(), 1);
534 EXPECT_FLOAT_EQ(findIt->getPurity().second, 8. / ndf);
535
536 findIt = find_if(purities.begin(), purities.end(), compMCId(0)); // get Id 0
537 ASSERT_FALSE(findIt == purities.end());
538 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
539 EXPECT_EQ(findIt->getNSVDUClustersTotal(), 8); // 8 SVD U Clusters are in container
540 EXPECT_EQ(findIt->getNClustersFound(), 10);
541 EXPECT_EQ(findIt->getNPXDClusters(), 2);
542 EXPECT_EQ(findIt->getNSVDUClusters(), 5);
543 EXPECT_EQ(findIt->getNSVDVClusters(), 3);
544 EXPECT_FLOAT_EQ(findIt->getPurity().second, 12. / ndf);
545
546 findIt = find_if(purities.begin(), purities.end(), compMCId(-1));
547 ASSERT_FALSE(findIt == purities.end());
548 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
549 EXPECT_EQ(findIt->getNSVDVClustersTotal(), 8); // 8 SVD U Clusters are in container
550 EXPECT_EQ(findIt->getNClustersFound(), 1);
551 EXPECT_EQ(findIt->getNPXDClusters(), 0);
552 EXPECT_EQ(findIt->getNSVDUClusters(), 0);
553 EXPECT_EQ(findIt->getNSVDVClusters(), 1);
554 EXPECT_FLOAT_EQ(findIt->getPurity().second, 1. / ndf);
555
556 findIt = find_if(purities.begin(), purities.end(), compMCId(-2));
557 ASSERT_FALSE(findIt == purities.end());
558 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
559 EXPECT_EQ(findIt->getNClustersFound(), 6);
560 EXPECT_EQ(findIt->getNPXDClusters(), 1);
561 EXPECT_EQ(findIt->getNSVDUClusters(), 2);
562 EXPECT_EQ(findIt->getNSVDVClusters(), 3);
563 EXPECT_FLOAT_EQ(findIt->getPurity().second, 7. / ndf);
564 }
565
566} // namespace
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
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
The MC VXD Purity info container class.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: PXDTrueHit.h:31
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float weight(int index) const
Get weight with index.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:33
Storage for (VXD) SpacePoint-based track candidates.
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
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
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Base class to provide Sensor Information for PXD and SVD.
SensorType
Enum specifing the type of sensor the SensorInfo represents.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
class for testing the purity calculator tools (i.e.
StoreArray< Belle2::MCParticle > m_mcParticles
some MCParticles for testing
StoreArray< Belle2::SpacePoint > m_spacePoints
some SpacePoints for testing
std::vector< short > m_assignedClusters
store the expected number of assigned Clusters in vector to be able to loop over it
virtual void TearDown()
tear down environment after test -> clear datastore
virtual void SetUp()
set up the mockup that is needed by the tests
StoreArray< Belle2::PXDTrueHit > m_pxdTrueHits
some PXDTrueHits for testing
StoreArray< Belle2::SVDTrueHit > m_svdTrueHits
some SVDTrueHits for testing
static bool findWeightInVector(std::vector< std::pair< int, double > > &vec, double weight)
find the given weight in the given vector of pair<int,double> NOTE: the criteria for finding are rath...
static std::vector< size_t > getAccessorsFromWeight(double weight)
convert the relation weight (SpacePoint <-> TrueHit) to a type that can be used to access arrays
static void increaseClusterCounters(const Belle2::SpacePoint *spacePoint, std::array< unsigned, 3 > &clusterCtr)
increase the appropriate Cluster counter by asking the SpacePoint which type he has and which Cluster...
static std::vector< Belle2::MCVXDPurityInfo > createPurityInfos(const SPContainer *container)
create a vector of MCVXDPurityInfos objects for any given container holding SpacePoints and providing...
Abstract base class for different kinds of events.
STL namespace.
small helper functor to find a pair in a container of pairs, where .first matches the passed integer ...
bool operator()(const pair< int, short > &p)
comparison operator returning true if .first is j (from ctor)
compFirst(int j)
explicit constructor for use as functor with argument
int i
only member holding the value that has to be matched by the .first element of a pair
small helper functor to get the MCVXDPurityInfo with the passed ParticleId from a container of MCVXDP...
compMCId(int j)
explicit constructor for use as functor with arguments
int i
member holding the value that has to be mateched by the .first element of a pair
bool operator()(const MCVXDPurityInfo &info)
operator comparing the particle Id and the passed argument