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