ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Surface.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Surface.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 // Surface.ipp, Acts project
12 
13 inline const Vector3D Surface::center(const GeometryContext& gctx) const {
14  // fast access via tranform matrix (and not translation())
15  auto tMatrix = transform(gctx).matrix();
16  return Vector3D(tMatrix(0, 3), tMatrix(1, 3), tMatrix(2, 3));
17 }
18 
20  const Vector3D& /*unused*/) const {
21  return normal(gctx, s_origin2D);
22 }
23 
25  const GeometryContext& gctx) const {
26  if (m_transform != nullptr) {
27  return (*(m_transform.get()));
28  }
29  if (m_associatedDetElement != nullptr) {
30  return m_associatedDetElement->transform(gctx);
31  }
32  return s_idTransform;
33 }
34 
35 inline bool Surface::insideBounds(const Vector2D& lposition,
36  const BoundaryCheck& bcheck) const {
37  return bounds().inside(lposition, bcheck);
38 }
39 
40 inline const RotationMatrix3D Surface::referenceFrame(
41  const GeometryContext& gctx, const Vector3D& /*unused*/,
42  const Vector3D& /*unused*/) const {
43  return transform(gctx).matrix().block<3, 3>(0, 0);
44 }
45 
46 inline void Surface::initJacobianToGlobal(const GeometryContext& gctx,
47  BoundToFreeMatrix& jacobian,
48  const Vector3D& position,
49  const Vector3D& direction,
50  const BoundVector& /*pars*/) const {
51  // The trigonometry required to convert the direction to spherical
52  // coordinates and then compute the sines and cosines again can be
53  // surprisingly expensive from a performance point of view.
54  //
55  // Here, we can avoid it because the direction is by definition a unit
56  // vector, with the following coordinate conversions...
57  const double x = direction(0); // == cos(phi) * sin(theta)
58  const double y = direction(1); // == sin(phi) * sin(theta)
59  const double z = direction(2); // == cos(theta)
60 
61  // ...which we can invert to directly get the sines and cosines:
62  const double cos_theta = z;
63  const double sin_theta = sqrt(x * x + y * y);
64  const double inv_sin_theta = 1. / sin_theta;
65  const double cos_phi = x * inv_sin_theta;
66  const double sin_phi = y * inv_sin_theta;
67  // retrieve the reference frame
68  const auto rframe = referenceFrame(gctx, position, direction);
69  // the local error components - given by reference frame
70  jacobian.topLeftCorner<3, 2>() = rframe.topLeftCorner<3, 2>();
71  // the time component
72  jacobian(3, eT) = 1;
73  // the momentum components
74  jacobian(4, ePHI) = (-sin_theta) * sin_phi;
75  jacobian(4, eTHETA) = cos_theta * cos_phi;
76  jacobian(5, ePHI) = sin_theta * cos_phi;
77  jacobian(5, eTHETA) = cos_theta * sin_phi;
78  jacobian(6, eTHETA) = (-sin_theta);
79  jacobian(7, eQOP) = 1;
80 }
81 
82 inline const RotationMatrix3D Surface::initJacobianToLocal(
83  const GeometryContext& gctx, FreeToBoundMatrix& jacobian,
84  const Vector3D& position, const Vector3D& direction) const {
85  // Optimized trigonometry on the propagation direction
86  const double x = direction(0); // == cos(phi) * sin(theta)
87  const double y = direction(1); // == sin(phi) * sin(theta)
88  const double z = direction(2); // == cos(theta)
89  // can be turned into cosine/sine
90  const double cosTheta = z;
91  const double sinTheta = sqrt(x * x + y * y);
92  const double invSinTheta = 1. / sinTheta;
93  const double cosPhi = x * invSinTheta;
94  const double sinPhi = y * invSinTheta;
95  // The measurement frame of the surface
96  RotationMatrix3D rframeT =
97  referenceFrame(gctx, position, direction).transpose();
98  // given by the refernece frame
99  jacobian.block<2, 3>(0, 0) = rframeT.block<2, 3>(0, 0);
100  // Time component
101  jacobian(eT, 3) = 1;
102  // Directional and momentum elements for reference frame surface
103  jacobian(ePHI, 4) = -sinPhi * invSinTheta;
104  jacobian(ePHI, 5) = cosPhi * invSinTheta;
105  jacobian(eTHETA, 4) = cosPhi * cosTheta;
106  jacobian(eTHETA, 5) = sinPhi * cosTheta;
107  jacobian(eTHETA, 6) = -sinTheta;
108  jacobian(eQOP, 7) = 1;
109  // return the frame where this happened
110  return rframeT;
111 }
112 
113 inline const BoundRowVector Surface::derivativeFactors(
114  const GeometryContext& /*unused*/, const Vector3D& /*unused*/,
115  const Vector3D& direction, const RotationMatrix3D& rft,
116  const BoundToFreeMatrix& jacobian) const {
117  // Create the normal and scale it with the projection onto the direction
118  ActsRowVectorD<3> norm_vec = rft.template block<1, 3>(2, 0);
119  norm_vec /= (norm_vec * direction);
120  // calculate the s factors
121  return (norm_vec * jacobian.topLeftCorner<3, eBoundParametersSize>());
122 }
123 
124 inline const DetectorElementBase* Surface::associatedDetectorElement() const {
125  return m_associatedDetElement;
126 }
127 
128 inline const Layer* Surface::associatedLayer() const {
129  return (m_associatedLayer);
130 }
131 
132 inline const ISurfaceMaterial* Surface::surfaceMaterial() const {
133  return m_surfaceMaterial.get();
134 }
135 
136 inline const std::shared_ptr<const ISurfaceMaterial>&
137 Surface::surfaceMaterialSharedPtr() const {
138  return m_surfaceMaterial;
139 }
140 
141 inline void Surface::assignSurfaceMaterial(
142  std::shared_ptr<const ISurfaceMaterial> material) {
143  m_surfaceMaterial = std::move(material);
144 }
145 
146 inline void Surface::associateLayer(const Layer& lay) {
147  m_associatedLayer = (&lay);
148 }