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
81 SpacePoint createSpacePoint(VxdID sensorId, bool pxd, short nClusters = 0, double u = 0.1, double v = 0.2)
82 {
83 if (pxd) {
84 VXD::SensorInfoBase sensorInfo = createSensorInfo(sensorId, VXD::SensorInfoBase::PXD);
85 PXDCluster pxdCluster(sensorId, u, v, 0.1, 0.1, 0, 0, 1, 1, 1, 1, 1, 1);
86 return SpacePoint(&pxdCluster, &sensorInfo);
87 } else {
88 VXD::SensorInfoBase sensorInfo = createSensorInfo(sensorId, VXD::SensorInfoBase::SVD);
89 vector<const SVDCluster*> clusters;
90
91 if (!nClusters) { // if 0 set both
92 clusters.push_back(new SVDCluster(sensorId, true, u, 1.0, 0.1, 0.001, 1, 1, 1, 1.0));
93 clusters.push_back(new SVDCluster(sensorId, false, v, 1.0, 0.1, 0.001, 1, 1, 1, 1.0));
94 } else { // set only one coordinate
95 bool setU = (nClusters > 0);
96 clusters.push_back(new SVDCluster(sensorId, setU, u, 1.0, 0.1, 0.001, 1, 1, 1, 1.0)); // position doesn't actually matter!
97 }
98 return SpacePoint(clusters, &sensorInfo);
99 }
100 return SpacePoint(); // empty SP as default but should not happen!
101 }
102
107 struct compFirst {
108 explicit compFirst(int j) : i(j) { }
109 bool operator()(const pair<int, short>& p)
110 {
111 return p.first == i;
112 }
113 private:
114 int i;
115 };
116
120 struct compMCId {
121 explicit compMCId(int j) : i(j) { }
122 bool operator()(const MCVXDPurityInfo& info)
123 {
124 return info.getParticleID() == i;
125 }
126 private:
127 int i;
128 };
129
133 class PurityCalculatorToolsTest : public ::testing::Test {
134 protected:
135
140 virtual void SetUp()
141 {
143
144 // register everything necessary in the datastore
145 m_pxdTrueHits.registerInDataStore("PXDTHs");
146 m_svdTrueHits.registerInDataStore("SVDTHs");
147 m_spacePoints.registerInDataStore("SPs");
148 m_mcParticles.registerInDataStore("MCPs");
149
150 // register the needed relations
151 m_spacePoints.registerRelationTo(m_svdTrueHits);
152 m_spacePoints.registerRelationTo(m_pxdTrueHits);
153 m_mcParticles.registerRelationTo(m_svdTrueHits);
154 m_mcParticles.registerRelationTo(m_pxdTrueHits);
155
157
158 // populate datastore
159 MCParticle* mcPart1 = m_mcParticles.appendNew(createMCParticle());
160 MCParticle* mcPart2 = m_mcParticles.appendNew(createMCParticle());
161
162 // add a PXD (ideal case: one TrueHit -> one MCParticle)
163 VxdID pxdId(1, 1, 1);
164 PXDTrueHit* pTrueHit = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
165 mcPart1->addRelationTo(pTrueHit);
166 SpacePoint* spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
167 spacePoint->addRelationTo(pTrueHit, 1); // PXD has only one Cluster
168 m_assignedClusters.push_back(1);
169
170 // add a PXD (non-ideal case: no TrueHit)
171 m_spacePoints.appendNew(createSpacePoint(pxdId, true));
172 m_assignedClusters.push_back(1);
173
174 // add a PXD (non-ideal case: more than one (i.e. two for the test) TrueHits -> 2 MCParticles)
175 PXDTrueHit* pTrueHit2 = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
176 mcPart2->addRelationTo(pTrueHit2);
177 spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
178 spacePoint->addRelationTo(pTrueHit, 1);
179 spacePoint->addRelationTo(pTrueHit2, 1);
180 m_assignedClusters.push_back(1);
181
182 // add a PXD (non-ideal case: more than one (i.e. two for the test) TrueHits -> 1 MCParticles)
183 // -> both TrueHits are related with the same MCParticle (probably a very rare corner case, but this is what testing is for)
184 PXDTrueHit* pTrueHit3 = m_pxdTrueHits.appendNew(createTrueHit<PXDTrueHit>(pxdId));
185 mcPart2->addRelationTo(pTrueHit3);
186 spacePoint = m_spacePoints.appendNew(createSpacePoint(pxdId, true));
187 spacePoint->addRelationTo(pTrueHit3, 1);
188 spacePoint->addRelationTo(pTrueHit2, 1);
189 m_assignedClusters.push_back(1);
190
191 // NOTE: SVD only testing two Clusters SpacePoints since single Clusters are essentially the same as PXDs!
192 // SVD: first set up some SVDTrueHits with differing relations to MCParticles
193 VxdID svdId(3, 1, 1);
194 SVDTrueHit* sTH2MC1 = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to mcParticle1
195 mcPart1->addRelationTo(sTH2MC1);
196 SVDTrueHit* sTH2MC2 = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to mcParticle2
197 mcPart2->addRelationTo(sTH2MC2);
198 SVDTrueHit* sTH2None = m_svdTrueHits.appendNew(createTrueHit<SVDTrueHit>(svdId)); // related to no MCParticle
199
200 // add a SVD (ideal case: two Clusters -> 1 TrueHit -> 1 MCParticle)
201 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
202 spacePoint->addRelationTo(sTH2MC1, 2); // both Clusters to one TrueHit
203 m_assignedClusters.push_back(2);
204
205 // add a SVD (non-ideal case: twoClusters -> 2 TrueHits -> 2 MCParticles)
206 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
207 m_assignedClusters.push_back(2);
208 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
209 spacePoint->addRelationTo(sTH2MC2, 21); // V-Cluster
210
211 // add a SVD (non-ideal case: no related TrueHits)
212 m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
213 m_assignedClusters.push_back(2);
214
215 // add a SVD (non-ideal case: twoClusters -> 2 TrueHits -> 2 MCParticles with different numbers of related Clusters
216 // for TrueHits)
217 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
218 m_assignedClusters.push_back(2);
219 spacePoint->addRelationTo(sTH2MC1, 2); // both Clusters related to this TrueHit
220 spacePoint->addRelationTo(sTH2MC2, 11); // only one Cluster related to TrueHit (U-Cluster in this case)
221
222 // add a SVD (non-ideal case: only one Cluster with relation to ONE TrueHit: V-Cluster related)
223 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
224 m_assignedClusters.push_back(2);
225 spacePoint->addRelationTo(sTH2MC1, 21); // one V-Cluster with relation to TrueHit with relation to MCParticle
226
227 // add a SVD (non-ideal case: only one Cluster with relation to ONE TrueHit: U-Cluster related)
228 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
229 m_assignedClusters.push_back(2);
230 spacePoint->addRelationTo(sTH2MC2, 11); // one U-Cluster with relation to TrueHit with relation to MCParticle
231
232 // add a SVD (non-ideal case: only one TrueHit has a relation to a MCParticle)
233 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
234 m_assignedClusters.push_back(2);
235 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
236 spacePoint->addRelationTo(sTH2None, 21); // V-Cluster without relation to MCParticle
237
238 // add a SVD (non-ideal case: one Cluster has relations to more than one TrueHit, while the other has not)
239 spacePoint = m_spacePoints.appendNew(createSpacePoint(svdId, false, 0)); // add twoCluster SP
240 m_assignedClusters.push_back(2);
241 spacePoint->addRelationTo(sTH2MC1, 11); // U-Cluster
242 spacePoint->addRelationTo(sTH2MC2, 11); // U-Cluster, no relation for V-Cluster
243
244 // add singleCluster SpacePoints for testing the increaseCounterMethod. Do not need any relations!
245 // NOTE: these shall not be included in the testing of the other methods!
246 m_spacePoints.appendNew(createSpacePoint(svdId, false, -1)); // add V-Cluster set only
247 m_assignedClusters.push_back(1);
248 m_spacePoints.appendNew(createSpacePoint(svdId, false, 1)); // add U-Cluster set only
249 m_assignedClusters.push_back(1);
250 }
251
253 virtual void TearDown() { DataStore::Instance().reset(); }
254
255 // members to be used in the tests
260
261 std::vector<short> m_assignedClusters;
262 };
263
267 TEST_F(PurityCalculatorToolsTest, testSetUp)
268 {
269 B2INFO("Contents of DataStore after SetUp: pxdTrueHits: " << m_pxdTrueHits.getEntries() <<
270 " svdTrueHits: " << m_svdTrueHits.getEntries() << " mcParticles: " << m_mcParticles.getEntries() <<
271 " spacePoints: " << m_spacePoints.getEntries());
272
273 // test if StoreArray has all the entries that should be there
274 EXPECT_EQ(m_pxdTrueHits.getEntries(), 3);
275 EXPECT_EQ(m_svdTrueHits.getEntries(), 3);
276 EXPECT_EQ(m_spacePoints.getEntries(), 14);
277 EXPECT_EQ(m_mcParticles.getEntries(), 2);
278
279 // test if the SpacePoints have the expected number of assigned Clusters
280 for (int i = 0; i < m_spacePoints.getEntries(); ++i) {
281 EXPECT_EQ(m_spacePoints[i]->getNClustersAssigned(), m_assignedClusters[i]);
282 }
283
284 // test if the relations are set according to the set-up (mainly testing if the methods for setting up are working properly)
285 // NOTE: only sampling here, not testing all SpacePoints! (but still tried to cover all important relations (i.e. TH -> MCPart))
286 RelationVector<PXDTrueHit> pxdTrueHits = m_spacePoints[0]->getRelationsTo<PXDTrueHit>("ALL");
287 ASSERT_EQ(pxdTrueHits.size(), 1);
288 EXPECT_EQ(pxdTrueHits[0]->getArrayIndex(), 0);
289 EXPECT_EQ(pxdTrueHits.weight(0), 1);
290
291 pxdTrueHits = m_spacePoints[2]->getRelationsTo<PXDTrueHit>("ALL");
292 ASSERT_EQ(pxdTrueHits.size(), 2);
293 EXPECT_EQ(pxdTrueHits[0]->getArrayIndex(), 0);
294 EXPECT_EQ(pxdTrueHits[0]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 0);
295 EXPECT_EQ(pxdTrueHits.weight(0), 1);
296 EXPECT_EQ(pxdTrueHits[1]->getArrayIndex(), 1);
297 EXPECT_EQ(pxdTrueHits[1]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 1);
298 EXPECT_EQ(pxdTrueHits.weight(1), 1);
299
300 RelationVector<SVDTrueHit> svdTrueHits = m_spacePoints[4]->getRelationsTo<SVDTrueHit>("ALL");
301 ASSERT_EQ(svdTrueHits.size(), 1);
302 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0);
303 EXPECT_EQ(svdTrueHits[0]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 0);
304 EXPECT_EQ(svdTrueHits.weight(0), 2);
305
306 svdTrueHits = m_spacePoints[5]->getRelationsTo<SVDTrueHit>("ALL");
307 ASSERT_EQ(svdTrueHits.size(), 2);
308 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0); // MCParticle relation already tested!
309 EXPECT_EQ(svdTrueHits.weight(0), 11);
310 EXPECT_EQ(svdTrueHits[1]->getArrayIndex(), 1);
311 EXPECT_EQ(svdTrueHits.weight(1), 21);
312 EXPECT_EQ(svdTrueHits[1]->getRelatedFrom<MCParticle>("ALL")->getArrayIndex(), 1);
313
314 svdTrueHits = m_spacePoints[6]->getRelationsTo<SVDTrueHit>("ALL");
315 ASSERT_EQ(svdTrueHits.size(), 0);
316
317 svdTrueHits = m_spacePoints[7]->getRelationsTo<SVDTrueHit>("ALL");
318 ASSERT_EQ(svdTrueHits.size(), 2);
319 EXPECT_EQ(svdTrueHits[0]->getArrayIndex(), 0); // MCParticle relation already tested!
320 EXPECT_EQ(svdTrueHits.weight(0), 2);
321 EXPECT_EQ(svdTrueHits.weight(1), 11); // only related to U-Cluster
322 EXPECT_EQ(svdTrueHits[1]->getArrayIndex(), 1); // MCParticle relation already tested!
323 }
324
328 TEST_F(PurityCalculatorToolsTest, testFindWeightInVector)
329 {
330 std::vector<std::pair<int, double> > vec;
331 vec.push_back(std::make_pair(1, 0));
332 vec.push_back(std::make_pair(1, 1.1));
333 vec.push_back(std::make_pair(1, 2));
334 vec.push_back(std::make_pair(1, 11));
335 vec.push_back(std::make_pair(1, 21));
336 vec.push_back(std::make_pair(1, 11));
337 vec.push_back(std::make_pair(1, 2.5));
338
339 EXPECT_TRUE(findWeightInVector(vec, 1e-4));
340 EXPECT_TRUE(findWeightInVector(vec, 1.1));
341 EXPECT_FALSE(findWeightInVector(vec, 11.1));
342 EXPECT_FALSE(findWeightInVector(vec, 2.501));
343 }
344
348 TEST_F(PurityCalculatorToolsTest, testGetAccessorsFromWeight)
349 {
350 // empty returns first
351 std::vector<size_t> accs = getAccessorsFromWeight(0);
352 EXPECT_TRUE(accs.empty());
353 accs = getAccessorsFromWeight(30);
354 EXPECT_TRUE(accs.empty());
355
356 // cases that occur in "real life"
357 accs = getAccessorsFromWeight(1);
358 EXPECT_EQ(accs[0], 0); // -> PXD
359 EXPECT_EQ(accs.size(), 1);
360 accs = getAccessorsFromWeight(2);
361 EXPECT_EQ(accs.size(), 2);
362 EXPECT_EQ(accs[0], 1);
363 EXPECT_EQ(accs[1], 2);
364 accs = getAccessorsFromWeight(11);
365 EXPECT_EQ(accs[0], 1); // -> SVD U Cluster
366 EXPECT_EQ(accs.size(), 1);
367 accs = getAccessorsFromWeight(21);
368 EXPECT_EQ(accs[0], 2);
369 EXPECT_EQ(accs.size(), 1);
370 }
371
375 TEST_F(PurityCalculatorToolsTest, testIncreaseClusterCounters)
376 {
377 // create Array and test its initialization
378 std::array<unsigned, 3> ctrArray = { {0, 0, 0} };
379 for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(ctrArray[i], 0); }
380
381 increaseClusterCounters(m_spacePoints[0], ctrArray); // PXD
382 EXPECT_EQ(ctrArray[0], 1);
383 increaseClusterCounters(m_spacePoints[1], ctrArray); // PXD
384 EXPECT_EQ(ctrArray[0], 2);
385
386 increaseClusterCounters(m_spacePoints[5], ctrArray); // SVD (two Cluster)
387 EXPECT_EQ(ctrArray[1], 1);
388 EXPECT_EQ(ctrArray[2], 1);
389
390 increaseClusterCounters(m_spacePoints[12], ctrArray); // SVD (only V set)
391 EXPECT_EQ(ctrArray[2], 2);
392 EXPECT_EQ(ctrArray[1], 1);
393 increaseClusterCounters(m_spacePoints[13], ctrArray); // SVD (only U set)
394 EXPECT_EQ(ctrArray[1], 2);
395 EXPECT_EQ(ctrArray[2], 2);
396 }
397
406 TEST_F(PurityCalculatorToolsTest, testGetMCParticlesPXD)
407 {
408 std::vector<std::pair<int, double> > mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[0]); // ideal PXD
409 ASSERT_EQ(mcParts.size(), 1);
410 EXPECT_EQ(mcParts[0].first, 0); // related to MCParticle with Id 0
411 EXPECT_DOUBLE_EQ(mcParts[0].second, 1);
412
413 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[1]); // PXD with no relation to TrueHit
414 ASSERT_EQ(mcParts.size(), 1);
415 EXPECT_EQ(mcParts[0].first, -2); // no TrueHit to Cluster
416 EXPECT_EQ(mcParts[0].second, 1);
417
418 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[2]); // PXD with two different TrueHits (to two different MCParticle Ids
419 ASSERT_EQ(mcParts.size(), 2);
420 auto findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
421 ASSERT_FALSE(findIt == mcParts.end());
422 EXPECT_DOUBLE_EQ(findIt->second, 1);
423 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
424 ASSERT_FALSE(findIt == mcParts.end());
425 EXPECT_DOUBLE_EQ(findIt->second, 1);
426
427 B2INFO("The occurring error message is expected! It is used to discover some corner cases in real usage!");
428 mcParts = getMCParticles<PXDTrueHit>(m_spacePoints[3]); // PXD with two TrueHits pointing to one MCParticle
429 ASSERT_EQ(mcParts.size(), 1);
430 EXPECT_EQ(mcParts[0].first, 1); // related to MCParticle 2
431 EXPECT_DOUBLE_EQ(mcParts[0].second, 1);
432 }
433
442 TEST_F(PurityCalculatorToolsTest, testGetMCParticlesSVD)
443 {
444 std::vector<std::pair<int, double> > mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[4]); // ideal SVD
445 ASSERT_EQ(mcParts.size(), 1);
446 EXPECT_EQ(mcParts[0].first, 0);
447 EXPECT_DOUBLE_EQ(mcParts[0].second, 2);
448
449 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[5]); // SVD with two THs to two different MCParticles
450 ASSERT_EQ(mcParts.size(), 2);
451 auto findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
452 ASSERT_FALSE(findIt == mcParts.end());
453 EXPECT_DOUBLE_EQ(findIt->second, 11); // U-Cluster to this MCParticle
454 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
455 ASSERT_FALSE(findIt == mcParts.end());
456 EXPECT_DOUBLE_EQ(findIt->second, 21); // V-Cluster to this MCParticle
457
458 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[6]); // SVD with no TrueHit relations
459 ASSERT_EQ(mcParts.size(), 1);
460 EXPECT_EQ(mcParts[0].first, -2);
461 EXPECT_DOUBLE_EQ(mcParts[0].second, 2);
462
463 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[7]);
464 ASSERT_EQ(mcParts.size(), 2);
465 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1)); // one MCParticle with Id 1
466 ASSERT_FALSE(findIt == mcParts.end());
467 EXPECT_DOUBLE_EQ(findIt->second, 11); // only U-Cluster has connection to this MCParticle
468 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0)); // one MCParticle with Id 0
469 ASSERT_FALSE(findIt == mcParts.end());
470 EXPECT_DOUBLE_EQ(findIt->second, 2); // both Clusters with relation to this MCParticle
471
472 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[8]); // only V-Cluster has relation to TrueHit
473 ASSERT_EQ(mcParts.size(), 2);
474 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
475 ASSERT_FALSE(findIt == mcParts.end());
476 EXPECT_DOUBLE_EQ(findIt->second, 11);
477 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0));
478 ASSERT_FALSE(findIt == mcParts.end());
479 EXPECT_DOUBLE_EQ(findIt->second, 21);
480
481 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[9]); // only U-Cluster has relation to TrueHit
482 ASSERT_EQ(mcParts.size(), 2);
483 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
484 ASSERT_FALSE(findIt == mcParts.end());
485 EXPECT_DOUBLE_EQ(findIt->second, 21);
486 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1));
487 ASSERT_FALSE(findIt == mcParts.end());
488 EXPECT_DOUBLE_EQ(findIt->second, 11);
489
490 mcParts = getMCParticles<SVDTrueHit>(m_spacePoints[11]); // U-Cluster has relations to two TrueHits, while V-Cluster has none
491 ASSERT_EQ(mcParts.size(), 3);
492 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(0));
493 ASSERT_FALSE(findIt == mcParts.end());
494 EXPECT_DOUBLE_EQ(findIt->second, 11);
495 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(1));
496 ASSERT_FALSE(findIt == mcParts.end());
497 EXPECT_DOUBLE_EQ(findIt->second, 11);
498 findIt = std::find_if(mcParts.begin(), mcParts.end(), compFirst(-2));
499 ASSERT_FALSE(findIt == mcParts.end());
500 EXPECT_DOUBLE_EQ(findIt->second, 21);
501
502 // NOTE: the rest of the occurring set-up cases should be covered by the above tests!
503 }
504
509 TEST_F(PurityCalculatorToolsTest, testCreatePurityInfos)
510 {
511 // first create a SpacePointTrackCand (as container of SpacePoints) containing all the wanted hits
512 std::vector<const SpacePoint*> spacePoints;
513 for (size_t i = 0; i < 12; ++i) { spacePoints.push_back(m_spacePoints[i]); } // do not use the last two SpacePoints from the setup
514 SpacePointTrackCand sptc(spacePoints);
515 EXPECT_EQ(sptc.getNHits(), 12); // check if the creation worked
516 unsigned totCls = 20;
517 float ndf = 4 * 2 + 8 * 2; // 4 PXD SpacePoints, and 8 two Cluster SVD-SpacePoints
518
519 B2INFO("There will be WARNING and ERROR messages! Those are expected!");
520 std::vector<MCVXDPurityInfo> purities = createPurityInfos(sptc); // create the purityInfos
521
522 EXPECT_EQ(purities.size(), 4); // 4 different Particle Ids: 0, 1, -1, -2
523
524 // check if the vector is sorted from highest to lowest overall purity
525 for (size_t i = 0; i < purities.size() - 1; ++i) {
526 EXPECT_TRUE(purities[i].getPurity().second >= purities[i + 1].getPurity().second);
527 }
528
529 auto findIt = find_if(purities.begin(), purities.end(), compMCId(1)); // get MCParticle with Id 1
530 ASSERT_FALSE(findIt == purities.end());
531 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
532 EXPECT_EQ(findIt->getNPXDClustersTotal(), 4); // 4 PXD Clusters were in container
533 EXPECT_EQ(findIt->getNClustersFound(), 6);
534 EXPECT_EQ(findIt->getNPXDClusters(), 2);
535 EXPECT_EQ(findIt->getNSVDUClusters(), 3);
536 EXPECT_EQ(findIt->getNSVDVClusters(), 1);
537 EXPECT_FLOAT_EQ(findIt->getPurity().second, 8. / ndf);
538
539 findIt = find_if(purities.begin(), purities.end(), compMCId(0)); // get Id 0
540 ASSERT_FALSE(findIt == purities.end());
541 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
542 EXPECT_EQ(findIt->getNSVDUClustersTotal(), 8); // 8 SVD U Clusters are in container
543 EXPECT_EQ(findIt->getNClustersFound(), 10);
544 EXPECT_EQ(findIt->getNPXDClusters(), 2);
545 EXPECT_EQ(findIt->getNSVDUClusters(), 5);
546 EXPECT_EQ(findIt->getNSVDVClusters(), 3);
547 EXPECT_FLOAT_EQ(findIt->getPurity().second, 12. / ndf);
548
549 findIt = find_if(purities.begin(), purities.end(), compMCId(-1));
550 ASSERT_FALSE(findIt == purities.end());
551 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
552 EXPECT_EQ(findIt->getNSVDVClustersTotal(), 8); // 8 SVD U Clusters are in container
553 EXPECT_EQ(findIt->getNClustersFound(), 1);
554 EXPECT_EQ(findIt->getNPXDClusters(), 0);
555 EXPECT_EQ(findIt->getNSVDUClusters(), 0);
556 EXPECT_EQ(findIt->getNSVDVClusters(), 1);
557 EXPECT_FLOAT_EQ(findIt->getPurity().second, 1. / ndf);
558
559 findIt = find_if(purities.begin(), purities.end(), compMCId(-2));
560 ASSERT_FALSE(findIt == purities.end());
561 EXPECT_EQ(findIt->getNClustersTotal(), totCls);
562 EXPECT_EQ(findIt->getNClustersFound(), 6);
563 EXPECT_EQ(findIt->getNPXDClusters(), 1);
564 EXPECT_EQ(findIt->getNSVDUClusters(), 2);
565 EXPECT_EQ(findIt->getNSVDVClusters(), 3);
566 EXPECT_FLOAT_EQ(findIt->getPurity().second, 7. / ndf);
567 }
568
569} // namespace
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition DataStore.cc:85
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
The MC VXD Purity info container class.
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).
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition SVDTrueHit.h:33
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition SpacePoint.h:42
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
SensorType
Enum specifying the type of sensor the SensorInfo represents.
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:32
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 std::vector< std::pair< int, double > > getMCParticles(const Belle2::SpacePoint *spacePoint)
get the related MCParticles to the TrueHit.
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