ATLAS Offline Software
ConeSurface.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // ConeSurface.cxx, (c) ATLAS Detector Software
8 
9 // Trk
12 // Gaudi
13 #include "GaudiKernel/MsgStream.h"
14 //CxxUtils
15 #include "CxxUtils/inline_hints.h"
16 // STD
17 #include <cassert>
18 
19 // default constructor
21  : Trk::Surface()
22  , m_bounds(nullptr)
23  , m_referencePoint(nullptr)
24  , m_rotSymmetryAxis(nullptr)
25 {}
26 
27 // copy constructor
29  : Trk::Surface(csf)
30  , m_bounds(csf.m_bounds)
31  , m_referencePoint(nullptr)
32  , m_rotSymmetryAxis(nullptr)
33 {}
34 
35 // copy constructor with shift
37  const Amg::Transform3D& transf)
38  : Trk::Surface(csf, transf)
39  , m_bounds(csf.m_bounds)
40  , m_referencePoint(nullptr)
41  , m_rotSymmetryAxis(nullptr)
42 {}
43 
44 // constructor by opening angle and whether its symmetric or a single cone
46  double alpha,
47  bool symmetric)
48  : Trk::Surface(htrans)
49  , m_bounds(std::make_shared<Trk::ConeBounds>(alpha, symmetric))
50  , m_referencePoint(nullptr)
51  , m_rotSymmetryAxis(nullptr)
52 {}
53 
54 // constructor by opening angle and its z values
56  double alpha,
57  double zmin,
58  double zmax,
59  double halfPhi)
60  : Trk::Surface(htrans)
61  , m_bounds(std::make_shared<Trk::ConeBounds>(alpha, zmin, zmax, halfPhi))
62  , m_referencePoint(nullptr)
63  , m_rotSymmetryAxis(nullptr)
64 {}
65 
66 // constructor by ConeBounds
68  Trk::ConeBounds* cbounds)
69  : Trk::Surface(htrans)
70  , m_bounds(cbounds)
71  , m_referencePoint(nullptr)
72  , m_rotSymmetryAxis(nullptr)
73 {
74  assert(cbounds);
75 }
76 
77 // constructor from transform, bounds not set.
79  : Trk::Surface(htrans)
80  , m_bounds(nullptr)
81  , m_referencePoint(nullptr)
82  , m_rotSymmetryAxis(nullptr)
83 {}
84 
87 {
88  if (this != &csf) {
90  m_bounds = csf.m_bounds;
91  m_referencePoint.store(nullptr);
92  m_rotSymmetryAxis.store(nullptr);
93  }
94  return *this;
95 }
96 
101  double l1, double l2, double phi, double theta, double qop,
102  std::optional<AmgSymMatrix(5)> cov) const {
103  return std::make_unique<ParametersT<5, Charged, ConeSurface>>(
104  l1, l2, phi, theta, qop, *this, std::move(cov));
105 }
110  const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
111  std::optional<AmgSymMatrix(5)> cov) const {
112  return std::make_unique<ParametersT<5, Charged, ConeSurface>>(
113  position, momentum, charge, *this, std::move(cov));
114 }
115 
120  double l1, double l2, double phi, double theta, double qop,
121  std::optional<AmgSymMatrix(5)> cov) const {
122  return std::make_unique<ParametersT<5, Neutral, ConeSurface>>(
123  l1, l2, phi, theta, qop, *this, std::move(cov));
124 }
125 
130  const Amg::Vector3D& position, const Amg::Vector3D& momentum, double charge,
131  std::optional<AmgSymMatrix(5)> cov) const {
132  return std::make_unique<ParametersT<5, Neutral, ConeSurface>>(
133  position, momentum, charge, *this, std::move(cov));
134 }
135 
136 // TODO: is the 0 always the cone center?
137 const Amg::Vector3D&
139 {
140  if (!m_referencePoint) {
141  // this is what was in cylinder
142  // double rMedium = bounds().r();
143  // double phi = bounds().averagePhi();
144  // Trk::GlobalPosition gp(rMedium*cos(phi), rMedium*sin(phi), 0.);
145  Amg::Vector3D gp(0., 0., 0.);
146  m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp));
147  }
148  return (*m_referencePoint);
149 }
150 
151 bool
153 {
154  // first check the type not to compare apples with oranges
155  if (sf.type()!=Trk::SurfaceType::Cone){
156  return false;
157  }
158  return (*this) == static_cast<const Trk::ConeSurface&>(sf);
159 }
160 
161 const Amg::Vector3D&
163 {
164  if (!m_rotSymmetryAxis) {
166  m_rotSymmetryAxis.set(std::make_unique<Amg::Vector3D>(zAxis));
167  }
168  return (*m_rotSymmetryAxis);
169 }
170 
171 // return the measurement frame: it's the tangential plane
174 {
175  Amg::RotationMatrix3D mFrame;
176  // construct the measurement frame
177  Amg::Vector3D measY(transform().rotation().col(2)); // measured Y is the z axis
178  Amg::Vector3D measDepth =
179  Amg::Vector3D(pos.x(), pos.y(), 0.).unit(); // measured z is the position transverse normalized
180  Amg::Vector3D measX(measY.cross(measDepth).unit()); // measured X is what comoes out of it
181  // the columnes
182  mFrame.col(0) = measX;
183  mFrame.col(1) = measY;
184  mFrame.col(2) = measDepth;
185  // return the rotation matrix
187  // return it
188  return mFrame;
189 }
190 // Avoid out-of-line-eigen calls
192 void
194 {
195  // create the position in the local 3d frame
196  double r = locpos[Trk::locZ] * bounds().tanAlpha();
197  double phi = locpos[Trk::locRPhi] / r;
198  Amg::Vector3D loc3Dframe(r * cos(phi), r * sin(phi), locpos[Trk::locZ]);
199  // transport it to the globalframe
200  glopos = transform() * loc3Dframe;
201 }
202 
203 bool
205 {
206  Amg::Vector3D loc3Dframe(inverseTransformMultHelper(glopos));
207  double r = loc3Dframe.z() * bounds().tanAlpha();
208  locpos = Amg::Vector2D(r * atan2(loc3Dframe.y(), loc3Dframe.x()), loc3Dframe.z());
209  // now decide on the quility of the transformation
210  // double inttol = r*0.0001;
211  // inttol = (inttol<0.01) ? 0.01 : 0.01; // ?
212  double inttol = 0.01;
213  return ((loc3Dframe.perp() - r) <= inttol);
214 }
215 
218  const Amg::Vector3D& dir,
219  bool forceDir,
220  Trk::BoundaryCheck bchk) const
221 {
222  // transform to a frame with the cone along z, with the tip at 0
223  const Amg::Transform3D surfaceTrans = inverseTransformHelper();
224  Amg::Vector3D tpos1 = surfaceTrans * pos;
225  Amg::Vector3D tdir = surfaceTrans.linear() * dir;
226  // see the header for the formula derivation
227  double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha();
228  double A = tdir.x() * tdir.x() + tdir.y() * tdir.y() - tan2Alpha * tdir.z() * tdir.z();
229  double B = 2 * (tdir.x() * tpos1.x() + tdir.y() * tpos1.y() - tan2Alpha * dir.z() * tpos1.z());
230  double C = tpos1.x() * tpos1.x() + tpos1.y() * tpos1.y() - tan2Alpha * tpos1.z() * tpos1.z();
231  if (A == 0.)
232  A += 1e-16; // avoid div by zero
233 
234  // use Andreas' quad solver, much more stable than what I wrote
235  Trk::RealQuadraticEquation solns(A, B, C);
236 
237  Amg::Vector3D solution(0., 0., 0.);
238  double path = 0.;
239  bool isValid = false;
240  if (solns.solutions != Trk::none) {
241  double t1 = solns.first;
242  Amg::Vector3D soln1Loc(tpos1 + t1 * dir);
243  isValid = forceDir ? (t1 > 0.) : true;
244  // there's only one solution
245  if (solns.solutions == Trk::one) {
246  solution = soln1Loc;
247  path = t1;
248  } else {
249  double t2 = solns.second;
250  Amg::Vector3D soln2Loc(tpos1 + t2 * dir);
251  // both solutions have the same sign
252  if (t1 * t2 > 0. || !forceDir) {
253  if (t1 * t1 < t2 * t2) {
254  solution = soln1Loc;
255  path = t1;
256  } else {
257  solution = soln2Loc;
258  path = t2;
259  }
260  } else {
261  if (t1 > 0.) {
262  solution = soln1Loc;
263  path = t1;
264  } else {
265  solution = soln2Loc;
266  path = t2;
267  }
268  }
269  }
270  }
271  solution = transform() * solution;
272 
273  isValid = bchk ? (isValid && isOnSurface(solution)) : isValid;
274  return Trk::Intersection(solution, path, isValid);
275 }
276 
279 // TODO understand what is going on here (copied from cylinder,
280 // because i really don't see what the idea is here vs. the other
281 // straightLineDistanceEstimate, and this is harder to see whats
282 // happening.
285 {
286  return straightLineDistanceEstimate(pos, dir, false);
287 }
288 
291 {
292  double tol = 0.001;
293 
294  Amg::Vector3D Cntr = center(); // tip of the cone (i.e. join between halves)
295  Amg::Vector3D N = normal(); // this is the z-direction of the cone in
296  // global coordiantes i believe
297 
298  Amg::Vector3D dPos = pos - Cntr; // pos w.r.t. cone tip
299  double posLength = sqrt(dPos.dot(dPos));
300  if (posLength < tol) // at origin of cone => on cone (avoid div by zero)
301  return {1, 0., true, 0.};
302  double posProj = dPos.dot(N);
303  double posProjAngle = acos(posProj / posLength);
304  double currDist = posLength * sin(posProjAngle - atan(bounds().tanAlpha()));
305  // solution on the surface
306  if (std::abs(currDist) < tol)
307  return {1, currDist, true, 0.};
308 
309  // transform to a frame with the cone along z, with the tip a 0
310  Amg::Vector3D locFramePos = inverseTransformMultHelper(pos);
311  Amg::Vector3D locFrameDir = transform().rotation().inverse() * dir.normalized();
312 
313  // solutions are in the form of a solution to a quadratic eqn.
314  double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha();
315  double A = locFrameDir.x() * locFrameDir.x() + locFrameDir.y() * locFrameDir.y() -
316  tan2Alpha * locFrameDir.z() * locFrameDir.z();
317  double B = 2 * (locFrameDir.x() * locFramePos.x() + locFrameDir.y() * locFramePos.y() -
318  tan2Alpha * locFrameDir.z() * locFramePos.z());
319  double C = locFramePos.x() * locFramePos.x() + locFramePos.y() * locFramePos.y() -
320  tan2Alpha * locFramePos.z() * locFramePos.z();
321  if (A == 0.)
322  A += 1e-16; // avoid div by zero
323  // use Andreas' quad solver, much more stable than what I wrote
324  Trk::RealQuadraticEquation solns(A, B, C);
325 
326  double d2bound = 0.;
327  if (bound && solns.solutions != Trk::none) {
328  std::optional<Amg::Vector2D> p = std::nullopt;
329  if (std::abs(solns.first) < std::abs(solns.second)){
330  p = Surface::globalToLocal(locFramePos + solns.first * locFrameDir);
331  }
332  else{
333  p = Surface::globalToLocal(locFramePos + solns.second * locFrameDir);
334  }
335  if (p) {
336  d2bound = bounds().minDistance(*p);
337  }
338  if (d2bound < 0){
339  d2bound = 0;
340  }
341  }
342  double totDist = d2bound > 0. ? sqrt(d2bound * d2bound + currDist * currDist) : currDist;
343 
344  switch (solns.solutions) {
345  case Trk::none:{
346  return {0, totDist, true, 0., 0.};
347  }
348  case Trk::one:{
349  return {1, totDist, true, solns.first};
350  }
351  case Trk::two:{
352  if (std::abs(solns.first) < std::abs(solns.second)){
353  return {2, totDist, true, solns.first, solns.second};
354  }
355  return {2, totDist, true, solns.second, solns.first};
356  }
357  default:{
358  return {0, totDist, true, 0., 0.};
359  }
360  };
361 }
362 
363 double
365 {
366  // (cos phi cos alpha, sin phi cos alpha, sgn z sin alpha)
367  bool applyTransform = !(transform().isApprox(Amg::Transform3D::Identity()));
368  Amg::Vector3D posLocal = applyTransform ? inverseTransformMultHelper(pos) : pos;
369  double phi = posLocal.phi();
370  double sgn = posLocal.z() > 0. ? -1. : +1.;
371  Amg::Vector3D normalC(cos(phi) * bounds().cosAlpha(), sin(phi) * bounds().cosAlpha(), sgn * bounds().sinAlpha());
372  if (applyTransform)
373  normalC = transform() * normalC;
374  // back in global frame
375  double cAlpha = normalC.dot(mom.unit());
376  return (cAlpha != 0.) ? std::abs(1. / cAlpha) : 1.; // ST undefined for cAlpha=0
377 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
beamspotman.r
def r
Definition: beamspotman.py:676
Trk::Intersection
Definition: Intersection.h:24
inline_hints.h
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
Trk::ConeSurface::operator=
ConeSurface & operator=(const ConeSurface &csf)
Assignment operator.
Definition: ConeSurface.cxx:86
PlotCalibFromCool.zAxis
zAxis
Definition: PlotCalibFromCool.py:76
Trk::DistanceSolution
Definition: DistanceSolution.h:25
Trk::RealQuadraticEquation::second
double second
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:55
Trk::Surface::ChargedTrackParametersUniquePtr
std::unique_ptr< ParametersBase< 5, Trk::Charged > > ChargedTrackParametersUniquePtr
Unique ptr types.
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:125
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
Trk::ConeSurface::ConeSurface
ConeSurface()
Default Constructor.
Definition: ConeSurface.cxx:20
Trk::ConeSurface::globalReferencePoint
virtual const Amg::Vector3D & globalReferencePoint() const override final
Returns a global reference point: For the Cylinder this is Where denotes the averagePhi() of the cy...
Definition: ConeSurface.cxx:138
Trk::locRPhi
@ locRPhi
Definition: ParamDefs.h:40
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
Trk::none
@ none
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:21
Trk::one
@ one
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:22
Trk::ConeBounds
Definition: ConeBounds.h:44
Trk::Surface::NeutralTrackParametersUniquePtr
std::unique_ptr< ParametersBase< 5, Trk::Neutral > > NeutralTrackParametersUniquePtr
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:127
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
isValid
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition: AtlasPID.h:620
Trk::RealQuadraticEquation::solutions
RQESolutionType solutions
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:56
Trk::ConeSurface::measurementFrame
virtual Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D &glopos, const Amg::Vector3D &glomom) const override final
Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perig...
Definition: ConeSurface.cxx:173
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
Trk::Surface::operator=
Surface & operator=(const Surface &sf)
Definition: Surface.cxx:91
A
Trk::ConeSurface::m_bounds
SharedObject< const ConeBounds > m_bounds
The global reference point (== a point on thesurface)
Definition: ConeSurface.h:276
skel.l2
l2
Definition: skel.GENtoEVGEN.py:399
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ParticleGun_EoverP_Config.mom
mom
Definition: ParticleGun_EoverP_Config.py:63
ConeSurface.h
Trk::locZ
@ locZ
local cylindrical
Definition: ParamDefs.h:42
Trk::ConeSurface::createUniqueNeutralParameters
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.
Definition: ConeSurface.cxx:119
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
Trk::two
@ two
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:23
Trk::ConeSurface::createUniqueTrackParameters
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.
Definition: ConeSurface.cxx:100
ATH_FLATTEN
#define ATH_FLATTEN
Definition: inline_hints.h:52
Trk::theta
@ theta
Definition: ParamDefs.h:66
xAOD::rotation
rotation
Definition: TrackSurface_v1.cxx:15
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
Trk::RealQuadraticEquation
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:52
Trk::SurfaceType::Cone
@ Cone
beamspotman.dir
string dir
Definition: beamspotman.py:623
Trk::ConeSurface::pathCorrection
virtual double pathCorrection(const Amg::Vector3D &, const Amg::Vector3D &) const override
the pathCorrection for derived classes with thickness
Definition: ConeSurface.cxx:364
Trk::ConeSurface::straightLineIntersection
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir=false, BoundaryCheck bchk=false) const override final
fast straight line intersection schema - provides closest intersection and (signed) path length
Definition: ConeSurface.cxx:217
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
charge
double charge(const T &p)
Definition: AtlasPID.h:756
Trk::ConeSurface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specialized for ConeSurface : LocalToGlobal method without dynamic memory allocation.
Definition: ConeSurface.cxx:193
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RealQuadraticEquation.h
query_example.col
col
Definition: query_example.py:7
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Trk::RealQuadraticEquation::first
double first
Definition: TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h:54
Trk::ConeSurface::rotSymmetryAxis
virtual const Amg::Vector3D & rotSymmetryAxis() const
Return method for the rotational symmetry axis - the z-Axis of the HepTransform.
Definition: ConeSurface.cxx:162
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
Trk::Surface::globalToLocal
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
Amg::RotationMatrix3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Definition: GeoPrimitives.h:49
Trk::BoundaryCheck
Definition: BoundaryCheck.h:51
Trk::ConeSurface
Definition: ConeSurface.h:51
Trk::phi
@ phi
Definition: ParamDefs.h:75
skel.l1
l1
Definition: skel.GENtoEVGEN.py:398
Trk::ConeSurface::globalToLocal
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specialized for ConeSurface : GlobalToLocal method without dynamic memory allocation - boolean checks...
Definition: ConeSurface.cxx:204
Trk::ConeSurface::straightLineDistanceEstimate
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const override final
fast straight line distance to Surface
Definition: ConeSurface.cxx:284
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
Trk::ConeSurface::operator==
virtual bool operator==(const Surface &sf) const override
Equality operator.
Definition: ConeSurface.cxx:152