ATLAS Offline Software
Loading...
Searching...
No Matches
PlaneSurface.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// PlaneSurface.cxx, (c) ATLAS Detector Software
8
9// Trk
21// Identifier
22#include "Identifier/Identifier.h"
23// Gaudi
24#include "GaudiKernel/MsgStream.h"
25//CxxUtils
26#include "CxxUtils/sincos.h"
28// STD
29#include <iomanip>
30#include <iostream>
31#include <cmath>
32
34
35// default constructor
40
41
42// copy constructor with shift
44 : Trk::Surface(psf, transf)
45 , m_bounds(psf.m_bounds)
46{}
47
48// We compile this function with optimization, even in debug builds; otherwise,
49// the heavy use of Eigen makes it too slow. However, from here we may call
50// to out-of-line Eigen code that is linked from other DSOs; in that case,
51// it would not be optimized. Avoid this by forcing all Eigen code
52// to be inlined here if possible.
54// constructor from CurvilinearUVT
56 : Trk::Surface()
57 , m_bounds(nullptr) // curvilinear surfaces are boundless
58{
59 Amg::Translation3D curvilinearTranslation(position.x(), position.y(), position.z());
60 // create the rotation
61 Amg::RotationMatrix3D curvilinearRotation;
62 curvilinearRotation.col(0) = curvUVT.curvU();
63 curvilinearRotation.col(1) = curvUVT.curvV();
64 curvilinearRotation.col(2) = curvUVT.curvT();
66 transform = curvilinearRotation;
67 transform.pretranslate(position);
68 Trk::Surface::m_transforms = std::make_unique<Transforms>(transform);
69}
70
71// construct form TrkDetElementBase
73 : Trk::Surface(detelement)
74 , m_bounds(nullptr)
75{
76 Trk::Surface::m_transforms = std::make_unique<Transforms>(transf);
77}
78
79// construct form TrkDetElementBase
81 : Trk::Surface(detelement)
82 , m_bounds(nullptr)
83{
84 //
85}
86
87// construct from SiDetectorElement
89 const Identifier& id,
90 const Amg::Transform3D & transf)
91 : Trk::Surface(detelement, id)
92 , m_bounds(nullptr)
93{
94 Trk::Surface::m_transforms = std::make_unique<Transforms>(transf);
95}
96
97// construct from SiDetectorElement
99 const Identifier& id)
100 : Trk::Surface(detelement, id)
101 , m_bounds(nullptr)
102{
103 //
104}
105
106// construct planar surface without bounds
108 : Trk::Surface(htrans)
109 , m_bounds(nullptr)
110{}
111
112// construct rectangle module
113Trk::PlaneSurface::PlaneSurface(const Amg::Transform3D & htrans, double halephi, double haleta)
114 : Trk::Surface(htrans)
115 , m_bounds(std::make_shared<const Trk::RectangleBounds>(halephi, haleta))
116{}
117
118// construct trapezoidal module with parameters
119Trk::PlaneSurface::PlaneSurface(const Amg::Transform3D & htrans, double minhalephi, double maxhalephi, double haleta)
120 : Trk::Surface(htrans)
121 , m_bounds(std::make_shared<const Trk::TrapezoidBounds>(minhalephi, maxhalephi, haleta))
122{}
123
124// construct module with shared boundaries
126 const Amg::Transform3D & htrans,
127 std::shared_ptr<const Trk::SurfaceBounds> tbounds)
128 : Trk::Surface(htrans), m_bounds(std::move(tbounds)) {}
129
130bool
132{
133 // first check the type not to compare apples with oranges
134 if (sf.type()!=Trk::SurfaceType::Plane){
135 return false;
136 }
137 return (*this) == static_cast<const Trk::PlaneSurface&>(sf);
138}
139
144 double l1,
145 double l2,
146 double phi,
147 double theta,
148 double qop,
149 std::optional<AmgSymMatrix(5)> cov) const
150{
151 return std::make_unique<ParametersT<5, Charged, PlaneSurface>>(
152 l1, l2, phi, theta, qop, *this, std::move(cov));
153}
154
158 const Amg::Vector3D& position,
159 const Amg::Vector3D& momentum,
160 double charge,
161 std::optional<AmgSymMatrix(5)> cov) const
162{
163 return std::make_unique<ParametersT<5, Charged, PlaneSurface>>(
164 position, momentum, charge, *this, std::move(cov));
165}
166
171 double l1,
172 double l2,
173 double phi,
174 double theta,
175 double oop,
176 std::optional<AmgSymMatrix(5)> cov) const
177{
178 return std::make_unique<ParametersT<5, Neutral, PlaneSurface>>(
179 l1, l2, phi, theta, oop, *this, std::move(cov));
180}
181
186 const Amg::Vector3D& position,
187 const Amg::Vector3D& momentum,
188 double charge,
189 std::optional<AmgSymMatrix(5)> cov) const
190{
191 return std::make_unique<ParametersT<5, Neutral, PlaneSurface>>(
192 position, momentum, charge, *this, std::move(cov));
193}
194
195// Avoid out-of-line Eigen calls
197void
199 const Amg::Vector3D&,
200 Amg::Vector3D& glopos) const
201{
202 Amg::Vector3D loc3Dframe(locpos[Trk::locX], locpos[Trk::locY], 0.);
203 glopos = transform() * loc3Dframe;
204}
205
206// Avoid out-of-line Eigen calls
208bool
210 const Amg::Vector3D&,
211 Amg::Vector2D& locpos) const {
212 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopos);
213 locpos = Amg::Vector2D(loc3Dframe.x(), loc3Dframe.y());
214 return (loc3Dframe.z() * loc3Dframe.z() <=
216}
217
220 const Amg::Vector3D& dir,
221 bool forceDir,
222 Trk::BoundaryCheck bchk) const {
223 double denom = dir.dot(normal());
224 if (denom) {
225 double u = (normal().dot((center() - pos))) / (denom);
226 Amg::Vector3D intersectPoint(pos + u * dir);
227 // evaluate the intersection in terms of direction
228 bool isValid = forceDir ? (u > 0.) : true;
229 // evaluate (if necessary in terms of boundaries)
230 isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid;
231 // return the result
232 return Trk::Intersection(intersectPoint, u, isValid);
233 }
234 return Trk::Intersection(pos, 0., false);
235}
236
237void
239{
240
241 CxxUtils::sincos scXZ(locdir.angleXZ());
242 CxxUtils::sincos scYZ(locdir.angleYZ());
243
244 double norm = 1. / std::sqrt(scYZ.cs * scYZ.cs * scXZ.sn * scXZ.sn + scYZ.sn * scYZ.sn);
245
246 // decide on the sign
247 double sign = (scXZ.sn < 0.) ? -1. : 1.;
248
249 // now calculate the GlobalDirection in the global frame
250 globdir =
251 transform().linear() *
252 Amg::Vector3D(sign * scXZ.cs * scYZ.sn * norm, sign * scXZ.sn * scYZ.cs * norm, sign * scXZ.sn * scYZ.sn * norm);
253}
254
255void
257{
258 // bring the global direction into the surface frame
259 Amg::Vector3D d(inverseTransformHelper().linear() * glodir);
260 ldir = Trk::LocalDirection(std::atan2(d.z(), d.x()), std::atan2(d.z(), d.y()));
261}
262
264bool
266 const Trk::BoundaryCheck& bchk,
267 double tol1, double tol2) const
268{
269 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopo);
270 if (std::abs(loc3Dframe(2)) > (s_onSurfaceTolerance + tol1)){
271 return false;
272 }
273 return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe(0), loc3Dframe(1)), tol1, tol2) : true);
274}
275
279{
280 static const double tol = 0.001;
281
282 const Amg::Vector3D& N = normal();
283
284 const double d = (pos - center()).dot(N);
285
286 const double A = dir.dot(N); // ignore sign
287 if (A == 0.) { // direction parallel to surface
288 if (std::abs(d) < tol) {
289 return {1, 0., true, 0.};
290 }
291 return {0, d, true, 0.};
292
293 }
294
295 return {1, d, true, -d / A};
296}
297
300{
301 const Amg::Transform3D& T = transform();
302 double Az[3] = { T(0, 2), T(1, 2), T(2, 2) };
303
304 // Transformation to plane system coordinates
305 //
306 double dx = pos[0] - T(0, 3);
307 double dy = pos[1] - T(1, 3);
308 double dz = pos[2] - T(2, 3);
309 double z = dx * Az[0] + dy * Az[1] + dz * Az[2];
310 double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2];
311
312 // Step to surface
313 //
314 int ns = 0;
315 double s = 0.;
316 if (az != 0.) {
317 s = -z / az;
318 ns = 1;
319 }
320 double dist = std::abs(z);
321 if (!bound)
322 return {ns, std::abs(z), true, s};
323
324 // Min distance to surface
325 //
326 double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0);
327 double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1);
328
329 Amg::Vector2D lp(x, y);
330
331 double d = bounds().minDistance(lp);
332 if (d > 0.)
333 dist = std::sqrt(dist * dist + d * d);
334
335 return {ns, dist, true, s};
336}
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)
int sign(int a)
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
simple class that constructs the curvilinear vectors curvU and curvV from a given momentum direction ...
const Amg::Vector3D & curvU() const
Access methods.
const Amg::Vector3D & curvT() const
const Amg::Vector3D & curvV() const
Access to distance solutions.
represents the three-dimensional global direction with respect to a planar surface frame.
double angleXZ() const
access method for angle of local XZ projection
double angleYZ() const
access method for angle of local YZ projection
Bounds object for a boundless surface (...)
Definition NoBounds.h:30
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
void localToGlobalDirection(const Trk::LocalDirection &locdir, Amg::Vector3D &globdir) const
This method transforms a local direction wrt the plane to a global direction.
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const override final
fast straight line distance evaluation to Surface
virtual NeutralTrackParametersUniquePtr createUniqueNeutralParameters(double l1, double l2, double phi, double theta, double oop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - neutral.
virtual bool isOnSurface(const Amg::Vector3D &glopo, const BoundaryCheck &bchk=true, double tol1=0., double tol2=0.) const override final
This method returns true if the GlobalPosition is on the Surface for both, within or without check of...
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 final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
static const NoBounds s_boundless
PlaneSurface()
Default Constructor - needed for persistency.
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir, Trk::BoundaryCheck bchk) const override final
fast straight line intersection schema - standard: provides closest intersection and (signed) path le...
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
virtual bool operator==(const Surface &sf) const override
Equality operator.
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
std::shared_ptr< const SurfaceBounds > m_bounds
bounds (shared)
virtual const SurfaceBounds & bounds() const override final
This method returns the bounds by reference, static NoBounds in case of no boundaries.
Bounds for a rectangular, planar surface.
Abstract Base Class for tracking surfaces.
Amg::Transform3D inverseTransformHelper() const
Helper method to factorize in one place common operations calculate inverse transofrm and multiply wi...
std::unique_ptr< ParametersBase< 5, Trk::Charged > > ChargedTrackParametersUniquePtr
Unique ptr types.
static constexpr double s_onSurfaceTolerance
Tolerance for being on Surface.
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.
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
Bounds for a trapezoidal, planar Surface.
This is the base class for all tracking detector elements with read-out relevant information.
#define ATH_FLATTEN
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
Ensure that the ATLAS eigen extensions are properly loaded.
@ locY
local cartesian
Definition ParamDefs.h:38
@ x
Definition ParamDefs.h:55
@ locX
Definition ParamDefs.h:37
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
@ theta
Definition ParamDefs.h:66
@ y
Definition ParamDefs.h:56
@ phi
Definition ParamDefs.h:75
Definition dot.py:1
STL namespace.
Helper to simultaneously calculate sin and cos of the same angle.
hold the test vectors and ease the comparison
Helper to simultaneously calculate sin and cos of the same angle.
Definition sincos.h:39