ATLAS Offline Software
Loading...
Searching...
No Matches
PerigeeSurface.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// PerigeeSurface.cxx, (c) ATLAS Detector Software
8
9// Trk
11// Gaudi
12#include "GaudiKernel/MsgStream.h"
13// STD
14#include <iomanip>
15#include <iostream>
16// Eigen
18
20
25
27 : Surface()
29{
30 Amg::Transform3D transform (Amg::Translation3D(gp.x(), gp.y(), gp.z()));
31 Surface::m_transforms = std::make_unique<Transforms>(transform, gp, s_xAxis);
32}
33
35 : Surface() // default for base
37{
38
40 std::make_unique<Transforms>(tTransform, tTransform.translation(), s_xAxis);
41}
42
43#if defined(FLATTEN)
44// We compile this function with optimization, even in debug builds; otherwise,
45// the heavy use of Eigen makes it too slow. However, from here we may call
46// to out-of-line Eigen code that is linked from other DSOs; in that case,
47// it would not be optimized. Avoid this by forcing all Eigen code
48// to be inlined here if possible.
50#endif
52 : Surface(pesf)
54{
55 if (pesf.m_transforms) {
56 Surface::m_transforms = std::make_unique<Transforms>(
57 pesf.m_transforms->transform, pesf.m_transforms->center, s_xAxis);
58 }
59}
60
62 : Surface()
64{
65 if (pesf.m_transforms) {
66 Surface::m_transforms =
67 std::make_unique<Transforms>(shift * pesf.m_transforms->transform,
68 shift * pesf.m_transforms->center,
69 s_xAxis);
70 }
71}
72
73// Out-of-line dtor.
75
76// assignment operator
79{
80 if (this != &pesf) {
83 }
84 return *this;
85}
86
87bool
89{
90 // first check the type not to compare apples with oranges
91 if (sf.type()!=Trk::SurfaceType::Perigee){
92 return false;
93 }
94 return (*this) == static_cast<const Trk::PerigeeSurface&>(sf);
95}
96
101 double l1,
102 double l2,
103 double phi,
104 double theta,
105 double qop,
106 std::optional<AmgSymMatrix(5)> cov) const
107{
108 return std::make_unique<ParametersT<5, Charged, PerigeeSurface>>(
109 l1, l2, phi, theta, qop, *this, std::move(cov));
110}
111
115 const Amg::Vector3D& position,
116 const Amg::Vector3D& momentum,
117 double charge,
118 std::optional<AmgSymMatrix(5)> cov) const
119{
120 return std::make_unique<ParametersT<5, Charged, PerigeeSurface>>(
121 position, momentum, charge, *this, std::move(cov));
122}
123
128 double l1,
129 double l2,
130 double phi,
131 double theta,
132 double qop,
133 std::optional<AmgSymMatrix(5)> cov) const
134{
135 return std::make_unique<ParametersT<5, Neutral, PerigeeSurface>>(
136 l1, l2, phi, theta, qop, *this, std::move(cov));
137}
138
143 const Amg::Vector3D& position,
144 const Amg::Vector3D& momentum,
145 double charge,
146 std::optional<AmgSymMatrix(5)> cov) const
147{
148 return std::make_unique<ParametersT<5, Neutral, PerigeeSurface>>(
149 position, momentum, charge, *this, std::move(cov));
150}
151
152// simple local to global - from LocalParameters /
155{
156 if (locpars.contains(Trk::phi0)) {
157 Amg::Vector3D loc3Dframe(-locpars[Trk::d0] * sin(locpars[Trk::phi0]),
158 locpars[Trk::d0] * cos(locpars[Trk::phi0]),
159 locpars[Trk::z0]);
160 return Amg::Vector3D(transform() * loc3Dframe);
161 }
162 return {0., 0., locpars[Trk::z0] + (center().z())};
163}
164
165// We compile this function with optimization, even in debug builds; otherwise,
166// the heavy use of Eigen makes it too slow. However, from here we may call
167// to out-of-line Eigen code that is linked from other DSOs; in that case,
168// it would not be optimized. Avoid this by forcing all Eigen code
169// to be inlined here if possible.
171// true local to global method/
172void
174 const Amg::Vector3D& glomom,
175 Amg::Vector3D& glopos) const
176{
177 // this is for a tilted perigee surface
179 // get the vector perpendicular to the momentum and the straw axis
180 Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom));
181 Amg::Vector3D locZinGlobal = transform() * Amg::Vector3D(0., 0., locpos[Trk::locZ]);
182 // transform zPosition into global coordinates and add locR * radiusAxis
183 glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR] * radiusAxisGlobal.normalized());
184 } else {
185 double phi = glomom.phi();
186 glopos[Amg::x] = -locpos[Trk::d0] * sin(phi);
187 glopos[Amg::y] = locpos[Trk::d0] * cos(phi);
188 glopos[Amg::z] = locpos[Trk::z0];
189 glopos += center();
190 }
191}
192
193// true local to global method - from LocalParameters /
196 const Amg::Vector3D& glomom) const
197{
199 Amg::Vector3D glopos = Amg::Vector3D(0., 0., 0.);
201 Amg::Vector2D(locpars[Trk::d0], locpars[Trk::z0]), glomom, glopos);
202 return glopos;
203 }
204 double phi = glomom.phi();
205 double x = -locpars[Trk::d0] * sin(phi) + center().x();
206 double y = locpars[Trk::d0] * cos(phi) + center().y();
207 double z = locpars[Trk::z0] + center().z();
208 return {x, y, z};
209}
210
211// true global to local method
212bool
214 const Amg::Vector3D& glomom,
215 Amg::Vector2D& locpos) const
216{
218 double d0 = perPos.perp();
219 double z0 = perPos.z();
220 // decide the sign of d0
221 d0 *= ((lineDirection().cross(glomom)).dot(perPos) < 0.0) ? -1.0 : 1.0;
222 locpos[Trk::d0] = d0;
223 locpos[Trk::z0] = z0;
224 return true;
225}
226
229 const Amg::Vector3D& dir,
230 bool forceDir,
231 Trk::BoundaryCheck) const {
232 // following nominclature found in header file and doxygen documentation
233 // line one is the straight track
234 const Amg::Vector3D& ma = pos;
235 const Amg::Vector3D& ea = dir;
236 // line two is the line surface
237 const Amg::Vector3D& mb = center();
238 const Amg::Vector3D& eb = lineDirection();
239 // now go ahead
240 Amg::Vector3D mab(mb - ma);
241 double eaTeb = ea.dot(eb);
242 double denom = 1 - eaTeb * eaTeb;
243 if (std::abs(denom) > 10e-7) {
244 double lambda0 = (mab.dot(ea) - mab.dot(eb) * eaTeb) / denom;
245 // evaluate the direction, bounds are always true for Perigee
246 bool isValid = forceDir ? (lambda0 > 0.) : true;
247 return Trk::Intersection((ma + lambda0 * ea), lambda0, isValid);
248 }
249 return Trk::Intersection(pos, 0., false);
250}
251
252// return the measurement frame - this is the frame where the covariance is defined
255{
257 // construct the measurement frame
258 const Amg::Vector3D& measY = lineDirection();
259 Amg::Vector3D measX(measY.cross(glomom).unit());
260 Amg::Vector3D measDepth(measX.cross(measY));
261 // assign the columnes
262 mFrame.col(0) = measX;
263 mFrame.col(1) = measY;
264 mFrame.col(2) = measDepth;
265 // return the rotation matrix
266 return mFrame;
267}
268
272{
273 const Amg::Vector3D& C = center();
274 Amg::Vector3D S(0., 0., 1.);
275
276 double D = dir.dot(S);
277 double A = (1. - D) * (1. + D);
278 if (A == 0.) {
279 return {1, pos.perp(), false, 0.};
280 }
281 double sol = (pos - C).dot(D * S - dir) / A;
282 return {1, pos.perp(), false, sol};
283}
284
287{
288 const Amg::Transform3D& T = transform();
289
290 double dx = pos[0] - T(3, 0);
291 double dy = pos[1] - T(3, 1);
292 double A = dir[0] * dir[0] + dir[1] * dir[1];
293
294 // Step to surface
295 //
296 if (A > 0.) {
297 return {1, 0., false, -(dir[0] * dx + dir[1] * dy) / A};
298 }
299 return {1, 0., false, 0.};
300}
301
302// overload of ostream operator
303MsgStream&
304Trk::PerigeeSurface::dump(MsgStream& sl) const
305{
306 sl << std::setiosflags(std::ios::fixed);
307 sl << std::setprecision(7);
308 sl << "Trk::PerigeeSurface:" << std::endl;
309 sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")";
310 sl << std::setprecision(-1);
311 return sl;
312}
313
314// overload of ostream operator
315std::ostream&
316Trk::PerigeeSurface::dump(std::ostream& sl) const
317{
318 sl << std::setiosflags(std::ios::fixed);
319 sl << std::setprecision(7);
320 sl << "Trk::PerigeeSurface:" << std::endl;
321 sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")";
322 sl << std::setprecision(-1);
323 return sl;
324}
double charge(const T &p)
Definition AtlasPID.h:997
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
#define AmgSymMatrix(dim)
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
Access to distance solutions.
bool contains(ParamDefs par) const
The simple check for the clients whether the parameter is contained.
Bounds object for a boundless surface (...)
Definition NoBounds.h:30
Class describing the Line to which the Perigee refers to.
Amg::Vector3D localToGlobal(const LocalParameters &locpos) const
Local to global method: Take care that by just providing locR and locZ the global position cannot be ...
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
GlobalToLocal method without dynamic memory allocation - boolean checks if on surface.
virtual NeutralTrackParametersUniquePtr createUniqueNeutralParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - neutral.
CxxUtils::CachedValue< Amg::Vector3D > m_lineDirection
< data members cache of the line direction (speeds up)
const Amg::Vector3D & lineDirection() const
Special method for StraightLineSurface - provides the Line direction from cache: speedup.
virtual MsgStream & dump(MsgStream &sl) const override
Output Method for MsgStream.
PerigeeSurface()
Default Constructor - needed for persistency.
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir=false, Trk::BoundaryCheck bchk=false) const override final
fast straight line intersection schema - standard: provides closest intersection and (signed) path le...
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const override final
fast straight line distance evaluation to Surface
virtual Surface::ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - charged.
static const NoBounds s_perigeeBounds
PerigeeSurface & operator=(const PerigeeSurface &slsf)
Assignment operator.
virtual Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D &glopos, const Amg::Vector3D &glomom) const override final
Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perig...
virtual ~PerigeeSurface()
Destructor.
virtual bool operator==(const Surface &sf) const override
Equality operator.
Abstract Base Class for tracking surfaces.
std::unique_ptr< ParametersBase< 5, Trk::Charged > > ChargedTrackParametersUniquePtr
Unique ptr types.
Surface & operator=(const Surface &sf)
Definition Surface.cxx:91
Amg::Vector3D inverseTransformMultHelper(const Amg::Vector3D &glopos) const
Surface()
Default Constructor for inheriting classes.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
std::unique_ptr< Transforms > m_transforms
Unique Pointer to the Transforms struct.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
std::unique_ptr< ParametersBase< 5, Trk::Neutral > > NeutralTrackParametersUniquePtr
#define ATH_FLATTEN
struct color C
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
static const Amg::Vector3D s_xAxis(1, 0, 0)
global x Axis;
@ x
Definition ParamDefs.h:55
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ locR
Definition ParamDefs.h:44
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ y
Definition ParamDefs.h:56
@ phi
Definition ParamDefs.h:75
@ locZ
local cylindrical
Definition ParamDefs.h:42
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
Definition dot.py:1
hold the test vectors and ease the comparison