Belle II Software  release-08-01-10
threeHitFilters.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 <tracking/trackFindingVXD/filterMap/threeHitVariables/Angle3DSimple.h>
13 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/Angle3DFull.h>
14 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/CosAngleXY.h>
15 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/AngleXYFull.h>
16 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/AngleRZSimple.h>
17 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/AngleRZFull.h>
18 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/CircleDist2IP.h>
19 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/SignCurvatureXY.h>
20 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/SignCurvatureXYError.h>
21 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/DeltaSlopeRZ.h>
22 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/DeltaSlopeZoverS.h>
23 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/DeltaSoverZ.h>
24 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/HelixParameterFit.h>
25 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/Pt.h>
26 #include <tracking/trackFindingVXD/filterMap/threeHitVariables/CircleRadius.h>
27 #include <tracking/trackFindingVXD/filterTools/SelectionVariableHelper.h>
28 
29 #include <tracking/trackFindingVXD/filterMap/filterFramework/Shortcuts.h>
30 
31 #include <vxd/geometry/SensorInfoBase.h>
32 
33 #include <math.h>
34 
35 
36 using namespace std;
37 using namespace Belle2;
38 
39 namespace VXDTFthreeHitFilterTest {
40 
42  class ThreeHitFilterTest : public ::testing::Test {
43  protected:
44  };
45 
46 
47 
49  VXD::SensorInfoBase createSensorInfo(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 reco-transform
61  sensorInfoBase.setTransformation(transform, true);
62 
63  return sensorInfoBase;
64  }
65 
66 
67 
69  SpacePoint provideSpacePointDummy(double X, double Y, double Z)
70  {
71  VxdID aVxdID = VxdID(1, 1, 1);
72  VXD::SensorInfoBase sensorInfoBase = createSensorInfo(aVxdID, X, Y, Z);
73 
74  PXDCluster aCluster = PXDCluster(aVxdID, 0., 0., 0.1, 0.1, 0, 0, 1, 1, 1, 1, 1, 1);
75 
76  return SpacePoint(&aCluster, &sensorInfoBase);
77  }
78 
79 
81  SpacePoint provideSpacePointDummyError(double X, double Y, double Z, double eX, double eY, double eZ)
82  {
83  VxdID aVxdID = VxdID(1, 1, 1);
84 
85  B2Vector3D pos(X, Y, Z);
86  B2Vector3D poserr(eX, eY, eZ);
87 
88  return SpacePoint(pos, poserr, {0.0, 0.0}, {false, false}, aVxdID, Belle2::VXD::SensorInfoBase::PXD);
89  }
90 
91 
92 
94  double lastResult = 0.;
95 
96 
97 
99  class ResultsObserver : public VoidObserver {
100  public:
102  template<class Var, typename ... otherTypes>
103  static void notify(const Var& filterType,
104  typename Var::variableType fResult,
105  otherTypes ...)
106  {
107  B2INFO("ResultsObserver: Filter " << filterType.name() << " got result of " << fResult);
108  lastResult = fResult;
109  }
110 
111  };
112 
113 
115  TEST_F(ThreeHitFilterTest, SpacePointCreation)
116  {
117  SpacePoint testSP = provideSpacePointDummy(1.2, 2.3, 4.2);
118  EXPECT_FLOAT_EQ(1.2, testSP.getPosition().X()) ;
119  EXPECT_FLOAT_EQ(2.3, testSP.getPosition().Y()) ;
120  EXPECT_FLOAT_EQ(4.2, testSP.getPosition().Z()) ;
121  }
122 
123 
125  TEST_F(ThreeHitFilterTest, SelectionVariableName)
126  {
127  auto angle3DS = Angle3DSimple<SpacePoint>();
128  EXPECT_EQ("Angle3DSimple", angle3DS.name());
129  auto angle3DF = Angle3DFull<SpacePoint>();
130  EXPECT_EQ("Angle3DFull", angle3DF.name());
131  auto angleXYF = AngleXYFull<SpacePoint>();
132  EXPECT_EQ("AngleXYFull", angleXYF.name());
133  auto angleXYS = CosAngleXY<SpacePoint>();
134  EXPECT_EQ("CosAngleXY", angleXYS.name());
135  auto angleRZF = AngleRZFull<SpacePoint>();
136  EXPECT_EQ("AngleRZFull", angleRZF.name());
137  auto angleRZS = AngleRZSimple<SpacePoint>();
138  EXPECT_EQ("AngleRZSimple", angleRZS.name());
139  auto dSlopeRZ = DeltaSlopeRZ<SpacePoint>();
140  EXPECT_EQ("DeltaSlopeRZ", dSlopeRZ.name());
141  auto helixFit = HelixParameterFit<SpacePoint>();
142  EXPECT_EQ("HelixParameterFit", helixFit.name());
143  auto dSlopeZS = DeltaSlopeZoverS<SpacePoint>();
144  EXPECT_EQ("DeltaSlopeZoverS", dSlopeZS.name());
145  auto dSZ = DeltaSoverZ<SpacePoint>();
146  EXPECT_EQ("DeltaSoverZ", dSZ.name());
147  auto pT = Pt<SpacePoint>();
148  EXPECT_EQ("Pt", pT.name());
149  auto cDist2IP = CircleDist2IP<SpacePoint>();
150  EXPECT_EQ("CircleDist2IP", cDist2IP.name());
151  }
152 
153 
155  TEST_F(ThreeHitFilterTest, BasicFilterTestAngle3DSimple)
156  {
157  // Very verbose declaration, see below for convenient shortcuts
159 
160  SpacePoint x1 = provideSpacePointDummy(0., 0., 0.);
161  SpacePoint x2 = provideSpacePointDummy(.5, 0., 0.);
162  SpacePoint x3 = provideSpacePointDummy(2., 0., 0.);
163 
164  EXPECT_FALSE(filter.accept(x1, x2, x3));
165 
166  }
167 
168 
170  TEST_F(ThreeHitFilterTest, TestAngles)
171  {
172  SpacePoint outerSP = provideSpacePointDummy(6., 4., 1.);
173  SpacePoint centerSP = provideSpacePointDummy(3., 3., 0.);
174  SpacePoint innerSP = provideSpacePointDummy(1., 1., 0.);
175 
176 
178  0.091));
179  EXPECT_TRUE(filterAngle3D.accept(outerSP, centerSP, innerSP));
180  EXPECT_FLOAT_EQ(0.090909090909090909091, lastResult); // last result is what filterAngle3D had calculated
181 
182  Filter< Angle3DFull<SpacePoint>, Range<double, double>, ResultsObserver > filterAngle3Dfull(Range<double, double>(31.48,
183  31.49));
184  EXPECT_TRUE(filterAngle3Dfull.accept(outerSP, centerSP, innerSP));
185  EXPECT_FLOAT_EQ(31.4821541052938556040832384555411729852856, lastResult);
186 
187 
188  Filter< AngleXYFull<SpacePoint>, Range<double, double>, ResultsObserver > filterAngleXYfull(Range<double, double>(26.5,
189  26.6));
190  EXPECT_TRUE(filterAngleXYfull.accept(outerSP, centerSP, innerSP));
191  EXPECT_FLOAT_EQ(26.5650511770779893515721937204532946712042, lastResult);
192 
193  Filter< CosAngleXY<SpacePoint>, Range<double, double>, ResultsObserver > filterAngleXY(Range<double, double>(0.7,
194  0.9));
195  EXPECT_TRUE(filterAngleXY.accept(outerSP, centerSP, innerSP));
196  EXPECT_NEAR(0.89442718, lastResult, 0.0000001);
197 
198 
199  Filter< AngleRZFull<SpacePoint>, Range<double, double>, ResultsObserver > filterAngleRZfull(Range<double, double>(17.5,
200  17.6));
201  EXPECT_TRUE(filterAngleRZfull.accept(outerSP, centerSP, innerSP));
202  EXPECT_NEAR(17.548400613792298064, lastResult, 0.001);
203 
205  0.96));
206  EXPECT_TRUE(filterAngleRZ.accept(outerSP, centerSP, innerSP));
207  EXPECT_NEAR(cos(17.54840061379229806435203716652846677620 * M_PI / 180.), lastResult, 0.001);
208  }
209 
210 
211 
213  TEST_F(ThreeHitFilterTest, TestSignAndOtherFilters)
214  {
215  SpacePoint outerSP = provideSpacePointDummy(6., 4., 1.);
216  SpacePoint centerSP = provideSpacePointDummy(3., 3., 0.);
217  SpacePoint innerSP = provideSpacePointDummy(1., 1., 0.);
218  SpacePoint outerHighSP = provideSpacePointDummy(4., 6., 1.);
219  B2Vector3D sigma(.01, .01, .01), unrealsigma(2, 2, 2);
220 
221  SpacePoint outerSPsigma = provideSpacePointDummyError(6., 4., 1., 0.01, 0.01, 0.01);
222  SpacePoint centerSPsigma = provideSpacePointDummyError(3., 3., 0., 0.01, 0.01, 0.01);
223  SpacePoint innerSPsigma = provideSpacePointDummyError(1., 1., 0., 0.01, 0.01, 0.01);
224  SpacePoint outerHighSPsigma = provideSpacePointDummyError(4., 6., 1., 0.01, 0.01, 0.01);
225 
226  SpacePoint outerSPunrealsigma = provideSpacePointDummyError(6., 4., 1., 2., 2., 2.);
227  SpacePoint centerSPunrealsigma = provideSpacePointDummyError(3., 3., 0., 2., 2., 2.);
228  SpacePoint innerSPunrealsigma = provideSpacePointDummyError(1., 1., 0., 2., 2., 2.);
229 
230  Filter< DeltaSlopeRZ<SpacePoint>, Range<double, double>, ResultsObserver > filterDeltaSlopeRZ(Range<double, double>(0.3,
231  0.31));
232  EXPECT_TRUE(filterDeltaSlopeRZ.accept(outerSP, centerSP, innerSP));
233  EXPECT_FLOAT_EQ(0.30627736916966945608, lastResult);
234 
236  0.01));
237  EXPECT_TRUE(filterHelixFit.accept(outerSP, centerSP, innerSP));
238  EXPECT_FLOAT_EQ(0., lastResult);
239 
240  EXPECT_DOUBLE_EQ(1., SignCurvatureXYError<SpacePoint>::value(outerSPsigma, centerSPsigma, innerSPsigma));
241  EXPECT_DOUBLE_EQ(-1., SignCurvatureXYError<SpacePoint>::value(outerHighSPsigma, centerSPsigma, innerSPsigma));
242  EXPECT_DOUBLE_EQ(-1., SignCurvatureXYError<SpacePoint>::value(innerSPsigma, centerSPsigma, outerSPsigma));
243  //for very large sigma, this track is approximately straight:
244  EXPECT_DOUBLE_EQ(0., SignCurvatureXYError<SpacePoint>::value(outerSPunrealsigma, centerSPunrealsigma, innerSPunrealsigma));
245 
246  EXPECT_LT(0., SignCurvatureXY<SpacePoint>::value(outerSP, centerSP, innerSP));
247  EXPECT_GT(0., SignCurvatureXY<SpacePoint>::value(outerHighSP, centerSP, innerSP));
248  EXPECT_GT(0., SignCurvatureXY<SpacePoint>::value(innerSP, centerSP, outerSP));
249  EXPECT_LT(0., SignCurvatureXY<SpacePoint>::value(outerSP, centerSP, innerSP));
250 
251  EXPECT_DOUBLE_EQ(1., SignCurvatureXY<SpacePoint>::value(outerSP, centerSP, innerSP));
252  EXPECT_DOUBLE_EQ(-1., SignCurvatureXY<SpacePoint>::value(outerHighSP, centerSP, innerSP));
253  EXPECT_DOUBLE_EQ(-1., SignCurvatureXY<SpacePoint>::value(innerSP, centerSP, outerSP));
254  }
255 
256 
257 
259  TEST_F(ThreeHitFilterTest, TestDeltaSOverZ)
260  {
261  lastResult = 0;
262  B2Vector3D iVec(1., 1., 0.), cVec(3., 3., 1.), oVec(6., 4., 3.);
263  SpacePoint outerSP = provideSpacePointDummy(oVec.X(), oVec.Y(), oVec.Z());
264  SpacePoint centerSP = provideSpacePointDummy(cVec.X(), cVec.Y(), cVec.Z());
265  SpacePoint innerSP = provideSpacePointDummy(iVec.X(), iVec.Y(), iVec.Z());
266 
267  Filter< DeltaSlopeZoverS<SpacePoint>, Range<double, double>, ResultsObserver > filterDeltaSlopeZOverS(Range<double, double>
268  (0.31,
269  0.32));
270  EXPECT_TRUE(filterDeltaSlopeZOverS.accept(outerSP, centerSP, innerSP));
271  EXPECT_NEAR(0.31823963, lastResult, 0.00001);
272 
273  Filter< DeltaSoverZ<SpacePoint>, Range<double, double>, ResultsObserver > filterDeltaSOverZ(Range<double, double>(-0.39,
274  -0.38));
275  EXPECT_TRUE(filterDeltaSOverZ.accept(outerSP, centerSP, innerSP));
276  EXPECT_FLOAT_EQ(-0.38471845, lastResult);
277 
278 
279  //calcDeltaSOverZV2 is invariant under rotations in the r-z plane:
280  oVec.RotateZ(.4);
281  cVec.RotateZ(.4);
282  iVec.RotateZ(.4);
283  SpacePoint outerSP2 = provideSpacePointDummy(oVec.X(), oVec.Y(), oVec.Z());
284  SpacePoint centerSP2 = provideSpacePointDummy(cVec.X(), cVec.Y(), cVec.Z());
285  SpacePoint innerSP2 = provideSpacePointDummy(iVec.X(), iVec.Y(), iVec.Z());
286 
287  EXPECT_TRUE(filterDeltaSlopeZOverS.accept(outerSP2, centerSP2, innerSP2));
288  EXPECT_NEAR(0.31823963, lastResult, 0.00001);
289 
290  EXPECT_TRUE(filterDeltaSOverZ.accept(outerSP2, centerSP2, innerSP2));
291  EXPECT_FLOAT_EQ(-0.38471845, lastResult);
292  }
293 
294 
295 
297  TEST_F(ThreeHitFilterTest, TestCalcPt)
298  {
299  typedef SelVarHelper<SpacePoint, double> Helper;
300 
301  SpacePoint outerSP = provideSpacePointDummy(3., 4., 3.);
302  SpacePoint centerSP = provideSpacePointDummy(3., 2., 1.);
303  SpacePoint innerSP = provideSpacePointDummy(1., 2., 0.);
304 
305  SpacePoint outerSPEvil = provideSpacePointDummy(6., 3., 0.);
306  SpacePoint centerSP2 = provideSpacePointDummy(3., 3., 0.);
307  SpacePoint innerSP2 = provideSpacePointDummy(1., 1., 0.);
308 
309  double ptTrue = 0,
310  rawRadius = 1.414213562373095048801688724209698078570;
311  ptTrue = Helper::calcPt(rawRadius);
312  Filter< Pt<SpacePoint>, Range<double, double>, ResultsObserver > filterPt(Range<double, double>(0.005, 0.05));
313  EXPECT_TRUE(filterPt.accept(outerSP, centerSP, innerSP));
314  EXPECT_FLOAT_EQ(ptTrue, lastResult);
315 
316  ptTrue = 0.017118925181688543;
317  EXPECT_TRUE(filterPt.accept(outerSPEvil, centerSP2, innerSP2));
318  EXPECT_FLOAT_EQ(ptTrue, lastResult);
319 
320  //B2WARNING("MUST produce errors: 2 hits are the same: " << ptTrue << ", Pt: " << pt );
321  EXPECT_ANY_THROW(filterPt.accept(outerSP, outerSP, innerSP));
322 
323  Helper::resetMagneticField(0.976);
324  double ptTrue1p5 = ptTrue;
325  ptTrue = Helper::calcPt(rawRadius);
326  EXPECT_FALSE(filterPt.accept(outerSP, centerSP, innerSP));
327  EXPECT_FLOAT_EQ(ptTrue, lastResult);
328  EXPECT_LT(ptTrue, ptTrue1p5);
329 
330  Helper::resetMagneticField(1.5);
331  }
332 
333 
335  TEST_F(ThreeHitFilterTest, TestCircleRadius)
336  {
337  SpacePoint outerSP = provideSpacePointDummy(3., 4., 3.);
338  SpacePoint centerSP = provideSpacePointDummy(3., 2., 1.);
339  SpacePoint innerSP = provideSpacePointDummy(1., 2., 0.);
340 
341  double rawRadius = 1.414213562373095048801688724209698078570;
342  Filter< CircleRadius<SpacePoint>, Range<double, double>, ResultsObserver > filterCrad(Range<double, double>(1.4, 1.42));
343  EXPECT_TRUE(filterCrad.accept(outerSP, centerSP, innerSP));
344  EXPECT_FLOAT_EQ(rawRadius, lastResult);
345 
346  //B2WARNING("MUST produce errors: 2 hits are the same:");
347  EXPECT_ANY_THROW(filterCrad.accept(outerSP, outerSP, innerSP));
348 
349 // EXPECT_FALSE(filterCrad.accept(outerSP, centerSP, innerSP));
350  EXPECT_FLOAT_EQ(rawRadius, lastResult); // after fail result is not changed
351  }
352 
354  TEST_F(ThreeHitFilterTest, TestCircleDist2IP)
355  {
356  SpacePoint outerSPEvil = provideSpacePointDummy(6., 3., 0.);
357  SpacePoint outerSPSimple = provideSpacePointDummy(6., 4., 0.);
358  SpacePoint centerSP = provideSpacePointDummy(3., 3., 0.);
359  SpacePoint innerSP = provideSpacePointDummy(1., 1., 0.);
360 
361  Filter< CircleDist2IP<SpacePoint>, Range<double, double>, ResultsObserver > filteCircleDist2IP(Range<double, double>(0.44,
362  0.45));
363  EXPECT_TRUE(filteCircleDist2IP.accept(outerSPSimple, centerSP, innerSP));
364  EXPECT_NEAR(0.44499173338941, lastResult, 0.00001);
365 
366  EXPECT_FALSE(filteCircleDist2IP.accept(outerSPEvil, centerSP, innerSP));
367  EXPECT_FLOAT_EQ(0.719806016136754, lastResult);
368 
369 
370  typedef SelVarHelper<SpacePoint, double> Helper;
371  Helper::resetMagneticField(0.976);
372 
373  EXPECT_TRUE(filteCircleDist2IP.accept(outerSPSimple, centerSP, innerSP));
374  EXPECT_NEAR(0.44499173338941, lastResult, 0.00001);
375 
376  EXPECT_FALSE(filteCircleDist2IP.accept(outerSPEvil, centerSP, innerSP));
377  EXPECT_FLOAT_EQ(0.719806016136754, lastResult);
378 
379  Helper::resetMagneticField(1.5);
380  }
381 
382 }
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
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
This class is used to select pairs, triplets...
Definition: Filter.h:34
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
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
Definition: SpacePoint.h:42
const B2Vector3< double > & getPosition() const
return the position vector in global coordinates
Definition: SpacePoint.h:138
Base class to provide Sensor Information for PXD and SVD.
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
takes result, prints it and stores it to lastResult
static void notify(const Var &filterType, typename Var::variableType fResult, otherTypes ...)
notify function is called by the filter, this one takes result, prints it and stores it to lastResult...
Test class for these new and shiny two-hit-filters.
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
std::map< ExpRun, std::pair< double, double > > filter(const std::map< ExpRun, std::pair< double, double >> &runs, double cut, std::map< ExpRun, std::pair< double, double >> &runsRemoved)
filter events to remove runs shorter than cut, it stores removed runs in runsRemoved
Definition: Splitter.cc:38
Abstract base class for different kinds of events.
contains a collection of functions and related stuff needed for SelectionVariables implementing 2-,...