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;
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 {
106
109
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:
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
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 {
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
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
956 TEST_F(ObserversTest, ignoreMe)
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}
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
std::string PrintStringXYZ(unsigned precision=4) const
create a string containing vector in cartesian coordinates
Definition: B2Vector3.h:487
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
DataType Mag() const
The magnitude (rho in spherical coordinate system).
Definition: B2Vector3.h:159
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:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:86
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: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.
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
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
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 occurred
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
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