ATLAS Offline Software
Loading...
Searching...
No Matches
TrackStateOnSurfaceComparisonFunction.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Trackstateonsurfacecomparisonfunction.h
7// Header file for struct TrackstateonSurfaceComparisonFunction
9// (c) ATLAS Detector software
11// Wolfgang.Liebig@cern.ch / Andreas.Salzburger@cern.ch / Martin.Siebel@CERN.ch
13
14
15#ifndef TRKNIRVANA_TSOSCOMPARISONFUNCTION_H
16#define TRKNIRVANA_TSOSCOMPARISONFUNCTION_H
17
18//Trk
23// extra-maths for cylinder intersections
29#include <cmath>
30//STL
31
32namespace Trk {
33
38 public:
39
42 : m_radius(std::abs(cradius)),
44 {}
45
50
56
57
60 bool
62 Amg::Vector3D gp1;
63 Amg::Vector3D gp2;
64 gp1.setZero();
65 gp2.setZero();
66 const Trk::Surface* surf1 = 0;
67 const Trk::Surface* surf2 = 0;
68 if ( ! ( one->trackParameters() || one->measurementOnTrack() ) ){
69 std::cout << "TrackStateOnSurfaceComparisonFunction: input TSOS one not sufficient" << std::endl;
70 return true;
71 }
72 if ( ! ( two->trackParameters() || two->measurementOnTrack() ) ){
73 std::cout << "TrackStateOnSurfaceComparisonFunction: input TSOS two not sufficient" << std::endl;
74 return false;
75 }
76 if (one->trackParameters()){
77 gp1 = one->trackParameters()->position();
78 surf1 = &one->trackParameters()->associatedSurface();
79 if (!surf1 && one->measurementOnTrack() ) surf1 = &(one->measurementOnTrack()->associatedSurface());
80 } else if (one->measurementOnTrack()){
81 gp1 = one->measurementOnTrack()->globalPosition();
82 surf1 = &(one->measurementOnTrack()->associatedSurface());
83 }
84 if (two->trackParameters()){
85 gp2 = two->trackParameters()->position();
86 surf2 = &two->trackParameters()->associatedSurface();
87 if (!surf2 && two->measurementOnTrack() ) surf2 = &(two->measurementOnTrack()->associatedSurface());
88 } else if (two->measurementOnTrack()) {
89 gp2 = two->measurementOnTrack()->globalPosition();
90 surf2 = &(two->measurementOnTrack()->associatedSurface());
91 }
92 // --- very simple case, check radial distances
93 if (m_mode == RADIAL_TO_ZERO) {
94 return ( std::abs(gp1.perp() - m_radius)< std::abs(gp2.perp() - m_radius) );
95 }
96 // --- simple case, just use global position distances
97 else if (m_mode == TO_GIVEN_RADIUS) {
98 return ( (gp1 - m_point).mag() < (gp2 - m_point).mag());
99 } else {// --- flexible sorting along a predicted direction
100 if ( ! ( surf1 && surf2 ) ){
101 std::cout << "TrackStateOnSurfaceComparisonFunction: surface missing" << std::endl;
102 return false;
103 }
104 double path1 = calculateAppropriatePath(surf1, gp1); //note: only cylinder needs
105 double path2 = calculateAppropriatePath(surf2, gp2); //the second param.
106 return path1 < path2;
107 }
108 }
109 private:
112 const Amg::Vector3D m_point{0.,0.,0.};
113 const Amg::Vector3D m_direction{0.,0.,0.};
114 const double m_radius{0.};
116
117 double
118 calculateAppropriatePath( const Trk::Surface* pSurface, const Amg::Vector3D gp) const{
119 double path{0.};
120 switch (pSurface->type()){
122 path = pathIntersectWithPlane(static_cast <const Trk::PlaneSurface*>(pSurface));
123 break;
125 path = pathIntersectWithLine(static_cast <const Trk::StraightLineSurface*>(pSurface));
126 break;
128 path = pathIntersectWithDisc(static_cast <const Trk::DiscSurface*>(pSurface));
129 break;
131 path = pathIntersectWithCylinder(static_cast <const Trk::CylinderSurface*>(pSurface), gp);
132 break;
134 path = pathIntersectWithLine(static_cast <const Trk::PerigeeSurface*>(pSurface));
135 break;
136 default:
137 std::cout << "TrackStateOnSurfaceComparisonFunction: surface type error" << std::endl;
138 }
139 return path;
140 }
141
142
143 double
145 double denom = m_direction.dot(psf->normal()); // c++ can be unreadable
146 return denom ?psf->normal().dot(psf->center() - m_point)/denom :
147 denom ;
148 }
149
150 double
152 Amg::Vector3D dirWire(lsf->transform().rotation().col(2).unit());
153 Amg::Vector3D trackToWire(lsf->center() - m_point);
154 double parallelity = m_direction.dot(dirWire);
155 double denom = 1 - parallelity*parallelity;
156 return (std::abs(denom)>10e-7) ?
157 (trackToWire.dot(m_direction)
158 - trackToWire.dot(dirWire)*parallelity)/denom :
159 0. ;
160 }
161
162 double
164 Amg::Vector3D trackToWire(pgsf->center() - m_point);
165 double parallelity = m_direction.dot(Trk::s_zAxis);
166 double denom = 1 - parallelity*parallelity;
167 return (std::abs(denom)>10e-7) ?
168 (trackToWire.dot(m_direction)- trackToWire.dot(Trk::s_zAxis) * parallelity)/denom :
169 0.;
170 }
171
172 double
174 double denom = m_direction.dot(dsf->normal());
175 return denom ? dsf->normal().dot(dsf->center() - m_point)/denom :
176 denom;
177 }
178
179 double
181 const Amg::Vector3D& globalHit) const{
182 // --- code from TrkExSlPropagator/LineCylinderIntersection.cxx
183 // get the rotation by reference
184 const Amg::Transform3D& locTrans = csf->transform();
185 // take two points of line and calculate them to the 3D frame of the cylinder
186 Amg::Vector3D point1(locTrans.inverse() * m_point);
187 Amg::Vector3D point2raw = m_point + m_direction;
188 Amg::Vector3D point2(locTrans.inverse() * point2raw); // do it in two steps - CLHEP stability
189 // new direction in 3D frame of cylinder
190 Amg::Vector3D direc((point2 - point1).unit());
191 if (!direc.x()){
192 return 0.;
193 } else {
194 // get line and circle constants
195 double k = (direc.y())/(direc.x());
196 double d = (point2.x()*point1.y() - point1.x()*point2.y())/(point2.x() - point1.x());
197 double R = csf->bounds().r();
198 double first = 0.;
199 double second= 0.;
200
201 // and solve the quadratic equation Trk::RealQuadraticEquation pquad(1+k*k, 2*k*d, d*d-R*R);
202 double a = 1 + k*k;
203 double p = 2*k*d;
204 double q = d*d - R*R;
205 double discriminant = p*p - 4*a*q;
206 if (discriminant<0) {
207 return 0.;
208 } else {
209 // solutions = (discriminant==0) ? one : two;
210 double x0 = -0.5*(p + (p>0 ? std::sqrt(discriminant) : -std::sqrt(discriminant)));
211 first = x0/a;
212 second = q/x0;
213 }
214 double t1 = (first - point1.x())/direc.x();
215 double t2 = (second - point1.x())/direc.x();
216 // the solutions in the 3D frame of the cylinder
217 Amg::Vector3D dist1raw(point1 + t1 * direc - globalHit);
218 Amg::Vector3D dist2raw(point1 + t2 * direc - globalHit);
219 // return the solution which is closer to Meas'Base's global coordinates
220 if ( dist1raw.mag() < dist2raw.mag() ) {
221 return t1; // FIXME - wrong line parameterisation
222 } else {
223 return t2;
224 }
225 }
226 }
227 };
228
229} // end of namespace
230
231#endif //TRKNIRVANA_TSOSCOMPARISONFUNCTION_H
232
Scalar mag() const
mag method
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
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...
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.
double pathIntersectWithPlane(const Trk::PlaneSurface *psf) const
TrackStateOnSurfaceComparisonFunction(double cradius)
Default Constructor, using a given radius.
double pathIntersectWithCylinder(const Trk::CylinderSurface *csf, const Amg::Vector3D &globalHit) const
double pathIntersectWithLine(const Trk::StraightLineSurface *lsf) const
double calculateAppropriatePath(const Trk::Surface *pSurface, const Amg::Vector3D gp) const
double pathIntersectWithLine(const Trk::PerigeeSurface *pgsf) const
TrackStateOnSurfaceComparisonFunction(const Amg::Vector3D &dir)
Simple relation definition using a 3d distance to the reference point.
TrackStateOnSurfaceComparisonFunction(const Amg::Vector3D &sp, const Amg::Vector3D &dir)
Full relation definition using a straight line propagation.
bool operator()(const Trk::TrackStateOnSurface *one, const Trk::TrackStateOnSurface *two) const
The comparison function defining in what case a PRD is 'smaller' than a second one.
double pathIntersectWithDisc(const Trk::DiscSurface *dsf) const
represents the track state (measurement, material, fit parameters and quality) at a surface.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
static const Amg::Vector3D s_zAxis(0, 0, 1)
global z Axis;
STL namespace.