Belle II Software development
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
32using namespace std;
33
34using namespace Belle2;
44
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
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());
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 {
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 {
198 }
199 };
200
201
202
205 public:
207
209 typedef std::vector<int> Particles;
210
211
217 typedef std::pair< bool, Particles > Key;
218
219
221 struct AcceptRejectPair {
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() {};
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
388
389
390
391
392
395 public:
397 template<class Var, typename ... otherTypes>
398 static void notify(const Var&,
399 otherTypes ...)
400 {
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
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
688
689
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 >
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);
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}
static const ChargedStable muon
muon particle
Definition Const.h:660
static const ChargedStable electron
electron particle
Definition Const.h:659
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition DataStore.cc:85
This class is used to select pairs, triplets... of objects.
Definition Filter.h:34
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition MCParticle.h:47
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition MCParticle.h:233
ROOT::Math::XYZVector getMomentum() const
Return momentum.
Definition MCParticle.h:187
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
Definition MCParticle.h:406
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.
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
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
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
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).
VoidObserver()
An empty constructor for an empty class.
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 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
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:699
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 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 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
static std::vector< observerFunction > sm_collectedObservers
collects observers with std::function to be executed during notify (variant A)
Definition observers.cc:738
a tiny counter class for counting stuff retrieved from MC-bla
Definition observers.cc:360
static CountContainer mcIDacceptedRejected
map for mcParticleIDs (key, vector of mcParticleIDs (pair: first: true, if combination was from the s...
Definition observers.cc:365
static void resetCounter()
destructor.
Definition observers.cc:368
static CountContainer pdGacceptedRejected
map for pdgCodes (key: vector of pdgCodes found for given hits, sorted) storing how often it was acce...
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
B2Vector3D outerHit(0, 0, 0)
testing out of range behavior
Abstract base class for different kinds of events.
TODO next steps:
Definition observers.cc:45
TEST_F(ObserversTest, TestRelationSetup)
initialize static member of variant Try2
Definition observers.cc:761
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
SpacePoint provideSpacePointDummy(unsigned short i, double X, double Y, double Z)
when given index number for vxdID and global coordinates, a SpacePoint lying there will be returned
Definition observers.cc:83
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
STL namespace.
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