ATLAS Offline Software
Loading...
Searching...
No Matches
PerigeeSurface.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 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
74// assignment operator
77{
78 if (this != &pesf) {
81 }
82 return *this;
83}
84
85bool
87{
88 // first check the type not to compare apples with oranges
89 if (sf.type()!=Trk::SurfaceType::Perigee){
90 return false;
91 }
92 return (*this) == static_cast<const Trk::PerigeeSurface&>(sf);
93}
94
99 double l1,
100 double l2,
101 double phi,
102 double theta,
103 double qop,
104 std::optional<AmgSymMatrix(5)> cov) const
105{
106 return std::make_unique<ParametersT<5, Charged, PerigeeSurface>>(
107 l1, l2, phi, theta, qop, *this, std::move(cov));
108}
109
113 const Amg::Vector3D& position,
114 const Amg::Vector3D& momentum,
115 double charge,
116 std::optional<AmgSymMatrix(5)> cov) const
117{
118 return std::make_unique<ParametersT<5, Charged, PerigeeSurface>>(
119 position, momentum, charge, *this, std::move(cov));
120}
121
126 double l1,
127 double l2,
128 double phi,
129 double theta,
130 double qop,
131 std::optional<AmgSymMatrix(5)> cov) const
132{
133 return std::make_unique<ParametersT<5, Neutral, PerigeeSurface>>(
134 l1, l2, phi, theta, qop, *this, std::move(cov));
135}
136
141 const Amg::Vector3D& position,
142 const Amg::Vector3D& momentum,
143 double charge,
144 std::optional<AmgSymMatrix(5)> cov) const
145{
146 return std::make_unique<ParametersT<5, Neutral, PerigeeSurface>>(
147 position, momentum, charge, *this, std::move(cov));
148}
149
150// simple local to global - from LocalParameters /
153{
154 if (locpars.contains(Trk::phi0)) {
155 Amg::Vector3D loc3Dframe(-locpars[Trk::d0] * sin(locpars[Trk::phi0]),
156 locpars[Trk::d0] * cos(locpars[Trk::phi0]),
157 locpars[Trk::z0]);
158 return Amg::Vector3D(transform() * loc3Dframe);
159 }
160 return {0., 0., locpars[Trk::z0] + (center().z())};
161}
162
163// We compile this function with optimization, even in debug builds; otherwise,
164// the heavy use of Eigen makes it too slow. However, from here we may call
165// to out-of-line Eigen code that is linked from other DSOs; in that case,
166// it would not be optimized. Avoid this by forcing all Eigen code
167// to be inlined here if possible.
169// true local to global method/
170void
172 const Amg::Vector3D& glomom,
173 Amg::Vector3D& glopos) const
174{
175 // this is for a tilted perigee surface
177 // get the vector perpendicular to the momentum and the straw axis
178 Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom));
179 Amg::Vector3D locZinGlobal = transform() * Amg::Vector3D(0., 0., locpos[Trk::locZ]);
180 // transform zPosition into global coordinates and add locR * radiusAxis
181 glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR] * radiusAxisGlobal.normalized());
182 } else {
183 double phi = glomom.phi();
184 glopos[Amg::x] = -locpos[Trk::d0] * sin(phi);
185 glopos[Amg::y] = locpos[Trk::d0] * cos(phi);
186 glopos[Amg::z] = locpos[Trk::z0];
187 glopos += center();
188 }
189}
190
191// true local to global method - from LocalParameters /
194 const Amg::Vector3D& glomom) const
195{
197 Amg::Vector3D glopos = Amg::Vector3D(0., 0., 0.);
199 Amg::Vector2D(locpars[Trk::d0], locpars[Trk::z0]), glomom, glopos);
200 return glopos;
201 }
202 double phi = glomom.phi();
203 double x = -locpars[Trk::d0] * sin(phi) + center().x();
204 double y = locpars[Trk::d0] * cos(phi) + center().y();
205 double z = locpars[Trk::z0] + center().z();
206 return {x, y, z};
207}
208
209// true global to local method
210bool
212 const Amg::Vector3D& glomom,
213 Amg::Vector2D& locpos) const
214{
216 double d0 = perPos.perp();
217 double z0 = perPos.z();
218 // decide the sign of d0
219 d0 *= ((lineDirection().cross(glomom)).dot(perPos) < 0.0) ? -1.0 : 1.0;
220 locpos[Trk::d0] = d0;
221 locpos[Trk::z0] = z0;
222 return true;
223}
224
227 const Amg::Vector3D& dir,
228 bool forceDir,
229 Trk::BoundaryCheck) const {
230 // following nominclature found in header file and doxygen documentation
231 // line one is the straight track
232 const Amg::Vector3D& ma = pos;
233 const Amg::Vector3D& ea = dir;
234 // line two is the line surface
235 const Amg::Vector3D& mb = center();
236 const Amg::Vector3D& eb = lineDirection();
237 // now go ahead
238 Amg::Vector3D mab(mb - ma);
239 double eaTeb = ea.dot(eb);
240 double denom = 1 - eaTeb * eaTeb;
241 if (std::abs(denom) > 10e-7) {
242 double lambda0 = (mab.dot(ea) - mab.dot(eb) * eaTeb) / denom;
243 // evaluate the direction, bounds are always true for Perigee
244 bool isValid = forceDir ? (lambda0 > 0.) : true;
245 return Trk::Intersection((ma + lambda0 * ea), lambda0, isValid);
246 }
247 return Trk::Intersection(pos, 0., false);
248}
249
250// return the measurement frame - this is the frame where the covariance is defined
253{
255 // construct the measurement frame
256 const Amg::Vector3D& measY = lineDirection();
257 Amg::Vector3D measX(measY.cross(glomom).unit());
258 Amg::Vector3D measDepth(measX.cross(measY));
259 // assign the columnes
260 mFrame.col(0) = measX;
261 mFrame.col(1) = measY;
262 mFrame.col(2) = measDepth;
263 // return the rotation matrix
264 return mFrame;
265}
266
270{
271 const Amg::Vector3D& C = center();
272 Amg::Vector3D S(0., 0., 1.);
273
274 double D = dir.dot(S);
275 double A = (1. - D) * (1. + D);
276 if (A == 0.) {
277 return {1, pos.perp(), false, 0.};
278 }
279 double sol = (pos - C).dot(D * S - dir) / A;
280 return {1, pos.perp(), false, sol};
281}
282
285{
286 const Amg::Transform3D& T = transform();
287
288 double dx = pos[0] - T(3, 0);
289 double dy = pos[1] - T(3, 1);
290 double A = dir[0] * dir[0] + dir[1] * dir[1];
291
292 // Step to surface
293 //
294 if (A > 0.) {
295 return {1, 0., false, -(dir[0] * dx + dir[1] * dy) / A};
296 }
297 return {1, 0., false, 0.};
298}
299
300// overload of ostream operator
301MsgStream&
302Trk::PerigeeSurface::dump(MsgStream& sl) const
303{
304 sl << std::setiosflags(std::ios::fixed);
305 sl << std::setprecision(7);
306 sl << "Trk::PerigeeSurface:" << std::endl;
307 sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")";
308 sl << std::setprecision(-1);
309 return sl;
310}
311
312// overload of ostream operator
313std::ostream&
314Trk::PerigeeSurface::dump(std::ostream& sl) const
315{
316 sl << std::setiosflags(std::ios::fixed);
317 sl << std::setprecision(7);
318 sl << "Trk::PerigeeSurface:" << std::endl;
319 sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")";
320 sl << std::setprecision(-1);
321 return sl;
322}
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 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