Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Surface.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Surface.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 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 
17 
18 #include <algorithm>
19 #include <iomanip>
20 #include <utility>
21 
22 std::array<std::string, Acts::Surface::SurfaceType::Other>
24  "Cone", "Cylinder", "Disc", "Perigee", "Plane", "Straw", "Curvilinear"};
25 
27  : GeometryObject(), m_transform(transform) {}
28 
30  : GeometryObject(), m_associatedDetElement(&detelement) {}
31 
33  : GeometryObject(other),
35  m_transform(other.m_transform),
36  m_surfaceMaterial(other.m_surfaceMaterial) {}
37 
39  const Transform3& shift)
40  : GeometryObject(),
41  m_transform(shift * other.transform(gctx)),
42  m_surfaceMaterial(other.m_surfaceMaterial) {}
43 
44 Acts::Surface::~Surface() = default;
45 
47  const Vector3& position,
48  const Vector3& direction,
49  const BoundaryCheck& bcheck) const {
50  // global to local transformation
51  auto lpResult = globalToLocal(gctx, position, direction);
52  if (lpResult.ok()) {
53  return bcheck ? bounds().inside(lpResult.value(), bcheck) : true;
54  }
55  return false;
56 }
57 
60  const FreeVector& pathDerivative) const {
61  // 1) Calculate the derivative of bound parameter local position w.r.t.
62  // alignment parameters without path length correction
63  const auto alignToBoundWithoutCorrection =
64  alignmentToBoundDerivativeWithoutCorrection(gctx, parameters);
65  // 2) Calculate the derivative of path length w.r.t. alignment parameters
66  const auto alignToPath = alignmentToPathDerivative(gctx, parameters);
67  // 3) Calculate the jacobian from free parameters to bound parameters
68  FreeToBoundMatrix jacToLocal = freeToBoundJacobian(gctx, parameters);
69  // 4) The derivative of bound parameters w.r.t. alignment
70  // parameters is alignToBoundWithoutCorrection +
71  // jacToLocal*pathDerivative*alignToPath
72  AlignmentToBoundMatrix alignToBound =
73  alignToBoundWithoutCorrection + jacToLocal * pathDerivative * alignToPath;
74 
75  return alignToBound;
76 }
77 
80  const GeometryContext& gctx, const FreeVector& parameters) const {
81  // The global posiiton
82  const auto position = parameters.segment<3>(eFreePos0);
83  // The vector between position and center
84  const auto pcRowVec = (position - center(gctx)).transpose().eval();
85  // The local frame rotation
86  const auto& rotation = transform(gctx).rotation();
87  // The axes of local frame
88  const auto& localXAxis = rotation.col(0);
89  const auto& localYAxis = rotation.col(1);
90  const auto& localZAxis = rotation.col(2);
91  // Calculate the derivative of local frame axes w.r.t its rotation
92  const auto [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
94  // Calculate the derivative of local 3D Cartesian coordinates w.r.t.
95  // alignment parameters (without path correction)
96  AlignmentToPositionMatrix alignToLoc3D = AlignmentToPositionMatrix::Zero();
97  alignToLoc3D.block<1, 3>(eX, eAlignmentCenter0) = -localXAxis.transpose();
98  alignToLoc3D.block<1, 3>(eY, eAlignmentCenter0) = -localYAxis.transpose();
99  alignToLoc3D.block<1, 3>(eZ, eAlignmentCenter0) = -localZAxis.transpose();
100  alignToLoc3D.block<1, 3>(eX, eAlignmentRotation0) =
101  pcRowVec * rotToLocalXAxis;
102  alignToLoc3D.block<1, 3>(eY, eAlignmentRotation0) =
103  pcRowVec * rotToLocalYAxis;
104  alignToLoc3D.block<1, 3>(eZ, eAlignmentRotation0) =
105  pcRowVec * rotToLocalZAxis;
106  // The derivative of bound local w.r.t. local 3D Cartesian coordinates
107  ActsMatrix<2, 3> loc3DToBoundLoc =
108  localCartesianToBoundLocalDerivative(gctx, position);
109  // Initialize the derivative of bound parameters w.r.t. alignment
110  // parameters without path correction
111  AlignmentToBoundMatrix alignToBound = AlignmentToBoundMatrix::Zero();
112  // It's only relevant with the bound local position without path correction
113  alignToBound.block<2, eAlignmentSize>(eBoundLoc0, eAlignmentCenter0) =
114  loc3DToBoundLoc * alignToLoc3D;
115  return alignToBound;
116 }
117 
119  const GeometryContext& gctx, const FreeVector& parameters) const {
120  // The global posiiton
121  const auto position = parameters.segment<3>(eFreePos0);
122  // The direction
123  const auto direction = parameters.segment<3>(eFreeDir0);
124  // The vector between position and center
125  const auto pcRowVec = (position - center(gctx)).transpose().eval();
126  // The local frame rotation
127  const auto& rotation = transform(gctx).rotation();
128  // The local frame z axis
129  const auto& localZAxis = rotation.col(2);
130  // Cosine of angle between momentum direction and local frame z axis
131  const auto dz = localZAxis.dot(direction);
132  // Calculate the derivative of local frame axes w.r.t its rotation
133  const auto [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
135  // Initialize the derivative of propagation path w.r.t. local frame
136  // translation (origin) and rotation
137  AlignmentToPathMatrix alignToPath = AlignmentToPathMatrix::Zero();
138  alignToPath.segment<3>(eAlignmentCenter0) = localZAxis.transpose() / dz;
139  alignToPath.segment<3>(eAlignmentRotation0) =
140  -pcRowVec * rotToLocalZAxis / dz;
141 
142  return alignToPath;
143 }
144 
145 std::shared_ptr<Acts::Surface> Acts::Surface::getSharedPtr() {
146  return shared_from_this();
147 }
148 
149 std::shared_ptr<const Acts::Surface> Acts::Surface::getSharedPtr() const {
150  return shared_from_this();
151 }
152 
154  if (&other != this) {
156  // detector element, identifier & layer association are unique
157  m_transform = other.m_transform;
158  m_associatedLayer = other.m_associatedLayer;
159  m_surfaceMaterial = other.m_surfaceMaterial;
160  m_associatedDetElement = other.m_associatedDetElement;
161  }
162  return *this;
163 }
164 
165 bool Acts::Surface::operator==(const Surface& other) const {
166  // (a) fast exit for pointer comparison
167  if (&other == this) {
168  return true;
169  }
170  // (b) fast exit for type
171  if (other.type() != type()) {
172  return false;
173  }
174  // (c) fast exit for bounds
175  if (other.bounds() != bounds()) {
176  return false;
177  }
178  // (d) compare detector elements
179  if (m_associatedDetElement != other.m_associatedDetElement) {
180  return false;
181  }
182  // (e) compare transform values
183  if (!m_transform.isApprox(other.m_transform, 1e-9)) {
184  return false;
185  }
186  // (f) compare material
187  if (m_surfaceMaterial != other.m_surfaceMaterial) {
188  return false;
189  }
190 
191  // we should be good
192  return true;
193 }
194 
195 // overload dump for stream operator
197  std::ostream& sl) const {
198  sl << std::setiosflags(std::ios::fixed);
199  sl << std::setprecision(4);
200  sl << name() << std::endl;
201  const Vector3& sfcenter = center(gctx);
202  sl << " Center position (x, y, z) = (" << sfcenter.x() << ", "
203  << sfcenter.y() << ", " << sfcenter.z() << ")" << std::endl;
204  Acts::RotationMatrix3 rot(transform(gctx).matrix().block<3, 3>(0, 0));
205  Acts::Vector3 rotX(rot.col(0));
206  Acts::Vector3 rotY(rot.col(1));
207  Acts::Vector3 rotZ(rot.col(2));
208  sl << std::setprecision(6);
209  sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1)
210  << ", " << rotX(2) << ")" << std::endl;
211  sl << " colY = (" << rotY(0) << ", " << rotY(1)
212  << ", " << rotY(2) << ")" << std::endl;
213  sl << " colZ = (" << rotZ(0) << ", " << rotZ(1)
214  << ", " << rotZ(2) << ")" << std::endl;
215  sl << " Bounds : " << bounds();
216  sl << std::setprecision(-1);
217  return sl;
218 }
219 
221  std::stringstream ss;
222  toStream(gctx, ss);
223  return ss.str();
224 }
225 
227  return !(operator==(sf));
228 }
229 
231  // fast access via transform matrix (and not translation())
232  auto tMatrix = transform(gctx).matrix();
233  return Vector3(tMatrix(0, 3), tMatrix(1, 3), tMatrix(2, 3));
234 }
235 
237  const Vector3& /*position*/) const {
238  return normal(gctx, Vector2(Vector2::Zero()));
239 }
240 
242  const GeometryContext& gctx) const {
243  if (m_associatedDetElement != nullptr) {
244  return m_associatedDetElement->transform(gctx);
245  }
246  return m_transform;
247 }
248 
249 bool Acts::Surface::insideBounds(const Vector2& lposition,
250  const BoundaryCheck& bcheck) const {
251  return bounds().inside(lposition, bcheck);
252 }
253 
255  const GeometryContext& gctx, const Vector3& /*position*/,
256  const Vector3& /*direction*/) const {
257  return transform(gctx).matrix().block<3, 3>(0, 0);
258 }
259 
261  const GeometryContext& gctx, const BoundVector& boundParams) const {
262  // Transform from bound to free parameters
263  FreeVector freeParams =
264  detail::transformBoundToFreeParameters(*this, gctx, boundParams);
265  // The global position
266  const Vector3 position = freeParams.segment<3>(eFreePos0);
267  // The direction
268  const Vector3 direction = freeParams.segment<3>(eFreeDir0);
269  // Use fast evaluation function of sin/cos
270  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
272  // retrieve the reference frame
273  const auto rframe = referenceFrame(gctx, position, direction);
274  // Initialize the jacobian from local to global
275  BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
276  // the local error components - given by reference frame
277  jacToGlobal.topLeftCorner<3, 2>() = rframe.topLeftCorner<3, 2>();
278  // the time component
279  jacToGlobal(eFreeTime, eBoundTime) = 1;
280  // the momentum components
281  jacToGlobal(eFreeDir0, eBoundPhi) = (-sinTheta) * sinPhi;
282  jacToGlobal(eFreeDir0, eBoundTheta) = cosTheta * cosPhi;
283  jacToGlobal(eFreeDir1, eBoundPhi) = sinTheta * cosPhi;
284  jacToGlobal(eFreeDir1, eBoundTheta) = cosTheta * sinPhi;
285  jacToGlobal(eFreeDir2, eBoundTheta) = (-sinTheta);
286  jacToGlobal(eFreeQOverP, eBoundQOverP) = 1;
287  return jacToGlobal;
288 }
289 
291  const GeometryContext& gctx, const FreeVector& parameters) const {
292  // The global position
293  const auto position = parameters.segment<3>(eFreePos0);
294  // The direction
295  const auto direction = parameters.segment<3>(eFreeDir0);
296  // Use fast evaluation function of sin/cos
297  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
299  // The measurement frame of the surface
300  RotationMatrix3 rframeT =
301  referenceFrame(gctx, position, direction).transpose();
302  // Initialize the jacobian from global to local
303  FreeToBoundMatrix jacToLocal = FreeToBoundMatrix::Zero();
304  // Local position component given by the reference frame
305  jacToLocal.block<2, 3>(eBoundLoc0, eFreePos0) = rframeT.block<2, 3>(0, 0);
306  // Time component
307  jacToLocal(eBoundTime, eFreeTime) = 1;
308  // Directional and momentum elements for reference frame surface
309  jacToLocal(eBoundPhi, eFreeDir0) = -sinPhi * invSinTheta;
310  jacToLocal(eBoundPhi, eFreeDir1) = cosPhi * invSinTheta;
311  jacToLocal(eBoundTheta, eFreeDir0) = cosPhi * cosTheta;
312  jacToLocal(eBoundTheta, eFreeDir1) = sinPhi * cosTheta;
313  jacToLocal(eBoundTheta, eFreeDir2) = -sinTheta;
314  jacToLocal(eBoundQOverP, eFreeQOverP) = 1;
315  return jacToLocal;
316 }
317 
319  const GeometryContext& gctx, const FreeVector& parameters) const {
320  // The global position
321  const auto position = parameters.segment<3>(eFreePos0);
322  // The direction
323  const auto direction = parameters.segment<3>(eFreeDir0);
324  // The measurement frame of the surface
325  const RotationMatrix3 rframe = referenceFrame(gctx, position, direction);
326  // The measurement frame z axis
327  const Vector3 refZAxis = rframe.col(2);
328  // Cosine of angle between momentum direction and measurement frame z axis
329  const ActsScalar dz = refZAxis.dot(direction);
330  // Initialize the derivative
331  FreeToPathMatrix freeToPath = FreeToPathMatrix::Zero();
332  freeToPath.segment<3>(eFreePos0) = -1.0 * refZAxis.transpose() / dz;
333  return freeToPath;
334 }
335 
337  const {
338  return m_associatedDetElement;
339 }
340 
342  return m_associatedLayer;
343 }
344 
346  return m_surfaceMaterial.get();
347 }
348 
349 const std::shared_ptr<const Acts::ISurfaceMaterial>&
351  return m_surfaceMaterial;
352 }
353 
355  const DetectorElementBase& detelement) {
356  m_associatedDetElement = &detelement;
357  // resetting the transform as it will be handled through the detector element
358  // now
359  m_transform = Transform3::Identity();
360 }
361 
363  std::shared_ptr<const Acts::ISurfaceMaterial> material) {
364  m_surfaceMaterial = std::move(material);
365 }
366 
368  m_associatedLayer = (&lay);
369 }