ATLAS Offline Software
Loading...
Searching...
No Matches
DiscSurface.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// DiscSurface.cxx, (c) ATLAS Detector Software
8
9// Trk
16// CxxUtils
18// Gaudi
19#include "GaudiKernel/MsgStream.h"
20// Eigen
22
24
25// default constructor
27 : Trk::Surface()
28 , m_bounds(nullptr)
29 , m_referencePoint(nullptr)
30{}
31
32// copy constructor
34 : Trk::Surface(dsf)
35 , m_bounds(dsf.m_bounds)
36 , m_referencePoint(nullptr)
37{}
38
39// copy constructor with shift
41 const Amg::Transform3D& transf)
42 : Trk::Surface(dsf, transf)
43 , m_bounds(dsf.m_bounds)
44 , m_referencePoint(nullptr)
45{}
46
47// construct a disc with full phi coverage
49 double rmin,
50 double rmax)
51 : Trk::Surface(htrans)
52 , m_bounds(std::make_shared<const Trk::DiscBounds>(rmin, rmax))
53 , m_referencePoint(nullptr)
54{}
55
56// construct a disc with given phi coverage
58 double rmin,
59 double rmax,
60 double hphisec)
61 : Trk::Surface(htrans)
62 , m_bounds(std::make_shared<Trk::DiscBounds>(rmin, rmax, hphisec))
63 , m_referencePoint(nullptr)
64{}
65
67 double minhalfx,
68 double maxhalfx,
69 double maxR,
70 double minR,
71 double avephi,
72 double stereo)
73 : Trk::Surface(htrans)
74 , m_bounds(std::make_shared<Trk::DiscTrapezoidalBounds>(minhalfx,
75 maxhalfx,
76 maxR,
77 minR,
78 avephi,
79 stereo))
80 , m_referencePoint(nullptr)
81{}
82
83// construct a disc with given bounds
85 std::shared_ptr<const Trk::DiscBounds> dbounds)
86 : Trk::Surface(htrans)
87 , m_bounds(std::move(dbounds))
88 , m_referencePoint(nullptr)
89{}
90
91// construct a disc with given bounds
93 std::shared_ptr<const Trk::DiscTrapezoidalBounds> dbounds)
94 : Trk::Surface(htrans)
95 , m_bounds(std::move(dbounds))
96 , m_referencePoint(nullptr)
97{}
98
100 std::shared_ptr<const Trk::AnnulusBoundsPC> annpcbounds)
101 : Trk::Surface(htrans),
102 m_bounds(std::move(annpcbounds)),
103 m_referencePoint(nullptr)
104{}
105
107 const Trk::AnnulusBounds& annbounds,
108 const TrkDetElementBase* detElem)
109 : Trk::Surface(htrans),
110 m_referencePoint(nullptr)
111{
112
113 if(detElem != nullptr) {
114 m_associatedDetElement = detElem;
116 }
117
118 // build AnnulusBoundsPC from XY AnnulusBounds
119 std::pair<AnnulusBoundsPC, double> res = AnnulusBoundsPC::fromCartesian(annbounds);
120 m_bounds = std::make_shared<AnnulusBoundsPC>(res.first);
121 double phiShift = res.second;
122 // construct shifted transform
123 // we get the necessary rotation from ::fromCartesian(), and we need to make
124 // the local coordinate system to be rotated correctly here
125 Amg::Vector2D origin2D = res.first.moduleOrigin();
126 Amg::Translation3D transl(Amg::Vector3D(origin2D.x(), origin2D.y(), 0));
127 Amg::Rotation3D rot(Amg::AngleAxis3D(-phiShift, Amg::Vector3D::UnitZ()));
128 Amg::Transform3D originTrf;
129 originTrf = transl * rot;
130
131 m_transforms->transform = m_transforms->transform * originTrf.inverse();
132}
133
134// construct a disc from a transform, bounds is not set.
136 : Trk::Surface(htrans)
137 , m_bounds(nullptr)
138 , m_referencePoint(nullptr)
139{}
140
141// construct form TrkDetElementBase
143 : Trk::Surface(detelement)
144 , m_bounds(nullptr)
145 , m_referencePoint(nullptr)
146{}
147
150{
151 if (this != &dsf) {
153 m_bounds = dsf.m_bounds;
154 m_referencePoint.store(nullptr);
155 }
156 return *this;
157}
158
159bool
161{
162 // first check the type not to compare apples with oranges
163 if (sf.type()!=Trk::SurfaceType::Disc){
164 return false;
165 }
166 return (*this) == static_cast<const Trk::DiscSurface&>(sf);
167}
168
169/* Use the Surface as a ParametersBase constructor, from local parameters -
170 * charged */
173 double l1, double l2, double phi, double theta, double qop,
174 std::optional<AmgSymMatrix(5)> cov) const {
175 return std::make_unique<ParametersT<5, Charged, DiscSurface>>(
176 l1, l2, phi, theta, qop, *this, std::move(cov));
177}
178
182 const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
183 std::optional<AmgSymMatrix(5)> cov) const {
184 return std::make_unique<ParametersT<5, Charged, DiscSurface>>(
185 position, momentum, charge, *this, std::move(cov));
186}
187
192 double l1, double l2, double phi, double theta, double qop,
193 std::optional<AmgSymMatrix(5)> cov) const {
194 return std::make_unique<ParametersT<5, Neutral, DiscSurface>>(
195 l1, l2, phi, theta, qop, *this, std::move(cov));
196}
197
202 const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
203 std::optional<AmgSymMatrix(5)> cov) const {
204 return std::make_unique<ParametersT<5, Neutral, DiscSurface>>(
205 position, momentum, charge, *this, std::move(cov));
206}
207
208const Amg::Vector3D&
210{
211 if (!m_referencePoint) {
212 const Trk::DiscBounds* dbo =
213 dynamic_cast<const Trk::DiscBounds*>(&(bounds()));
214 if (dbo) {
215 double rMedium = bounds().r();
216 double phi = dbo->averagePhi();
217 Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.);
218 m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp));
219 } else {
220 const Trk::DiscTrapezoidalBounds* dtbo =
221 dynamic_cast<const Trk::DiscTrapezoidalBounds*>(&(bounds()));
222 // double rMedium = dtbo ? bounds().r() : dtbo->rCenter() ; //nonsense, or
223 // logic inverted?
224 double rMedium = bounds().r();
225 double phi = dtbo ? dtbo->averagePhi() : 0.;
226 Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.);
227 m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp));
228 }
229 }
230 return (*m_referencePoint);
231}
232
233// Avoid out-of-line Eigen calls
235void
237 const Amg::Vector3D&,
238 Amg::Vector3D& glopos) const
239{
240 // create the position in the local 3d frame
241 Amg::Vector3D loc3Dframe(locpos[Trk::locR] * cos(locpos[Trk::locPhi]),
242 locpos[Trk::locR] * sin(locpos[Trk::locPhi]),
243 0.);
244 // transport it to the globalframe
245 glopos = transform() * loc3Dframe;
246}
247
249bool
251 const Amg::Vector3D&,
252 Amg::Vector2D& locpos) const
253{
254 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopos);
255 locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi());
256 return (std::fabs(loc3Dframe.z()) <= s_onSurfaceTolerance);
257}
258
261 const Amg::Vector3D& dir,
262 bool forceDir,
263 Trk::BoundaryCheck bchk) const {
264 double denom = dir.dot(normal());
265 if (denom) {
266 double u = (normal().dot((center() - pos))) / (denom);
267 Amg::Vector3D intersectPoint(pos + u * dir);
268 // evaluate the intersection in terms of direction
269 bool isValid = forceDir ? (u > 0.) : true;
270 // evaluate (if necessary in terms of boundaries)
271 isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid;
272 // return the result
273 return Trk::Intersection(intersectPoint, u, isValid);
274 }
275 return Trk::Intersection(pos, 0., false);
276}
277
278#if defined(FLATTEN)
279// We compile this function with optimization, even in debug builds; otherwise,
280// the heavy use of Eigen makes it too slow. However, from here we may call
281// to out-of-line Eigen code that is linked from other DSOs; in that case,
282// it would not be optimized. Avoid this by forcing all Eigen code
283// to be inlined here if possible.
285#endif
286bool
288 const Trk::BoundaryCheck& bchk,
289 double tol1,
290 double tol2) const
291{
292 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopo);
293 if (std::abs(loc3Dframe.z()) > (s_onSurfaceTolerance + tol1)) {
294 return false;
295 }
296 return (bchk
297 ? bounds().inside(
298 Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()), tol1, tol2)
299 : true);
300}
301
305 const Amg::Vector3D& dir) const
306{
307 double tol = 0.001;
308
309 const Amg::Vector3D& C = center();
310 const Amg::Vector3D& N = normal();
311
312 double S = C.dot(N);
313 double b = S < 0. ? -1 : 1;
314 double d = (pos - C).dot(N); // distance to surface
315
316 double A = b * dir.dot(N);
317 if (A == 0.) { // direction parallel to surface
318 if (fabs(d) < tol) {
319 return {1, 0., true, 0.};
320 }
321 return {0, d, true, 0.};
322 }
323
324 double D = b * (S - (pos.dot(N))) / A;
325 return {1, d, true, D};
326}
327
330 const Amg::Vector3D& dir,
331 bool bound) const
332{
333 const Amg::Transform3D& T = transform();
334 const double Az[3] = { T(0, 2), T(1, 2), T(2, 2) };
335
336 // Transformation to cylinder system coordinates
337 //
338 const double dx = pos[0] - T(0, 3);
339 const double dy = pos[1] - T(1, 3);
340 const double dz = pos[2] - T(2, 3);
341 const double z = dx * Az[0] + dy * Az[1] + dz * Az[2];
342 const double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2];
343
344 // Step to surface
345 //
346 int ns = 0;
347 double s = 0.;
348 if (az != 0.) {
349 s = -z / az;
350 ns = 1;
351 }
352 double dist = std::abs(z);
353 if (!bound) {
354 return {ns, dist, true, s};
355 }
356
357 // Min distance to surface
358 //
359 const double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0);
360 const double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1);
361
362 Amg::Vector2D lp(sqrt(x * x + y * y), atan2(y, x));
363
364 double d = bounds().minDistance(lp);
365 if (d > 0.) {
366 dist = std::sqrt(dist * dist + d * d);
367 }
368
369 return {ns, dist, true, s};
370}
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)
std::pair< std::vector< unsigned int >, bool > res
static std::pair< AnnulusBoundsPC, double > fromCartesian(const AnnulusBounds &annbo)
Static factory method to produce an instance of this class from the cartesian implementation.
Bounds for a annulus-like, planar Surface.
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
Class to describe the bounds for a planar DiscSurface.
Definition DiscBounds.h:44
double averagePhi() const
This method returns the average phi.
Class for a DiscSurface in the ATLAS detector.
Definition DiscSurface.h:54
virtual const Amg::Vector3D & globalReferencePoint() const override final
Returns a global reference point: For the Disc this is Where denote the r(), averagePhi() of the Bo...
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.
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override
Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation.
virtual bool isOnSurface(const Amg::Vector3D &glopo, const BoundaryCheck &bchk=true, double tol1=0., double tol2=0.) const override
This method returns true if the GlobalPosition is on the Surface for both, within or without check of...
DiscSurface()
Default Constructor.
CxxUtils::CachedUniquePtr< Amg::Vector3D > m_referencePoint
static member for boundless approach
DiscSurface & operator=(const DiscSurface &dsf)
Assignement operator.
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.
std::shared_ptr< const SurfaceBounds > m_bounds
reference Point on the Surface
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...
const SurfaceBounds & bounds() const override final
This method returns the bounds by reference.
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const override
fast straight line distance evaluation to Surface
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override
Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks ...
static const NoBounds s_boundless
virtual bool operator==(const Surface &sf) const override
Equality operator.
Class to describe the bounds for a planar DiscSurface.
double averagePhi() const
This method returns the average phi.
Access to distance solutions.
Bounds object for a boundless surface (...)
Definition NoBounds.h:30
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
static constexpr double s_onSurfaceTolerance
Tolerance for being on Surface.
const TrkDetElementBase * m_associatedDetElement
Not owning Pointer to the Detector Element.
Amg::Vector3D inverseTransformMultHelper(const Amg::Vector3D &glopos) const
Surface()
Default Constructor for inheriting classes.
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.
Identifier m_associatedDetElementId
Identifier to the Detector Element.
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
This is the base class for all tracking detector elements with read-out relevant information.
#define ATH_FLATTEN
struct color C
Eigen::AngleAxisd AngleAxis3D
Eigen::Quaternion< double > Rotation3D
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
Ensure that the ATLAS eigen extensions are properly loaded.
@ x
Definition ParamDefs.h:55
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ locR
Definition ParamDefs.h:44
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
@ theta
Definition ParamDefs.h:66
@ y
Definition ParamDefs.h:56
@ phi
Definition ParamDefs.h:75
@ locPhi
local polar
Definition ParamDefs.h:45
Definition dot.py:1
STL namespace.
hold the test vectors and ease the comparison