ATLAS Offline Software
Loading...
Searching...
No Matches
DiscSurface.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// 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
148// Out-of-line dtor.
150
153{
154 if (this != &dsf) {
156 m_bounds = dsf.m_bounds;
157 m_referencePoint.store(nullptr);
158 }
159 return *this;
160}
161
162bool
164{
165 // first check the type not to compare apples with oranges
166 if (sf.type()!=Trk::SurfaceType::Disc){
167 return false;
168 }
169 return (*this) == static_cast<const Trk::DiscSurface&>(sf);
170}
171
172/* Use the Surface as a ParametersBase constructor, from local parameters -
173 * charged */
176 double l1, double l2, double phi, double theta, double qop,
177 std::optional<AmgSymMatrix(5)> cov) const {
178 return std::make_unique<ParametersT<5, Charged, DiscSurface>>(
179 l1, l2, phi, theta, qop, *this, std::move(cov));
180}
181
185 const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
186 std::optional<AmgSymMatrix(5)> cov) const {
187 return std::make_unique<ParametersT<5, Charged, DiscSurface>>(
188 position, momentum, charge, *this, std::move(cov));
189}
190
195 double l1, double l2, double phi, double theta, double qop,
196 std::optional<AmgSymMatrix(5)> cov) const {
197 return std::make_unique<ParametersT<5, Neutral, DiscSurface>>(
198 l1, l2, phi, theta, qop, *this, std::move(cov));
199}
200
205 const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
206 std::optional<AmgSymMatrix(5)> cov) const {
207 return std::make_unique<ParametersT<5, Neutral, DiscSurface>>(
208 position, momentum, charge, *this, std::move(cov));
209}
210
211const Amg::Vector3D&
213{
214 if (!m_referencePoint) {
215 const Trk::DiscBounds* dbo =
216 dynamic_cast<const Trk::DiscBounds*>(&(bounds()));
217 if (dbo) {
218 double rMedium = bounds().r();
219 double phi = dbo->averagePhi();
220 Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.);
221 m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp));
222 } else {
223 const Trk::DiscTrapezoidalBounds* dtbo =
224 dynamic_cast<const Trk::DiscTrapezoidalBounds*>(&(bounds()));
225 // double rMedium = dtbo ? bounds().r() : dtbo->rCenter() ; //nonsense, or
226 // logic inverted?
227 double rMedium = bounds().r();
228 double phi = dtbo ? dtbo->averagePhi() : 0.;
229 Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.);
230 m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp));
231 }
232 }
233 return (*m_referencePoint);
234}
235
236// Avoid out-of-line Eigen calls
238void
240 const Amg::Vector3D&,
241 Amg::Vector3D& glopos) const
242{
243 // create the position in the local 3d frame
244 Amg::Vector3D loc3Dframe(locpos[Trk::locR] * cos(locpos[Trk::locPhi]),
245 locpos[Trk::locR] * sin(locpos[Trk::locPhi]),
246 0.);
247 // transport it to the globalframe
248 glopos = transform() * loc3Dframe;
249}
250
252bool
254 const Amg::Vector3D&,
255 Amg::Vector2D& locpos) const
256{
257 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopos);
258 locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi());
259 return (std::fabs(loc3Dframe.z()) <= s_onSurfaceTolerance);
260}
261
264 const Amg::Vector3D& dir,
265 bool forceDir,
266 Trk::BoundaryCheck bchk) const {
267 double denom = dir.dot(normal());
268 if (denom) {
269 double u = (normal().dot((center() - pos))) / (denom);
270 Amg::Vector3D intersectPoint(pos + u * dir);
271 // evaluate the intersection in terms of direction
272 bool isValid = forceDir ? (u > 0.) : true;
273 // evaluate (if necessary in terms of boundaries)
274 isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid;
275 // return the result
276 return Trk::Intersection(intersectPoint, u, isValid);
277 }
278 return Trk::Intersection(pos, 0., false);
279}
280
281#if defined(FLATTEN)
282// We compile this function with optimization, even in debug builds; otherwise,
283// the heavy use of Eigen makes it too slow. However, from here we may call
284// to out-of-line Eigen code that is linked from other DSOs; in that case,
285// it would not be optimized. Avoid this by forcing all Eigen code
286// to be inlined here if possible.
288#endif
289bool
291 const Trk::BoundaryCheck& bchk,
292 double tol1,
293 double tol2) const
294{
295 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopo);
296 if (std::abs(loc3Dframe.z()) > (s_onSurfaceTolerance + tol1)) {
297 return false;
298 }
299 return (bchk
300 ? bounds().inside(
301 Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()), tol1, tol2)
302 : true);
303}
304
308 const Amg::Vector3D& dir) const
309{
310 double tol = 0.001;
311
312 const Amg::Vector3D& C = center();
313 const Amg::Vector3D& N = normal();
314
315 double S = C.dot(N);
316 double b = S < 0. ? -1 : 1;
317 double d = (pos - C).dot(N); // distance to surface
318
319 double A = b * dir.dot(N);
320 if (A == 0.) { // direction parallel to surface
321 if (fabs(d) < tol) {
322 return {1, 0., true, 0.};
323 }
324 return {0, d, true, 0.};
325 }
326
327 double D = b * (S - (pos.dot(N))) / A;
328 return {1, d, true, D};
329}
330
333 const Amg::Vector3D& dir,
334 bool bound) const
335{
336 const Amg::Transform3D& T = transform();
337 const double Az[3] = { T(0, 2), T(1, 2), T(2, 2) };
338
339 // Transformation to cylinder system coordinates
340 //
341 const double dx = pos[0] - T(0, 3);
342 const double dy = pos[1] - T(1, 3);
343 const double dz = pos[2] - T(2, 3);
344 const double z = dx * Az[0] + dy * Az[1] + dz * Az[2];
345 const double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2];
346
347 // Step to surface
348 //
349 int ns = 0;
350 double s = 0.;
351 if (az != 0.) {
352 s = -z / az;
353 ns = 1;
354 }
355 double dist = std::abs(z);
356 if (!bound) {
357 return {ns, dist, true, s};
358 }
359
360 // Min distance to surface
361 //
362 const double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0);
363 const double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1);
364
365 Amg::Vector2D lp(sqrt(x * x + y * y), atan2(y, x));
366
367 double d = bounds().minDistance(lp);
368 if (d > 0.) {
369 dist = std::sqrt(dist * dist + d * d);
370 }
371
372 return {ns, dist, true, s};
373}
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...
virtual ~DiscSurface()
Destructor.
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