Belle II Software  release-08-01-10
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 
29 using namespace std;
30 using namespace Belle2;
31 
32 namespace 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 doesnot 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  {
139  DataStore::Instance().setInitializeActive(true);
140 
141  // register everything necessary in the datastore
142  m_pxdTrueHits.registerInDataStore("PXDTHs");
143  m_svdTrueHits.registerInDataStore("SVDTHs");
144  m_spacePoints.registerInDataStore("SPs");
145  m_mcParticles.registerInDataStore("MCPs");
146 
147  // register the needed relations
148  m_spacePoints.registerRelationTo(m_svdTrueHits);
149  m_spacePoints.registerRelationTo(m_pxdTrueHits);
150  m_mcParticles.registerRelationTo(m_svdTrueHits);
151  m_mcParticles.registerRelationTo(m_pxdTrueHits);
152 
153  DataStore::Instance().setInitializeActive(false);
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 
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 occuring 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 occuring 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
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
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
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
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 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...
static std::vector< size_t > getAccessorsFromWeight(double weight)
convert the relation weight (SpacePoint <-> TrueHit) to a type that can be used to access arrays
Abstract base class for different kinds of events.
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