ATLAS Offline Software
GeoPrimitivesHelpers.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // GeoPrimitivesHelpers.h, (c) ATLAS Detector software
8 
9 #ifndef GEOPRIMITIVES_GEOPRIMITIVESHELPERS_H
10 #define GEOPRIMITIVES_GEOPRIMITIVESHELPERS_H
11 
14 #include "CxxUtils/sincos.h"
15 
16 #include "cmath"
17 
18 #include <vector>
19 #include <optional>
20 #include <set>
21 #include <iostream>
22 
23 
31 namespace Amg {
32 
33 
34 
35 using SetVector3D = std::set<Amg::Vector3D, Vector3DComparer>;
36 using SetVectorVector3D = std::set< std::vector< Amg::Vector3D>, VectorVector3DComparer>;
37 
38 
39 
41 inline double angle(const Amg::Vector3D& v1, const Amg::Vector3D& v2) {
42  const double dp = std::clamp(v1.dot(v2) / (v1.mag() * v2.mag()), -1. ,1.);
43  return std::acos(dp);
44 }
45 
46 
48 inline float distance2(const Amg::Vector3D& p1, const Amg::Vector3D& p2) {
49  float dx = p2.x()-p1.x(), dy = p2.y()-p1.y(), dz = p2.z()-p1.z();
50  return dx*dx + dy*dy + dz*dz;
51 }
52 
54 inline float distance(const Amg::Vector3D& p1, const Amg::Vector3D& p2) {
55  return std::sqrt( distance2(p1, p2) );
56 }
57 
58 
59 
60 
62 inline void setPhi(Amg::Vector3D& v, double phi) {
63  double xy = v.perp();
64  CxxUtils::sincos sc(phi);
65  v[0] = xy * sc.cs;
66  v[1] = xy * sc.sn;
67 }
68 
70 inline void setThetaPhi(Amg::Vector3D& v, double theta, double phi) {
71  double mag = v.mag();
72  CxxUtils::sincos sc(phi);
73  CxxUtils::sincos sct(theta);
74  v[0] = mag * sct.sn * sc.cs;
75  v[1] = mag * sct.sn * sc.sn;
76  v[2] = mag * sct.cs;
77 }
78 
80 inline void setRThetaPhi(Amg::Vector3D& v, double r, double theta, double phi) {
81  CxxUtils::sincos sc(phi);
82  CxxUtils::sincos sct(theta);
83  v[0] = r * sct.sn * sc.cs;
84  v[1] = r * sct.sn * sc.sn;
85  v[2] = r * sct.cs;
86 }
87 
89 inline void setTheta(Amg::Vector3D& v, double theta) {
90  setThetaPhi(v, theta, v.phi());
91 }
92 
94 inline void setPerp(Amg::Vector3D& v, double perp) {
95  double p = v.perp();
96  if (p != 0.0) {
97  double scale = perp / p;
98  v[0] *= scale;
99  v[1] *= scale;
100  }
101 }
102 
104 inline void setMag(Amg::Vector3D& v, double mag) {
105  double p = v.mag();
106  if (p != 0.0) {
107  double scale = mag / p;
108  v[0] *= scale;
109  v[1] *= scale;
110  v[2] *= scale;
111  }
112 }
113 inline double deltaPhi(const Amg::Vector3D& v1, const Amg::Vector3D& v2) {
114  double dphi = v2.phi() - v1.phi();
115  if (dphi > M_PI) {
116  dphi -= M_PI*2;
117  } else if (dphi <= -M_PI) {
118  dphi += M_PI*2;
119  }
120  return dphi;
121 }
122 inline double deltaR(const Amg::Vector3D& v1, const Amg::Vector3D& v2){
123  double a = v1.eta() - v2.eta();
124  double b = deltaPhi(v1,v2);
125  return sqrt(a*a + b*b);
126 }
127 
128 
129 
130 
131 
132 
136 inline void setVector3DCartesian(Amg::Vector3D& v1, double x1, double y1, double z1) { v1[0] = x1; v1[1] = y1; v1[2] = z1; }
140 inline double mag2Vector3D(const Amg::Vector3D& v1) { return v1.x()*v1.x() + v1.y()*v1.y() + v1.z()*v1.z(); }
144 inline double magVector3D(const Amg::Vector3D& v1) { return std::sqrt(mag2Vector3D(v1)); }
148 inline double rVector3D(const Amg::Vector3D& v1) { return magVector3D(v1); }
149 
157  Amg::Vector3D vect;
158  double vx = v.x(), vy = v.y(), vz = v.z();
159  setVector3DCartesian( vect,
160  tr(0,0)*vx + tr(0,1)*vy + tr(0,2)*vz + tr(0,3),
161  tr(1,0)*vx + tr(1,1)*vy + tr(1,2)*vz + tr(1,3),
162  tr(2,0)*vx + tr(2,1)*vy + tr(2,2)*vz + tr(2,3));
163  return vect;
164 }
165 
166 
167 
168 
169 /*
170  * the analogous to CLHEP HepGeom::Transform3D trans (localRot, theSurface.transform().translation());
171  */
173 {
174  Amg::Transform3D trans = Amg::Transform3D::Identity();
175  trans = trans * rot;
176  trans.translation() = transl_vec;
177  return trans;
178 }
179 
180 /*
181  * Replacing the CLHEP::HepRotation::getAngleAxis() functionality
182  *
183  * Note:
184  * CLHEP has a 'HepRotation::getAngleAxis()' function, e.g.:
185  * ---
186  * CLHEP::HepRotation rotation = transform.getRotation();
187  * CLHEP::Hep3Vector rotationAxis;
188  * double rotationAngle;
189  * rotation.getAngleAxis(rotationAngle,rotationAxis);
190  * ---
191  */
192 inline void getAngleAxisFromRotation(Amg::RotationMatrix3D& rotation, double& rotationAngle, Amg::Vector3D& rotationAxis)
193 {
194  rotationAngle = 0.;
195 
196  double xx = rotation(0,0);
197  double yy = rotation(1,1);
198  double zz = rotation(2,2);
199 
200  double cosa = 0.5 * (xx + yy + zz - 1);
201  double cosa1 = 1 - cosa;
202 
203  if (cosa1 <= 0) {
204  rotationAngle = 0;
205  rotationAxis = Amg::Vector3D(0,0,1);
206  }
207  else{
208  double x=0, y=0, z=0;
209  if (xx > cosa) x = std::sqrt((xx-cosa)/cosa1);
210  if (yy > cosa) y = std::sqrt((yy-cosa)/cosa1);
211  if (zz > cosa) z = std::sqrt((zz-cosa)/cosa1);
212  if (rotation(2,1) < rotation(1,2)) x = -x;
213  if (rotation(0,2) < rotation(2,0)) y = -y;
214  if (rotation(1,0) < rotation(0,1)) z = -z;
215  rotationAngle = (cosa < -1.) ? std::acos(-1.) : std::acos(cosa);
216  rotationAxis = Amg::Vector3D(x,y,z);
217  }
218 
219  return;
220 }
221 
226  return Amg::Vector3D(tr(0,3),tr(1,3),tr(2,3));
227 } // TODO: check! it's perhaps useless, you acn use the transform.translation() method
228 
229 
230 
238 {
239  AngleAxis3D t;
240  t = Eigen::AngleAxis<double>(angle,axis);
241 
242  Amg::Rotation3D rot;
243  rot = t;
244 
245  return rot;
246 }
247 
248 
253  Amg::Transform3D transf;
254  Amg::AngleAxis3D angleaxis(angle, Amg::Vector3D::UnitX());
255  transf = angleaxis;
256  return transf;
257 }
262  Amg::Transform3D transf;
263  Amg::AngleAxis3D angleaxis(angle, Amg::Vector3D::UnitY());
264  transf = angleaxis;
265  return transf;
266 }
271  Amg::Transform3D transf;
272  Amg::AngleAxis3D angleaxis(angle, Amg::Vector3D::UnitZ());
273  transf = angleaxis;
274  return transf;
275 }
277 inline Amg::Transform3D getTranslateX3D(const double X) {
278  return Amg::Transform3D{Amg::Translation3D{X * Amg::Vector3D::UnitX()}};
279 }
281 inline Amg::Transform3D getTranslateY3D(const double Y) {
282  return Amg::Transform3D{Amg::Translation3D{Y * Amg::Vector3D::UnitY()}};
283 }
285 inline Amg::Transform3D getTranslateZ3D(const double Z) {
286  return Amg::Transform3D{Amg::Translation3D{Z * Amg::Vector3D::UnitZ()}};
287 }
289 inline Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z) {
291 }
295 }
296 
297 
303 template<int N> double lineDistance(const AmgVector(N)& posA,
304  const AmgVector(N)& dirA,
305  const AmgVector(N)& posB,
306  const AmgVector(N)& dirB) {
307 
308  const double dirDots = dirA.dot(dirB);
309  const double divisor = (1. - dirDots * dirDots);
310  const AmgVector(N) AminusB = posA - posB;
311  if (std::abs(divisor) < std::numeric_limits<double>::epsilon()) {
312  const AmgVector(N) d = posA + dirA.dot(AminusB)*dirA;
313  return std::sqrt(d.dot(d));
314  }
315  const AmgVector(N) lineTravel = AminusB.dot(dirA) * dirA -
316  AminusB.dot(dirB) * dirB;
317  return std::sqrt(std::max(0., AminusB.dot(AminusB) - lineTravel.dot(lineTravel)) / divisor);
318 }
325 template <int N> std::optional<double> intersect(const AmgVector(N)& posA,
326  const AmgVector(N)& dirA,
327  const AmgVector(N)& posB,
328  const AmgVector(N)& dirB) {
337  const double dirDots = dirA.dot(dirB);
338  const double divisor = (1. - dirDots * dirDots);
340  if (std::abs(divisor) < std::numeric_limits<double>::epsilon()) return std::nullopt;
341  const AmgVector(N) AminusB = posA - posB;
342  return (AminusB.dot(dirB) - AminusB.dot(dirA) * dirDots) / divisor;
343 }
346 template <int N>
347 std::optional<double> intersect(const AmgVector(N)& pos,
348  const AmgVector(N)& dir,
349  const AmgVector(N)& planeNorm,
350  const double offset) {
354  const double normDot = planeNorm.dot(dir);
355  if (std::abs(normDot) < std::numeric_limits<double>::epsilon()) return std::nullopt;
356  return (offset - pos.dot(planeNorm)) / normDot;
357 }
358 
361 inline bool doesNotDeform(const Amg::Transform3D& trans) {
362  for (unsigned int d = 0; d < 3 ; ++d) {
363  const double defLength = Amg::Vector3D::Unit(d).dot(trans.linear() * Amg::Vector3D::Unit(d));
364  if (std::abs(defLength - 1.) > std::numeric_limits<float>::epsilon()) {
365  return false;
366  }
367  }
368  return true;
369 }
371 inline bool isIdentity(const Amg::Transform3D& trans) {
372  return doesNotDeform(trans) &&
373  trans.translation().mag() < std::numeric_limits<float>::epsilon();
374 }
375 
376 
377 } // end of Amg namespace
378 
379 #endif
beamspotman.r
def r
Definition: beamspotman.py:676
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:840
Amg::Rotation3D
Eigen::Quaternion< double > Rotation3D
Definition: GeoPrimitives.h:43
max
#define max(a, b)
Definition: cfImp.cxx:41
Amg::setMag
void setMag(Amg::Vector3D &v, double mag)
scales the vector length without changing the angles
Definition: GeoPrimitivesHelpers.h:104
PlotCalibFromCool.yy
yy
Definition: PlotCalibFromCool.py:714
Amg::angle
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Definition: GeoPrimitivesHelpers.h:41
perp
Scalar perp() const
perp method - perpenticular length
Definition: AmgMatrixBasePlugin.h:44
hist_file_dump.d
d
Definition: hist_file_dump.py:137
Amg::deltaPhi
double deltaPhi(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
Definition: GeoPrimitivesHelpers.h:113
Amg::getTranslateZ3D
Amg::Transform3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis
Definition: GeoPrimitivesHelpers.h:285
yodamerge_tmp.axis
list axis
Definition: yodamerge_tmp.py:241
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
Amg::y
@ y
Definition: GeoPrimitives.h:35
compute_lumi.divisor
divisor
Definition: compute_lumi.py:60
M_PI
#define M_PI
Definition: ActiveFraction.h:11
sincos.h
Helper to simultaneously calculate sin and cos of the same angle.
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
Amg::getTranslateY3D
Amg::Transform3D getTranslateY3D(const double Y)
: Returns a shift transformation along the y-axis
Definition: GeoPrimitivesHelpers.h:281
Amg::getAngleAxisFromRotation
void getAngleAxisFromRotation(Amg::RotationMatrix3D &rotation, double &rotationAngle, Amg::Vector3D &rotationAxis)
Definition: GeoPrimitivesHelpers.h:192
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
Amg::SetVectorVector3D
std::set< std::vector< Amg::Vector3D >, VectorVector3DComparer > SetVectorVector3D
Definition: GeoPrimitivesHelpers.h:36
Amg::setPhi
Amg::RotationMatrix3D setPhi(Amg::RotationMatrix3D mat, double angle, int convention=0)
Definition: EulerAnglesHelpers.h:102
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
Amg::rVector3D
double rVector3D(const Amg::Vector3D &v1)
Gets r-component in spherical coordinate system.
Definition: GeoPrimitivesHelpers.h:148
Amg::getTransformFromRotTransl
Amg::Transform3D getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec)
Definition: GeoPrimitivesHelpers.h:172
GeoPrimitives.h
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
Amg::z
@ z
Definition: GeoPrimitives.h:36
Amg::getRotateX3D
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
Definition: GeoPrimitivesHelpers.h:252
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
CxxUtils::sincos::cs
double cs
Definition: sincos.h:95
Amg::getTranslationVectorFromTransform
Amg::Vector3D getTranslationVectorFromTransform(const Amg::Transform3D &tr)
Get the Translation vector out of a Transformation.
Definition: GeoPrimitivesHelpers.h:225
Amg::getRotation3DfromAngleAxis
Amg::Rotation3D getRotation3DfromAngleAxis(double angle, Amg::Vector3D &axis)
get a AngleAxis from an angle and an axis.
Definition: GeoPrimitivesHelpers.h:237
xAOD::rotation
rotation
Definition: TrackSurface_v1.cxx:15
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
Amg::x
@ x
Definition: GeoPrimitives.h:34
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::doesNotDeform
bool doesNotDeform(const Amg::Transform3D &trans)
Checks whether the linear part of the transformation rotates or stetches any of the basis vectors.
Definition: GeoPrimitivesHelpers.h:361
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Amg::setVector3DCartesian
void setVector3DCartesian(Amg::Vector3D &v1, double x1, double y1, double z1)
Sets components in cartesian coordinate system.
Definition: GeoPrimitivesHelpers.h:136
Amg::isIdentity
bool isIdentity(const Amg::Transform3D &trans)
Checks whether the transformation is the Identity transformation.
Definition: GeoPrimitivesHelpers.h:371
beamspotman.dir
string dir
Definition: beamspotman.py:623
Amg::setPerp
void setPerp(Amg::Vector3D &v, double perp)
scales the vector in the xy plane without changing the z coordinate nor the angles
Definition: GeoPrimitivesHelpers.h:94
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
Amg
Definition of ATLAS Math & Geometry primitives (Amg)
Definition: AmgStringHelpers.h:19
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
Amg::setTheta
void setTheta(Amg::Vector3D &v, double theta)
sets the theta of a vector without changing phi nor the magnitude
Definition: GeoPrimitivesHelpers.h:89
Amg::lineDistance
double lineDistance(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the shortest distance between two lines posA: offset point of line A dirA: orientation of ...
Definition: GeoPrimitivesHelpers.h:303
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Amg::mag2Vector3D
double mag2Vector3D(const Amg::Vector3D &v1)
Gets magnitude squared of the vector.
Definition: GeoPrimitivesHelpers.h:140
CxxUtils::sincos::sn
double sn
Definition: sincos.h:92
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
python.PyAthena.v
v
Definition: PyAthena.py:154
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
Amg::deltaR
double deltaR(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
Definition: GeoPrimitivesHelpers.h:122
a
TList * a
Definition: liststreamerinfos.cxx:10
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point of closest approach of two lines.
Definition: GeoPrimitivesHelpers.h:325
Amg::RotationMatrix3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Definition: GeoPrimitives.h:49
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
Amg::setRThetaPhi
void setRThetaPhi(Amg::Vector3D &v, double r, double theta, double phi)
sets radius, the theta and phi angle of a vector.
Definition: GeoPrimitivesHelpers.h:80
GeoPrimitivesCompare.h
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
CxxUtils::sincos
Helper to simultaneously calculate sin and cos of the same angle.
Definition: sincos.h:76
Amg::AngleAxis3D
Eigen::AngleAxisd AngleAxis3D
Definition: GeoPrimitives.h:45
Amg::distance2
float distance2(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the squared distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:48
Amg::magVector3D
double magVector3D(const Amg::Vector3D &v1)
Gets magnitude of the vector.
Definition: GeoPrimitivesHelpers.h:144
Amg::SetVector3D
std::set< Amg::Vector3D, Vector3DComparer > SetVector3D
Definition: GeoPrimitivesHelpers.h:35
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
Amg::getTranslateX3D
Amg::Transform3D getTranslateX3D(const double X)
: Returns a shift transformation along the x-axis
Definition: GeoPrimitivesHelpers.h:277
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:26
Amg::setThetaPhi
void setThetaPhi(Amg::Vector3D &v, double theta, double phi)
sets the theta and phi angle of a vector without changing the magnitude
Definition: GeoPrimitivesHelpers.h:70
Amg::getTranslate3D
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Definition: GeoPrimitivesHelpers.h:289
Amg::VectorVector3DComparer
Definition: GeoPrimitivesCompare.h:58