Belle II Software  release-08-01-10
observers.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/SpacePoint.h>
12 #include <vxd/geometry/SensorInfoBase.h>
13 #include <tracking/trackFindingVXD/filterMap/twoHitVariables/Distance3DSquared.h>
14 
15 #include <tracking/trackFindingVXD/filterMap/filterFramework/Shortcuts.h>
16 
17 #include <svd/dataobjects/SVDCluster.h>
18 #include <pxd/dataobjects/PXDCluster.h>
19 #include <mdst/dataobjects/MCParticle.h>
20 
21 #include <framework/datastore/StoreArray.h>
22 #include <framework/gearbox/Const.h>
23 
24 #include <utility>
25 #include <map>
26 #include <string>
27 #include <iostream>
28 #include <cmath>
29 
30 #include <functional>
31 
32 using namespace std;
33 
34 using namespace Belle2;
45 namespace VXDTFObserversTest {
46 
47 
49  VXD::SensorInfoBase provideSensorInfo(VxdID aVxdID, double globalX = 0., double globalY = 0., double globalZ = -0.)
50  {
51  // (SensorType type, VxdID id, double width, double length, double thickness, int uCells, int vCells, double width2=-1, double splitLength=-1, int vCells2=0)
52  VXD::SensorInfoBase sensorInfoBase(VXD::SensorInfoBase::PXD, aVxdID, 2.3, 4.2, 0.3, 2, 4, -1);
53 
54  TGeoRotation r1;
55  r1.SetAngles(45, 20, 30); // rotation defined by Euler angles
56  TGeoTranslation t1(globalX, globalY, globalZ);
57  TGeoCombiTrans c1(t1, r1);
58  TGeoHMatrix transform = c1;
59  sensorInfoBase.setTransformation(transform);
60  // also need the reco transform
61  sensorInfoBase.setTransformation(transform, true);
62 
63  return sensorInfoBase;
64  }
65 
66 
67 
69  PXDCluster providePXDCluster(double u, double v, VxdID aVxdID, double uError = 0.1, double vError = 0.1)
70  {
71  return PXDCluster(aVxdID, u, v, uError, vError, 0, 0, 1, 1, 1, 1, 1, 1);
72  }
73 
74 
76  SVDCluster provideSVDCluster(VxdID aVxdID, bool isU, double position, double error = 0.1)
77  {
78  return SVDCluster(aVxdID, isU, position, error, 0.1, 0.1, 1, 1, 1, 1);
79  }
80 
81 
83  SpacePoint provideSpacePointDummy(unsigned short i, double X, double Y, double Z)
84  {
85  VxdID aVxdID = VxdID(i, i, i);
86  VXD::SensorInfoBase sensorInfoBase = provideSensorInfo(aVxdID, X, Y, Z);
87 
88  PXDCluster aCluster = PXDCluster(aVxdID, 0., 0., 0.1, 0.1, 0, 0, 1, 1, 1, 1, 1, 1);
89 
90  return SpacePoint(&aCluster, &sensorInfoBase);
91  }
92 
93 
94 
96  class ObserversTest : public ::testing::Test {
97  protected:
98 
100  virtual void SetUp()
101  {
102  spacePointData.registerInDataStore();
103  pxdClusterData.registerInDataStore();
104  svdClusterData.registerInDataStore();
105  mcParticleData.registerInDataStore();
106 
107  spacePointData.registerRelationTo(pxdClusterData);
108  pxdClusterData.registerRelationTo(mcParticleData);
109 
110  spacePointData.registerRelationTo(svdClusterData);
111  svdClusterData.registerRelationTo(mcParticleData);
112 
113  DataStore::Instance().setInitializeActive(false);
114 
115 
116  for (unsigned int i = 1; i < 3; ++i) { // prepare mcParticles, pxdClusters and spacePoints related to them
117  MCParticle* aParticle = mcParticleData.appendNew();
118 
119  aParticle->setMomentum(float(i), float(i), float(i));
120 
121  VxdID aVxdID = VxdID(i, i, i);
122 
123  VXD::SensorInfoBase aSensorInfo = provideSensorInfo(aVxdID, (unsigned short)i, (unsigned short)i + 1., (unsigned short)i + 2.);
124 
125  const PXDCluster* pxdCluster = pxdClusterData.appendNew(providePXDCluster(0., 0., aVxdID));
126  pxdCluster->addRelationTo(aParticle);
127 
128  SpacePoint* newSP = spacePointData.appendNew(pxdCluster, &aSensorInfo);
129  B2DEBUG(10, " setup: new spacePoint got arrayIndex: " << newSP->getArrayIndex() << " and VxdID " << newSP->getVxdID());
130  newSP->addRelationTo(pxdCluster);
131  }
132 
133  mcParticleData[0]->setPDG(Const::electron.getPDGCode());
134  mcParticleData[1]->setPDG(Const::muon.getPDGCode());
135  mcParticleData[1]->addStatus(MCParticle::c_PrimaryParticle);
136 
137 
138  for (unsigned int i = 3; i < 7; ++i) { // now SVDClusters and their related spacePoints
139 
140  VxdID aVxdID = VxdID(i, i, i);
141 
142  VXD::SensorInfoBase aSensorInfo = provideSensorInfo(aVxdID, (unsigned short)i, (unsigned short)i + 1., (unsigned short)i + 2.);
143 
144  unsigned int pID = (i - 3) / 2;
145 
146  const SVDCluster* clusterU = svdClusterData.appendNew(provideSVDCluster(aVxdID, true, 0.));
147  clusterU->addRelationTo(mcParticleData[pID]);
148  const SVDCluster* clusterV = svdClusterData.appendNew(provideSVDCluster(aVxdID, false, 0.));
149  clusterV->addRelationTo(mcParticleData[pID]);
150 
151  std::vector<const SVDCluster*> clusterVector = {clusterU, clusterV};
152 
153  SpacePoint* newSP = spacePointData.appendNew(clusterVector, &aSensorInfo);
154  newSP->addRelationTo(clusterU);
155  newSP->addRelationTo(clusterV);
156  }
157 
158  B2INFO("ObserversTest:SetUP: created " << mcParticleData.getEntries() << "/" << pxdClusterData.getEntries() << "/" <<
159  svdClusterData.getEntries() << "/" << spacePointData.getEntries() << " mcParticles/pxdClusters/svdClusters/SpacePoints");
160  }
161 
162 
163 
165  virtual void TearDown()
166  {
167  DataStore::Instance().reset();
168  }
169 
174  };
175 
176 
177 
178 
179 
181  template < class T>
182  class counter {
183  public:
184  static unsigned int used;
185  static unsigned int accepted;
186  static unsigned int rejected;
187  static unsigned int wasInf;
188  static unsigned int wasNan;
189  counter() {};
190  ~counter() {};
191  static void resetCounter()
192  {
193  counter<T>::used = 0;
196  counter<T>::wasInf = 0;
197  counter<T>::wasNan = 0;
198  }
199  };
200 
201 
202 
205  public:
206  CountContainer() { m_container.clear(); }
209  typedef std::vector<int> Particles;
210 
211 
217  typedef std::pair< bool, Particles > Key;
218 
219 
222  AcceptRejectPair() : accept(0), reject(0) {}
223 
227  void Increase(bool accepted)
228  {
229  if (accepted) {
230  accept += 1;
231  } else {
232  reject += 1;
233  }
234  }
235 
236  unsigned accept;
237  unsigned reject;
238  };
239 
240 
242  void clear() { m_container.clear(); }
243 
244 
246  unsigned int size() { return m_container.size(); }
247 
248 
250  template<class ContainerType> static void uniqueIdentifier(ContainerType& particles)
251  {
252  std::sort(particles.begin(), particles.end());
253  auto newEndIterator = std::unique(particles.begin(), particles.end());
254  particles.resize(std::distance(particles.begin(), newEndIterator));
255  }
256 
257 
259  bool IncreaseCounter(Key& aKey, bool accepted)
260  {
261  bool keyAlreadyExisted = true;
262  auto foundPos = m_container.find(aKey);
263  if (foundPos == m_container.end()) {
264  B2DEBUG(100, " the IDs " << key2str(aKey) << " collected haven't been found yet");
265  foundPos = m_container.insert({aKey, AcceptRejectPair() }).first;
266  keyAlreadyExisted = false;
267  } else { B2DEBUG(100, " the IDs " << key2str(aKey) << " collected were already there"); }
268 
269  foundPos->second.Increase(accepted);
270 
271  return keyAlreadyExisted;
272  }
273 
274 
275 
278  {
279 
280  auto foundPos = m_container.find(givenKey);
281 
282  if (foundPos == m_container.end()) {
283  return AcceptRejectPair();
284  }
285 
286  return foundPos->second;
287  }
288 
289 
290 
293  {
294  for (const auto& aKey : m_container) {
295  B2DEBUG(100, "comparing given particles: " << vec2str(givenKey) << " with entry: " << vec2str(
296  aKey.first.second) << " with result " << (aKey.first.second == givenKey));
297  if (aKey.first.second == givenKey) { return aKey.second; }
298  }
299 
300  return AcceptRejectPair();
301  }
302 
303 
304 
306  void PrintResults(const string& identifier = "unknown")
307  {
308  for (auto& entry : m_container) {
309  B2WARNING(" for " << identifier << "-combination: " <<
310  key2str(entry.first) <<
311  ", combi was accepted/rejected: " <<
312  entry.second.accept <<
313  "/" <<
314  entry.second.reject);
315  }
316  }
317 
318 
319 
321  static std::string key2str(const Key& aKey)
322  {
323  return key2str(&aKey);
324  }
325 
326 
328  static std::string key2str(const Key* aKey)
329  {
330  string output;
331 
332  if (aKey->first == true) { output += "GoodCombi: "; }
333  else { output += "BadCombi: "; }
334 
335  output += vec2str(aKey->second);
336 
337  return output;
338  }
339 
340 
342  template<class Type> static std::string vec2str(const vector<Type>& vec)
343  {
344  string output;
345 
346  for (const auto& entry : vec) {
347  output += " " + std::to_string(entry);
348  }
349 
350  return output;
351  }
352  protected:
353  std::map< Key, AcceptRejectPair> m_container;
354  };
355 
356 
357 
359  template < class T>
360  class counterMC {
361  public:
362  static CountContainer
364  static CountContainer
366  counterMC() {};
367  ~counterMC() {};
368  static void resetCounter()
369  {
372  }
373  };
374 
375 
376 
378  template<class T> unsigned int counter<T>::used(0);
379  template<class T> unsigned int counter<T>::accepted(0);
380  template<class T> unsigned int counter<T>::rejected(0);
381  template<class T> unsigned int counter<T>::wasInf(0);
382  template<class T> unsigned int counter<T>::wasNan(0);
383 
384  template<class T> CountContainer counterMC< T >::pdGacceptedRejected =
385  CountContainer();
386  template<class T> CountContainer counterMC< T >::mcIDacceptedRejected =
387  CountContainer();
395  public:
397  template<class Var, typename ... otherTypes>
398  static void notify(const Var&,
399  otherTypes ...)
400  {
401  counter<Var>::used ++ ;
402  }
403  };
404 
405 
406 
407 
408 
411  public:
413  template<class Var, class RangeType>
414  static void notify(const Var&,
415  typename Var::variableType fResult,
416  const RangeType& range,
417  const typename Var::argumentType&,
418  const typename Var::argumentType&)
419  {
420  if (range.contains(fResult)) {
422  } else {
424  }
425  }
426  };
427 
428 
429 
430 
431 
434  public:
436  template<class Var, typename ... otherTypes>
437  static void notify(const Var&,
438  typename Var::variableType fResult,
439  otherTypes ...)
440  {
441  if (std::isinf(fResult)) {
443  } else if (std::isnan(fResult)) {
445  }
446  }
447  };
448 
449 
450 
451 
452 
454  class InfoObserver : public VoidObserver {
455  public:
457  template<class Var, class RangeType>
458  static void notify(const Var& filterType,
459  typename Var::variableType fResult,
460  const RangeType& range,
461  const typename Var::argumentType& outerHit,
462  const typename Var::argumentType& innerHit)
463  {
464 
465  stringstream outputStream;
466  outputStream << filterType.name()
467  << " with outer-/innerhit: "
468  << outerHit.getPosition().PrintStringXYZ()
469  << "/"
470  << innerHit.getPosition().PrintStringXYZ()
471  << " having indices "
472  << outerHit.getArrayIndex()
473  << "/"
474  << innerHit.getArrayIndex()
475  << " and VxdIDs "
476  << outerHit.getVxdID()
477  << "/"
478  << innerHit.getVxdID()
479  << " results in "
480  << fResult
481  << " & accepted: "
482  << (range.contains(fResult) ? string("true") : string("false"))
483  << " in range "
484  << range.getInf()
485  << "/"
486  << range.getSup();
487 
488  if (range.contains(fResult)) {
489  B2INFO(outputStream.str());
490  } else {
491  B2WARNING(outputStream.str());
492  }
493  }
494  };
495 
496 
497 
498 
501  public:
502 
504  template<class Var, class RangeType>
505  static void notify(const Var&,
506  typename Var::variableType fResult,
507  const RangeType& range,
508  const typename Var::argumentType& outerHit,
509  const typename Var::argumentType& innerHit)
510  {
511  B2INFO("CountAcceptedRejectedMCParticleObserver called" << endl
512  << "range: ( " << range.getInf() << " , " << range.getSup() << " )" << endl
513  << "var = " << fResult << endl
514  << "outerHit: (" << outerHit.X() << " , "
515  << outerHit.Y() << " , "
516  << outerHit.Z() << " ) (x,y,z) " << endl
517  << "innerHit: (" << innerHit.X() << " , "
518  << innerHit.Y() << " , "
519  << innerHit.Z() << " ) (x,y,z) " << endl
520  );
521 
522  // we use the pdgCodes of the particles as identifier (not unique, since more than one primary particle can have the same PDG-code) and count their acceptance rate:
523  CountContainer::Key myPDGs = createKey(outerHit, innerHit, true);
524 
525  counterMC< Var >::pdGacceptedRejected.IncreaseCounter(myPDGs, range.contains(fResult));
526 
527 
528  // now we do the same but with mcParticleIDs:
529 
530  CountContainer::Key myPIDs = createKey(outerHit, innerHit, false);
531 
532  counterMC< Var >::mcIDacceptedRejected.IncreaseCounter(myPIDs, range.contains(fResult));
533  }
534 
535 
536 
544  template <class hitType>
545  static void collectPDGs(const hitType& aHit, vector< pair< bool, int> >& collectedPDGs)
546  {
547 
548  std::vector<const MCParticle*> collectedParticles;
549 
550  collectMCParticles(aHit, collectedParticles);
551 
552  for (const MCParticle* aParticle : collectedParticles) {
553  collectedPDGs.push_back({aParticle->hasStatus(MCParticle::c_PrimaryParticle), aParticle->getPDG()});
554  }
555  }
556 
557 
558 
566  template <class hitType>
567  static void collectParticleIDs(const hitType& aHit, vector< pair< bool, int> >& collectedIDS)
568  {
569 
570  std::vector<const MCParticle*> collectedParticles;
571 
572  collectMCParticles(aHit, collectedParticles);
573 
574  for (const MCParticle* aParticle : collectedParticles) {
575  collectedIDS.push_back({aParticle->hasStatus(MCParticle::c_PrimaryParticle), aParticle->getIndex()});
576  }
577  }
578 
580  template <class hitType>
581  static CountContainer::Key createKey(const hitType& hitA, const hitType& hitB, bool usePDG)
582  {
583  CountContainer::Key newKey;
584 
585  vector< pair< bool, int> > collectedIDS;
586 
587  if (usePDG) {
588  collectPDGs(hitA, collectedIDS);
589  collectPDGs(hitB, collectedIDS);
590  } else {
591  collectParticleIDs(hitA, collectedIDS);
592  collectParticleIDs(hitB, collectedIDS);
593  }
594 
595  CountContainer::uniqueIdentifier(collectedIDS);
596 
597  if (collectedIDS.size() == 1) {
598  newKey.first = collectedIDS[0].first;
599  newKey.second = { collectedIDS[0].second };
600  return newKey;
601  }
602 
603  newKey.first = false;
604 
605  for (auto& entry : collectedIDS) {
606  newKey.second.push_back(entry.second);
607  }
608 
609  return newKey;
610  }
611 
612 
620  template <class hitType>
621  static void collectMCParticles(const hitType& aHit, std::vector<const MCParticle*>& collectedParticles)
622  {
623  RelationVector<PXDCluster> relatedToPXDClusters = aHit.template getRelationsTo<PXDCluster>();
624  RelationVector<SVDCluster> relatedToSVDClusters = aHit.template getRelationsTo<SVDCluster>();
625 
626  for (const PXDCluster& aCluster : relatedToPXDClusters) {
627  for (const MCParticle& aParticle : aCluster.getRelationsTo<MCParticle>()) {
628  collectedParticles.push_back(&aParticle);
629  }
630  }
631 
632  for (const SVDCluster& aCluster : relatedToSVDClusters) {
633  for (const MCParticle& aParticle : aCluster.getRelationsTo<MCParticle>()) {
634  collectedParticles.push_back(&aParticle);
635  }
636  }
637  }
638 
639 
640 
642  template<class Type> static std::string vec2str(const vector<Type>& vec)
643  {
644  string output;
645 
646  for (const auto& entry : vec) {
647  output += " " + std::to_string(entry);
648  }
649 
650  return output;
651  }
652  };
653 
654 
657  public:
659  template<class Var, class RangeType>
660  static void notify(const Var& filterType,
661  typename Var::variableType fResult,
662  const RangeType& range,
663  const typename Var::argumentType& outerHit,
664  const typename Var::argumentType& innerHit)
665  {
666  CountUsedObserver::notify(filterType);
667  CountAcceptRejectObserver::notify(filterType, fResult, range, outerHit, innerHit);
668  CountBadCaseObserver::notify(filterType, fResult, range, outerHit, innerHit);
669  InfoObserver::notify(filterType, fResult, range, outerHit, innerHit);
670  }
671  };
672 
673 
674 
675 
676 
691  template<class FilterType> class VectorOfObservers : public VoidObserver {
692  public:
693 
695  typedef std::function< void (const FilterType&, typename FilterType::variableType, const typename FilterType::argumentType&, const typename FilterType::argumentType&)>
697 
699  using CStyleFunctionPointer = void(*)(const typename FilterType::argumentType&, const typename FilterType::argumentType&,
700  const FilterType&, typename FilterType::variableType) ;
701 
703  template<typename range, typename ... otherTypes>
704  static void notify(const FilterType& filterType,
705  typename FilterType::variableType filterResult,
706  const range&,
707  const typename FilterType::argumentType& outerHit,
708  const typename FilterType::argumentType& innerHit,
709  otherTypes ...)
710  {
711  B2INFO(" Filter " << filterType.name() << " with Mag of outer-/innerHit " << outerHit.getPosition().Mag() << "/" <<
712  innerHit.getPosition().Mag() << " got result of " << filterResult << " and Observer-Vector sm_collectedObservers got " <<
713  VectorOfObservers<FilterType>::sm_collectedObservers.size() << " observers collected");
714  B2INFO(" Filter " << filterType.name() << " with Mag of outer-/innerHit " << outerHit.getPosition().Mag() << "/" <<
715  innerHit.getPosition().Mag() << " got result of " << filterResult << " and Observer-Vector sm_collectedObserversCSTYLE got " <<
716  VectorOfObservers<FilterType>::sm_collectedObserversCSTYLE.size() << " observers collected");
717 
719  // for(auto& anObserver : CollectedObservers<FilterType>::collectedObservers) {
720  // anObserver(outerHit, innerHit, filterResult);
721  // }
723  }
724 
725 
726 
728  template <typename ObserverType>
729  static void addObserver(observerFunction newObserver)
730  {
731  VectorOfObservers<FilterType>::sm_collectedObservers.push_back(std::bind(&newObserver, std::placeholders::_1, std::placeholders::_2,
732  FilterType(), std::placeholders::_3));
733  }
734 
735 
736 
738  static std::vector< observerFunction > sm_collectedObservers;
740  static std::vector< CStyleFunctionPointer > sm_collectedObserversCSTYLE;
741 
743 // static std::vector< std::_Bind<void (*(std::_Placeholder<1>, std::_Placeholder<2>, Belle2::Distance3DSquared, std::_Placeholder<3>))(Belle2::SpacePoint const&, Belle2::SpacePoint const&, Belle2::Distance3DSquared const&, float)> > sm_collectedObserversTry2;
744  };
745 
746 
748  template<typename FilterType> std::vector< typename VectorOfObservers<FilterType>::observerFunction >
751  template<typename FilterType> std::vector< typename VectorOfObservers<FilterType>::CStyleFunctionPointer >
752  VectorOfObservers<FilterType>::sm_collectedObserversCSTYLE = {};
754 // template<typename FilterType> std::vector< typename VectorOfObservers<FilterType>::CStyleFunctionPointer > VectorOfObservers<FilterType>::sm_collectedObserversTry2 = {};
755 
756 
757 
758 
759 
761  TEST_F(ObserversTest, TestRelationSetup)
762  {
763  EXPECT_EQ(6, spacePointData.getEntries());
764 
765  for (SpacePoint& aSP : spacePointData) {
766  unsigned nullptrTrap = 0;
767  RelationVector<PXDCluster> pxDClusters = aSP.getRelationsTo<PXDCluster>();
768  for (PXDCluster& aCluster : pxDClusters) {
769  MCParticle* aParticle = aCluster.getRelatedTo<MCParticle>();
770  if (aParticle == nullptr) { nullptrTrap = 1; }
771  EXPECT_EQ(0, nullptrTrap);
772 
773  if (aParticle) {
774  EXPECT_EQ(aSP.getArrayIndex(), aCluster.getArrayIndex());
775  EXPECT_EQ(aSP.getArrayIndex(), aParticle->getArrayIndex());
776  EXPECT_EQ(int(aParticle->getMomentum().X()), aParticle->getArrayIndex() + 1);
777  EXPECT_EQ(int(aParticle->getMomentum().Y()), aParticle->getArrayIndex() + 1);
778  EXPECT_EQ(int(aParticle->getMomentum().Z()), aParticle->getArrayIndex() + 1);
779  }
780 
781  nullptrTrap = 0;
782  }
783 
784  RelationVector<SVDCluster> svDClusters = aSP.getRelationsTo<SVDCluster>();
785  for (SVDCluster& aCluster : svDClusters) {
786  MCParticle* aParticle = aCluster.getRelatedTo<MCParticle>();
787  if (aParticle == nullptr) { nullptrTrap = 2; }
788  EXPECT_EQ(0, nullptrTrap);
789 
790  if (aParticle) {
791  EXPECT_EQ(aSP.getArrayIndex(), 2 + aCluster.getArrayIndex() / 2);
792  EXPECT_EQ(aSP.getArrayIndex() / 4, aParticle->getArrayIndex());
793  EXPECT_EQ(int(aParticle->getMomentum().X()), aParticle->getArrayIndex() + 1);
794  EXPECT_EQ(int(aParticle->getMomentum().Y()), aParticle->getArrayIndex() + 1);
795  EXPECT_EQ(int(aParticle->getMomentum().Z()), aParticle->getArrayIndex() + 1);
796  }
797 
798  nullptrTrap = 0;
799  }
800 
801  // at least one cluster type has to be connected to given spacePoint!
802  EXPECT_NE(0, pxDClusters.size() + svDClusters.size());
803  }
804  }
805 
806 
807 
808 
809 
811  TEST_F(ObserversTest, TestMCDataAccess)
812  {
814  3.5));
816  unobservedFilter);
817  auto mcCounter = counterMC< Distance3DSquared<SpacePoint> >();
818 
819  for (int i = 1 ; i < spacePointData.getEntries(); i++) {
820  SpacePoint& spA = *spacePointData[i];
821  SpacePoint& spB = *spacePointData[i - 1];
822  B2DEBUG(10, "spData-Sps got arraIndices: " << spacePointData[i]->getArrayIndex() << "/" << spacePointData[i - 1]->getArrayIndex() <<
823  " and VxdIDs " << spacePointData[i]->getVxdID() << "/" << spacePointData[i - 1]->getVxdID());
824  observedFilter.accept(spA, spB);
825  }
826 
827  EXPECT_EQ(3, mcCounter.pdGacceptedRejected.size());
828  EXPECT_EQ(3, mcCounter.mcIDacceptedRejected.size());
829 
830  mcCounter.pdGacceptedRejected.PrintResults("pdgCode");
831 
833  // the filter was too loose, everything is accepted
834  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11}).accept);
835  EXPECT_EQ(3, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11, 13}).accept);
836  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{13}).accept);
837  // and nothing was rejected...
838  EXPECT_EQ(0, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11}).reject);
839  EXPECT_EQ(0, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11, 13}).reject);
840  EXPECT_EQ(0, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{13}).reject);
841 
842 
843  mcCounter.mcIDacceptedRejected.PrintResults("pID");
844 
845  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1}).accept);
846  EXPECT_EQ(3, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1, 2}).accept);
847  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{2}).accept);
848 
849  EXPECT_EQ(0, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1}).reject);
850  EXPECT_EQ(0, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1, 2}).reject);
851  EXPECT_EQ(0, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{2}).reject);
852 
853 
854  // now we set the filter using values which are too strict
856  (3.1, 3.5));
858  observedFilterStrict(
859  unobservedFilterStrict);
860 
861  for (int i = 1 ; i < spacePointData.getEntries(); i++) {
862  SpacePoint& spA = *spacePointData[i];
863  SpacePoint& spB = *spacePointData[i - 1];
864  observedFilterStrict.accept(spA, spB);
865  }
866 
867  EXPECT_EQ(3, mcCounter.pdGacceptedRejected.size());
868  EXPECT_EQ(3, mcCounter.mcIDacceptedRejected.size());
869 
870  // first filter does write into the same container, therefore values didn't change for accepted
871  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11}).accept);
872  EXPECT_EQ(3, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11, 13}).accept);
873  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{13}).accept);
874 
875  // second filter does reject everything:
876  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11}).reject);
877  EXPECT_EQ(3, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{11, 13}).reject);
878  EXPECT_EQ(1, mcCounter.pdGacceptedRejected.ReturnResult(CountContainer::Particles{13}).reject);
879 
880  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1}).accept);
881  EXPECT_EQ(3, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1, 2}).accept);
882  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{2}).accept);
883 
884  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1}).reject);
885  EXPECT_EQ(3, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{1, 2}).reject);
886  EXPECT_EQ(1, mcCounter.mcIDacceptedRejected.ReturnResult(CountContainer::Particles{2}).reject);
887 
888  }
889 
890 
891 
892 
893 
895  TEST_F(ObserversTest, TestObserverFlexibility)
896  {
897  // Very verbose declaration, see below for convenient shortcuts
899  1.));
900 
901  // Filter< Distance3DSquared<SpacePoint>, Range<double, double>, VectorOfObservers<Distance3DSquared> > filter(unobservedFilter);
902  Filter< Distance3DSquared<SpacePoint>, Range<double, double>, InfoObserver > observedFilter(unobservedFilter);
903  SpacePoint x1 = provideSpacePointDummy(1, 0.0f, 0.0f, 0.0f);
904  SpacePoint x2 = provideSpacePointDummy(1, 0.5f, 0.0f, 0.0f);
905  SpacePoint x3 = provideSpacePointDummy(1, 2.0f, 0.0f, 0.0f);
906  auto myCounter = counter<Distance3DSquared<SpacePoint>>();
907  myCounter.resetCounter();
908 
910 // auto storeFuncVariantA = std::bind( ((VectorOfObservers<Distance3DSquared>::observerFunction) &CountingObserver::notify), std::placeholders::_1, std::placeholders::_2, Distance3DSquared(), std::placeholders::_3);
911  // VectorOfObservers<Distance3DSquared>::sm_collectedObservers.push_back(storeFuncVariantA);
912 
914  auto storeFuncVariantB = std::bind(((VectorOfObservers<Distance3DSquared<SpacePoint>>::CStyleFunctionPointer)
915  &CountUsedObserver::notify), std::placeholders::_1, std::placeholders::_2, Distance3DSquared<SpacePoint>(),
916  std::placeholders::_3);
917 
918  char* realname(nullptr);
919  int status(0);
920  realname = abi::__cxa_demangle(typeid(storeFuncVariantB).name(), 0, 0, &status);
921  std::string name(realname);
922  free(realname);
923  B2INFO("storeFuncVariantB is of type: " << name);
924 
925 // VectorOfObservers<Distance3DSquared>::sm_collectedObserversTry2.push_back(storeFuncVariantB);
926 
927 
929 // VectorOfObservers<Distance3DSquared>::sm_collectedObserversCSTYLE.push_back(storeFuncVariantB);
930 
932  // VectorOfObservers<Distance3DSquared>::addObserver(CountUsedObserver);
933  // VectorOfObservers<Distance3DSquared>::addObserver(WarningObserver);
934 
935  observedFilter.accept(x2, x1);
936  observedFilter.accept(x3, x1);
937  EXPECT_EQ(0, myCounter.used);
938 
940  unobservedFilter);
941 
942  anotherObservedFilter.accept(x2, x1);
943  anotherObservedFilter.accept(x3, x1);
944  EXPECT_EQ(2, myCounter.used);
945  EXPECT_EQ(1, myCounter.accepted);
946  EXPECT_EQ(1, myCounter.rejected);
947  EXPECT_EQ(0, myCounter.wasInf);
948  EXPECT_EQ(0, myCounter.wasNan);
949  }
950 
951 
952 
953 
954 
957  {
958  //garbage:
959  // VectorOfObservers<Distance3DSquared>::addObserver(CountUsedObserver::notify);
960  // auto storeFunc = std::bind((void(*)(const SpacePoint&, const SpacePoint&, const Belle2::Distance3DSquared&, float))&CountUsedObserver::notify, std::placeholders::_1, std::placeholders::_2, Distance3DSquared(), std::placeholders::_3);
961  // auto storeFunc1 = std::bind(void(*)(const typename Distance3DSquared::argumentType&, const typename Distance3DSquared::argumentType&, const Distance3DSquared&, typename Distance3DSquared::variableType) /*&CountUsedObserver::notify*/), std::placeholders::_1, std::placeholders::_2, Distance3DSquared(), std::placeholders::_3);
962 
963 // ObserverVector<Distance3DSquared>::sm_collectedObservers.push_back(storeFunc);
964  // ObserverVector<Distance3DSquared>::sm_collectedObservers.push_back(std::bind((void(*)(const SpacePoint&, const SpacePoint&, const Belle2::Distance3DSquared&, float))&CountUsedObserver::notify, std::placeholders::_1, std::placeholders::_2, Distance3DSquared(), std::placeholders::_3));
965  // std::vector< typename ObserverVector<FilterType>::observerFunction >();
966  // ObserverVector<VectorOfObservers>::sm_collectedObservers = std::vector< typename VectorOfObservers<Distance3DSquared>::observerFunction >();
967 // ErrorObserver anErrorBla();
968  // WarningObserver aWarningBla();
969  // ObserverVector<Distance3DSquared>::addObserver(aWarningBla/*, filterBla*/);
970  // ObserverVector<Distance3DSquared>::addObserver(aBla/*, filterBla*/);
971  // // // // // // Distance3DSquared filterBla();
972 
974 // template<class FilterType> class CollectedObservers {
975 // public:
976 // typedef std::function< void (const typename FilterType::argumentType&, const typename FilterType::argumentType&, const FilterType&, typename FilterType::variableType)> observerFunction;
977 //
978 // /** collects observers to be executed during notify */
979 // static std::vector< observerFunction > collectedObservers;
980 // CollectedObservers() {};
981 // ~CollectedObservers() {};
982 // };
983 
984 // static void addObserver( CountUsedObserver& newObserver) {
985 // // static void addObserver(observerFunction newObserver) {
986 // ObserverVector<FilterType>::sm_collectedObservers.push_back(std::bind(&newObserver::notify, std::placeholders::_1, std::placeholders::_2, FilterType(), std::placeholders::_3));
987 // }
988  }
989 
990 }
This class is used to select pairs, triplets...
Definition: Filter.h:34
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition: MCParticle.h:244
ROOT::Math::XYZVector getMomentum() const
Return momentum.
Definition: MCParticle.h:198
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
Definition: MCParticle.h:417
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
Represents a range of arithmetic types.
Definition: Range.h:29
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
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).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
VxdID getVxdID() const
Return the VxdID of the sensor on which the the cluster of the SpacePoint lives.
Definition: SpacePoint.h:148
Base class to provide Sensor Information for PXD and SVD.
void setTransformation(const TGeoHMatrix &transform, bool reco=false)
Set the transformation matrix of the Sensor.
The most CPU efficient Observer for the VXDTF filter tools (even if useless).
Definition: VoidObserver.h:30
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
this observer does simply count the number of times, the attached SelectionVariable was accepted or r...
Definition: observers.cc:410
static void notify(const Var &, typename Var::variableType fResult, const RangeType &range, const typename Var::argumentType &, const typename Var::argumentType &)
notifier counting how often a SelectionVariable was accepted/rejected
Definition: observers.cc:414
this observer identifies the McParticles responsible for creating underlying clusters for given space...
Definition: observers.cc:500
static std::string vec2str(const vector< Type > &vec)
small helper for easily printing vectors
Definition: observers.cc:642
static void collectMCParticles(const hitType &aHit, std::vector< const MCParticle * > &collectedParticles)
collects all mcParticles connected to given hit.
Definition: observers.cc:621
static void collectPDGs(const hitType &aHit, vector< pair< bool, int > > &collectedPDGs)
collects all PDGs connected to given hit.
Definition: observers.cc:545
static CountContainer::Key createKey(const hitType &hitA, const hitType &hitB, bool usePDG)
for two hits given, a key for the CountContainer is returned.
Definition: observers.cc:581
static void collectParticleIDs(const hitType &aHit, vector< pair< bool, int > > &collectedIDS)
collects all particleIDs connected to given hit.
Definition: observers.cc:567
static void notify(const Var &, typename Var::variableType fResult, const RangeType &range, const typename Var::argumentType &outerHit, const typename Var::argumentType &innerHit)
notifier producing a info message if SelectionVariable was accepted and a Warning if otherwise
Definition: observers.cc:505
this observer does simply count the number of times, the attached Filter resulted in isinf or isnan
Definition: observers.cc:433
static void notify(const Var &, typename Var::variableType fResult, otherTypes ...)
notifier counting how often a SelectionVariable was resulting in nan or inf
Definition: observers.cc:437
a container for counting accepted and rejected stuff, just delivers some interfaces to make the code ...
Definition: observers.cc:204
std::pair< bool, Particles > Key
key for the internal container of this map
Definition: observers.cc:217
std::vector< int > Particles
a vector containing IDs
Definition: observers.cc:209
static void uniqueIdentifier(ContainerType &particles)
cleans a container of double entries
Definition: observers.cc:250
static std::string vec2str(const vector< Type > &vec)
small helper for easily printing vectors
Definition: observers.cc:342
bool IncreaseCounter(Key &aKey, bool accepted)
accepts a key (first parameter) and if given key was accepted by the filter (second parameter)
Definition: observers.cc:259
unsigned int size()
size of container
Definition: observers.cc:246
static std::string key2str(const Key &aKey)
small helper for easily printing vectors
Definition: observers.cc:321
void clear()
clear container
Definition: observers.cc:242
std::map< Key, AcceptRejectPair > m_container
collects the data
Definition: observers.cc:353
AcceptRejectPair ReturnResult(const Key &givenKey)
for given key, the function returns the result found.
Definition: observers.cc:277
AcceptRejectPair ReturnResult(const Particles &givenKey)
for given key, the function returns the result found.
Definition: observers.cc:292
static std::string key2str(const Key *aKey)
small helper for easily printing vectors
Definition: observers.cc:328
void PrintResults(const string &identifier="unknown")
for easy printing of results collected so far
Definition: observers.cc:306
this observer does simply count the number of times, the attached SelectionVariable was used
Definition: observers.cc:394
static void notify(const Var &, otherTypes ...)
notifier counting how often a SelectionVariable was used
Definition: observers.cc:398
this observer does simply print the name of the SelectionVariable and the result of its value-functio...
Definition: observers.cc:454
static void notify(const Var &filterType, typename Var::variableType fResult, const RangeType &range, const typename Var::argumentType &outerHit, const typename Var::argumentType &innerHit)
notifier producing a info message if SelectionVariable was accepted and a Warning if otherwise
Definition: observers.cc:458
Test class for testing and developing new Observers.
Definition: observers.cc:96
StoreArray< PXDCluster > pxdClusterData
some pxd clusters to test RelationsInterface for observers.
Definition: observers.cc:171
virtual void TearDown()
clear datastore
Definition: observers.cc:165
StoreArray< SpacePoint > spacePointData
some spacePoints to test RelationsInterface for observers.
Definition: observers.cc:170
StoreArray< MCParticle > mcParticleData
some mcParticles to test RelationsInterface for observers.
Definition: observers.cc:173
virtual void SetUp()
prepare related storearrays of SpacePoints, SVD- and PXDClusters and MCParticles
Definition: observers.cc:100
StoreArray< SVDCluster > svdClusterData
some svd clusters to test RelationsInterface for observers.
Definition: observers.cc:172
this observer combines all the easy-to-get info retrievable by observers and prints it to screen
Definition: observers.cc:656
static void notify(const Var &filterType, typename Var::variableType fResult, const RangeType &range, const typename Var::argumentType &outerHit, const typename Var::argumentType &innerHit)
notify function is called by the filter, this one combines all the easy-to-get info retrievable by ob...
Definition: observers.cc:660
static std::vector< observerFunction > sm_collectedObservers
collects observers with std::function to be executed during notify (variant A)
Definition: observers.cc:738
static std::vector< CStyleFunctionPointer > sm_collectedObserversCSTYLE
collects observers with c-style function pointers to be executed during notify (variant B)
Definition: observers.cc:740
static void addObserver(observerFunction newObserver)
collects observers to be executed during notify (can not be used so far, but is long-term goal)
Definition: observers.cc:729
std::function< void(const FilterType &, typename FilterType::variableType, const typename FilterType::argumentType &, const typename FilterType::argumentType &)> observerFunction
a typedef to make the stuff more readable
Definition: observers.cc:696
static void notify(const FilterType &filterType, typename FilterType::variableType filterResult, const range &, const typename FilterType::argumentType &outerHit, const typename FilterType::argumentType &innerHit, otherTypes ...)
iterate over all stored Observers and execute their notify-function
Definition: observers.cc:704
void(*)(const typename FilterType::argumentType &, const typename FilterType::argumentType &, const FilterType &, typename FilterType::variableType) CStyleFunctionPointer
a typedef to make the c-style pointer more readable (can not be done with classic typedef)
Definition: observers.cc:700
a tiny counter class for counting stuff retrieved from MC-bla
Definition: observers.cc:360
static CountContainer mcIDacceptedRejected
map for pdgCodes (key: vector of pdgCodes found for given hits, sorted) storing how often it was acce...
Definition: observers.cc:365
static void resetCounter()
destructor.
Definition: observers.cc:368
counterMC()
map for mcParticleIDs (key, vector of mcParticleIDs (pair: first: true, if combination was from the s...
Definition: observers.cc:366
static CountContainer pdGacceptedRejected
counts nCases accepted/rejected for each pdgCode-combination occured
Definition: observers.cc:363
a tiny counter class for counting stuff
Definition: observers.cc:182
static unsigned int accepted
count number of times result was accepted
Definition: observers.cc:185
static void resetCounter()
destructor.
Definition: observers.cc:191
static unsigned int wasInf
count number of times result was inf
Definition: observers.cc:187
static unsigned int used
count number of times used
Definition: observers.cc:184
static unsigned int rejected
count number of times result was rejected
Definition: observers.cc:186
static unsigned int wasNan
count number of times result was nan
Definition: observers.cc:188
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
Abstract base class for different kinds of events.
TODO next steps:
Definition: observers.cc:45
SVDCluster provideSVDCluster(VxdID aVxdID, bool isU, double position, double error=0.1)
returns a svdCluster with given sensorID, uType and local position
Definition: observers.cc:76
PXDCluster providePXDCluster(double u, double v, VxdID aVxdID, double uError=0.1, double vError=0.1)
returns a pxdCluster with given sensorID and local coordinates
Definition: observers.cc:69
VXD::SensorInfoBase provideSensorInfo(VxdID aVxdID, double globalX=0., double globalY=0., double globalZ=-0.)
this is a small helper function to create a sensorInfo to be used
Definition: observers.cc:49
simple struct for counting accepted and rejected cases.
Definition: observers.cc:221
unsigned reject
counts nTimes when it was rejected
Definition: observers.cc:237
void Increase(bool accepted)
Increase respective counter if accepted or not.
Definition: observers.cc:227
unsigned accept
counts nTimes when it was accepted
Definition: observers.cc:236