ATLAS Offline Software
Loading...
Searching...
No Matches
MeasurementBaseComparisonFunction.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MeasurementBaseComparisonFunction.h
7// Header file for struct MeasurementBaseComparisonFunction
9// (c) ATLAS Detector software
11// Wolfgang.Liebig@cern.ch / Andreas.Salzburger@cern.ch
13
14#ifndef TRKNIRVANA_MEASUREMENTBASECOMPARISONFUNCTION_H
15#define TRKNIRVANA_MEASUREMENTBASECOMPARISONFUNCTION_H
16
17// Trk
22// extra-maths for cylinder intersections
26// STL
27#include <algorithm>
28#include <stdexcept>
29
30// Amg
33
34namespace Trk {
35
38
40{
41public:
50
51 /*
52 * Default methods
53 */
55 const MeasurementBaseComparisonFunction& MCF) = default;
59 default;
61 MeasurementBaseComparisonFunction&& MCF) = default;
62
66 const Trk::MeasurementBase* two) const
67 {
68
69 // --- flexible sorting along a predicted direction
70 double path1 = 0;
71 const Trk::Surface& sf1 = one->associatedSurface();
72 const Trk::SurfaceType surfType1 = sf1.type();
73 switch (surfType1) {
75 const Trk::PlaneSurface& opsf =
76 static_cast<const Trk::PlaneSurface&>(sf1);
77 path1 = this->pathIntersectWithPlane(opsf);
78 } break;
80 const Trk::StraightLineSurface& ossf =
81 static_cast<const Trk::StraightLineSurface&>(sf1);
82 path1 = this->pathIntersectWithLine(ossf);
83 } break;
85 const Trk::DiscSurface& odsf =
86 static_cast<const Trk::DiscSurface&>(sf1);
87 path1 = this->pathIntersectWithDisc(odsf);
88 } break;
90 const Trk::CylinderSurface& ocsf =
91 static_cast<const Trk::CylinderSurface&>(sf1);
92 path1 = this->pathIntersectWithCylinder(ocsf, one->globalPosition());
93 } break;
95 const Trk::PerigeeSurface& ogsf =
96 static_cast<const Trk::PerigeeSurface&>(sf1);
97 path1 = this->pathIntersectWithLine(ogsf);
98 } break;
99 default: {
100 throw std::runtime_error(
101 "MeasurementBaseComparisonFunction: surface type error for Sf1!");
102 }
103 }
104
105 // --- identify the 2nd surface type and get intersection path for surface 1
106 double path2 = 0;
107 const Trk::Surface& sf2 = two->associatedSurface();
108 const Trk::SurfaceType surfType2 = sf2.type();
109 switch (surfType2) {
111 const Trk::PlaneSurface& tpsf =
112 static_cast<const Trk::PlaneSurface&>(sf2);
113 path2 = this->pathIntersectWithPlane(tpsf);
114 } break;
116 const Trk::StraightLineSurface& tssf =
117 static_cast<const Trk::StraightLineSurface&>(sf2);
118 path2 = this->pathIntersectWithLine(tssf);
119 } break;
121 const Trk::DiscSurface& tdsf =
122 static_cast<const Trk::DiscSurface&>(sf2);
123 path2 = this->pathIntersectWithDisc(tdsf);
124 } break;
126 const Trk::CylinderSurface& tcsf =
127 static_cast<const Trk::CylinderSurface&>(sf2);
128 path2 = this->pathIntersectWithCylinder(tcsf, two->globalPosition());
129 } break;
131 const Trk::PerigeeSurface& tgsf =
132 static_cast<const Trk::PerigeeSurface&>(sf2);
133 path2 = this->pathIntersectWithLine(tgsf);
134 } break;
135 default: {
136 throw std::runtime_error(
137 "MeasurementBaseComparisonFunction: surface type error for Sf2!");
138 }
139 }
140 return path1 < path2;
141 }
142
143private:
146
148 {
149 double denom = m_direction.dot(psf.normal());
150 return (denom) ? psf.normal().dot(psf.center() - m_point) / (denom) : denom;
151 }
152
154 {
155 const Amg::Vector3D& dirWire = lsf.lineDirection().normalized();
156 Amg::Vector3D trackToWire(lsf.center() - m_point);
157 double parallelity = m_direction.dot(dirWire);
158 double denom = 1 - parallelity * parallelity;
159 return (fabs(denom) > 10e-7) ? (trackToWire.dot(m_direction) -
160 trackToWire.dot(dirWire) * parallelity) /
161 denom
162 : 0.;
163 }
164
166 {
167 Amg::Vector3D trackToWire(pgsf.center() - m_point);
168 double parallelity = m_direction.dot(Trk::s_zAxis);
169 double denom = 1 - parallelity * parallelity;
170 return (fabs(denom) > 10e-7)
171 ? (trackToWire.dot(m_direction) -
172 trackToWire.dot(Trk::s_zAxis) * parallelity) /
173 denom
174 : 0.;
175 }
176
178 {
179 double denom = m_direction.dot(dsf.normal());
180 return (denom) ? dsf.normal().dot(dsf.center() - m_point) / (denom) : denom;
181 }
182
184 const Amg::Vector3D& globalHit) const
185 { // --- code from TrkExSlPropagator/LineCylinderIntersection.cxx
186
187 // get the rotation by reference
188 const Amg::Transform3D& locTrans = csf.transform();
189 // take two points of line and calculate them to the 3D frame of the
190 // cylinder
191 Amg::Vector3D point1(locTrans.inverse() * m_point);
192 Amg::Vector3D point2raw = m_point + m_direction;
193 Amg::Vector3D point2(locTrans.inverse() * point2raw); // do it in two steps
194
195 // new direction in 3D frame of cylinder
196 Amg::Vector3D direc((point2 - point1).unit());
197
198 if (!direc.x()) {
199 return 0.;
200 } else {
201 // get line and circle constants
202 double k = (direc.y()) / (direc.x());
203 double d = (point2.x() * point1.y() - point1.x() * point2.y()) /
204 (point2.x() - point1.x());
205 double R = csf.bounds().r();
206 double first = 0.;
207 double second = 0.;
208
209 // and solve the quadratic equation Trk::RealQuadraticEquation
210 // pquad(1+k*k, 2*k*d, d*d-R*R);
211 double a = 1 + k * k;
212 double p = 2 * k * d;
213 double q = d * d - R * R;
214 double discriminant = p * p - 4 * a * q;
215 if (discriminant < 0) {
216 return 0.;
217 } else {
218 // solutions = (discriminant==0) ? one : two;
219 double x0 =
220 -0.5 * (p + (p > 0 ? sqrt(discriminant) : -sqrt(discriminant)));
221 first = x0 / a;
222 second = q / x0;
223 }
224 double t1 = (first - point1.x()) / direc.x();
225 double t2 = (second - point1.x()) / direc.x();
226 // the solutions in the 3D frame of the cylinder
227 Amg::Vector3D dist1raw(point1 + t1 * direc - globalHit);
228 Amg::Vector3D dist2raw(point1 + t2 * direc - globalHit);
229 // return the solution which is closer to Meas'Base's global coordinates
230 if (dist1raw.mag() < dist2raw.mag()) {
231 return t1;
232 } else {
233 return t2;
234 }
235 }
236 }
237};
238} // end of namespace
239
240#endif // TRKNIRVANA_MEASUREMENTBASECOMPARISONFUNCTION_H
241
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
static Double_t sp
static Double_t a
virtual double r() const override final
This method returns the radius.
Class for a CylinderSurface in the ATLAS detector.
virtual const CylinderBounds & bounds() const override final
This method returns the CylinderBounds by reference (NoBounds is not possible for cylinder)
Class for a DiscSurface in the ATLAS detector.
Definition DiscSurface.h:54
bool operator()(const Trk::MeasurementBase *one, const Trk::MeasurementBase *two) const
The comparison function defining in what case a Measurement is 'smaller' than a second one.
double pathIntersectWithLine(const Trk::PerigeeSurface &pgsf) const
double pathIntersectWithLine(const Trk::StraightLineSurface &lsf) const
MeasurementBaseComparisonFunction(const Amg::Vector3D &sp, const Amg::Vector3D &dir)
Full relation definition using a straight line propagation.
double pathIntersectWithCylinder(const Trk::CylinderSurface &csf, const Amg::Vector3D &globalHit) const
MeasurementBaseComparisonFunction & operator=(MeasurementBaseComparisonFunction &MCF)=default
MeasurementBaseComparisonFunction(MeasurementBaseComparisonFunction &&MCF)=default
MeasurementBaseComparisonFunction & operator=(MeasurementBaseComparisonFunction &&MCF)=default
MeasurementBaseComparisonFunction(const MeasurementBaseComparisonFunction &MCF)=default
double pathIntersectWithDisc(const Trk::DiscSurface &dsf) const
double pathIntersectWithPlane(const Trk::PlaneSurface &psf) const
This class is the pure abstract base class for all fittable tracking measurements.
Class describing the Line to which the Perigee refers to.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
const Amg::Vector3D & lineDirection() const
Special method for StraightLineSurface - provides the Line direction from cache: speedup.
Abstract Base Class for tracking surfaces.
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
SurfaceType
This enumerator simplifies the persistency & calculations,.
static const Amg::Vector3D s_zAxis(0, 0, 1)
global z Axis;