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
130// Out-of-line dtor.
132
133bool
135{
136 // first check the type not to compare apples with oranges
137 if (sf.type()!=Trk::SurfaceType::Plane){
138 return false;
139 }
140 return (*this) == static_cast<const Trk::PlaneSurface&>(sf);
141}
142
147 double l1,
148 double l2,
149 double phi,
150 double theta,
151 double qop,
152 std::optional<AmgSymMatrix(5)> cov) const
153{
154 return std::make_unique<ParametersT<5, Charged, PlaneSurface>>(
155 l1, l2, phi, theta, qop, *this, std::move(cov));
156}
157
161 const Amg::Vector3D& position,
162 const Amg::Vector3D& momentum,
163 double charge,
164 std::optional<AmgSymMatrix(5)> cov) const
165{
166 return std::make_unique<ParametersT<5, Charged, PlaneSurface>>(
167 position, momentum, charge, *this, std::move(cov));
168}
169
174 double l1,
175 double l2,
176 double phi,
177 double theta,
178 double oop,
179 std::optional<AmgSymMatrix(5)> cov) const
180{
181 return std::make_unique<ParametersT<5, Neutral, PlaneSurface>>(
182 l1, l2, phi, theta, oop, *this, std::move(cov));
183}
184
189 const Amg::Vector3D& position,
190 const Amg::Vector3D& momentum,
191 double charge,
192 std::optional<AmgSymMatrix(5)> cov) const
193{
194 return std::make_unique<ParametersT<5, Neutral, PlaneSurface>>(
195 position, momentum, charge, *this, std::move(cov));
196}
197
198// Avoid out-of-line Eigen calls
200void
202 const Amg::Vector3D&,
203 Amg::Vector3D& glopos) const
204{
205 Amg::Vector3D loc3Dframe(locpos[Trk::locX], locpos[Trk::locY], 0.);
206 glopos = transform() * loc3Dframe;
207}
208
209// Avoid out-of-line Eigen calls
211bool
213 const Amg::Vector3D&,
214 Amg::Vector2D& locpos) const {
215 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopos);
216 locpos = Amg::Vector2D(loc3Dframe.x(), loc3Dframe.y());
217 return (loc3Dframe.z() * loc3Dframe.z() <=
219}
220
223 const Amg::Vector3D& dir,
224 bool forceDir,
225 Trk::BoundaryCheck bchk) const {
226 double denom = dir.dot(normal());
227 if (denom) {
228 double u = (normal().dot((center() - pos))) / (denom);
229 Amg::Vector3D intersectPoint(pos + u * dir);
230 // evaluate the intersection in terms of direction
231 bool isValid = forceDir ? (u > 0.) : true;
232 // evaluate (if necessary in terms of boundaries)
233 isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid;
234 // return the result
235 return Trk::Intersection(intersectPoint, u, isValid);
236 }
237 return Trk::Intersection(pos, 0., false);
238}
239
240void
242{
243
244 CxxUtils::sincos scXZ(locdir.angleXZ());
245 CxxUtils::sincos scYZ(locdir.angleYZ());
246
247 double norm = 1. / std::sqrt(scYZ.cs * scYZ.cs * scXZ.sn * scXZ.sn + scYZ.sn * scYZ.sn);
248
249 // decide on the sign
250 double sign = (scXZ.sn < 0.) ? -1. : 1.;
251
252 // now calculate the GlobalDirection in the global frame
253 globdir =
254 transform().linear() *
255 Amg::Vector3D(sign * scXZ.cs * scYZ.sn * norm, sign * scXZ.sn * scYZ.cs * norm, sign * scXZ.sn * scYZ.sn * norm);
256}
257
258void
260{
261 // bring the global direction into the surface frame
262 Amg::Vector3D d(inverseTransformHelper().linear() * glodir);
263 ldir = Trk::LocalDirection(std::atan2(d.z(), d.x()), std::atan2(d.z(), d.y()));
264}
265
267bool
269 const Trk::BoundaryCheck& bchk,
270 double tol1, double tol2) const
271{
272 Amg::Vector3D loc3Dframe = inverseTransformMultHelper(glopo);
273 if (std::abs(loc3Dframe(2)) > (s_onSurfaceTolerance + tol1)){
274 return false;
275 }
276 return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe(0), loc3Dframe(1)), tol1, tol2) : true);
277}
278
282{
283 static const double tol = 0.001;
284
285 const Amg::Vector3D& N = normal();
286
287 const double d = (pos - center()).dot(N);
288
289 const double A = dir.dot(N); // ignore sign
290 if (A == 0.) { // direction parallel to surface
291 if (std::abs(d) < tol) {
292 return {1, 0., true, 0.};
293 }
294 return {0, d, true, 0.};
295
296 }
297
298 return {1, d, true, -d / A};
299}
300
303{
304 const Amg::Transform3D& T = transform();
305 double Az[3] = { T(0, 2), T(1, 2), T(2, 2) };
306
307 // Transformation to plane system coordinates
308 //
309 double dx = pos[0] - T(0, 3);
310 double dy = pos[1] - T(1, 3);
311 double dz = pos[2] - T(2, 3);
312 double z = dx * Az[0] + dy * Az[1] + dz * Az[2];
313 double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2];
314
315 // Step to surface
316 //
317 int ns = 0;
318 double s = 0.;
319 if (az != 0.) {
320 s = -z / az;
321 ns = 1;
322 }
323 double dist = std::abs(z);
324 if (!bound)
325 return {ns, std::abs(z), true, s};
326
327 // Min distance to surface
328 //
329 double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0);
330 double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1);
331
332 Amg::Vector2D lp(x, y);
333
334 double d = bounds().minDistance(lp);
335 if (d > 0.)
336 dist = std::sqrt(dist * dist + d * d);
337
338 return {ns, dist, true, s};
339}
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 ~PlaneSurface()
Destructor.
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