Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JacobianEngine.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JacobianEngine.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 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 
15 
16 #include <algorithm>
17 #include <cmath>
18 #include <utility>
19 
20 namespace Acts {
21 
22 namespace detail {
23 
25  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
27  // Prepare the jacobian to curvilinear
28  FreeToBoundMatrix freeToCurvJacobian = FreeToBoundMatrix::Zero();
29  if (std::abs(cosTheta) < s_curvilinearProjTolerance) {
30  // We normally operate in curvilinear coordinates defined as follows
31  freeToCurvJacobian(eBoundLoc0, eFreePos0) = -sinPhi;
32  freeToCurvJacobian(eBoundLoc0, eFreePos1) = cosPhi;
33  freeToCurvJacobian(eBoundLoc1, eFreePos0) = -cosPhi * cosTheta;
34  freeToCurvJacobian(eBoundLoc1, eFreePos1) = -sinPhi * cosTheta;
35  freeToCurvJacobian(eBoundLoc1, eFreePos2) = sinTheta;
36  } else {
37  // Under grazing incidence to z, the above coordinate system definition
38  // becomes numerically unstable, and we need to switch to another one
39  const ActsScalar x = direction(0); // == cos(phi) * sin(theta)
40  const ActsScalar y = direction(1); // == sin(phi) * sin(theta)
41  const ActsScalar z = direction(2); // == cos(theta)
42  const ActsScalar c = std::hypot(y, z);
43  const ActsScalar invC = 1. / c;
44  freeToCurvJacobian(eBoundLoc0, eFreePos1) = -z * invC;
45  freeToCurvJacobian(eBoundLoc0, eFreePos2) = y * invC;
46  freeToCurvJacobian(eBoundLoc1, eFreePos0) = c;
47  freeToCurvJacobian(eBoundLoc1, eFreePos1) = -x * y * invC;
48  freeToCurvJacobian(eBoundLoc1, eFreePos2) = -x * z * invC;
49  }
50  // Time parameter
51  freeToCurvJacobian(eBoundTime, eFreeTime) = 1.;
52  // Directional and momentum parameters for curvilinear
53  freeToCurvJacobian(eBoundPhi, eFreeDir0) = -sinPhi * invSinTheta;
54  freeToCurvJacobian(eBoundPhi, eFreeDir1) = cosPhi * invSinTheta;
55  freeToCurvJacobian(eBoundTheta, eFreeDir0) = cosPhi * cosTheta;
56  freeToCurvJacobian(eBoundTheta, eFreeDir1) = sinPhi * cosTheta;
57  freeToCurvJacobian(eBoundTheta, eFreeDir2) = -sinTheta;
58  freeToCurvJacobian(eBoundQOverP, eFreeQOverP) = 1.;
59 
60  return freeToCurvJacobian;
61 }
62 
64  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
66 
67  // Prepare the jacobian to free
68  BoundToFreeMatrix curvToFreeJacobian = BoundToFreeMatrix::Zero();
69 
70  curvToFreeJacobian(eFreePos0, eBoundLoc0) = -sinPhi;
71  curvToFreeJacobian(eFreePos0, eBoundLoc1) = -cosPhi * cosTheta;
72  curvToFreeJacobian(eFreePos1, eBoundLoc0) = cosPhi;
73  curvToFreeJacobian(eFreePos1, eBoundLoc1) = -sinPhi * cosTheta;
74  curvToFreeJacobian(eFreePos2, eBoundLoc1) = sinTheta;
75  // Time parameter: stays as is
76  curvToFreeJacobian(eFreeTime, eBoundTime) = 1;
77  curvToFreeJacobian(eFreeDir0, eBoundPhi) = -sinTheta * sinPhi;
78  curvToFreeJacobian(eFreeDir0, eBoundTheta) = cosTheta * cosPhi;
79  curvToFreeJacobian(eFreeDir1, eBoundPhi) = sinTheta * cosPhi;
80  curvToFreeJacobian(eFreeDir1, eBoundTheta) = cosTheta * sinPhi;
81  curvToFreeJacobian(eFreeDir2, eBoundTheta) = -sinTheta;
82  // Q/P parameter: stays as is
83  curvToFreeJacobian(eFreeQOverP, eBoundQOverP) = 1;
84 
85  return curvToFreeJacobian;
86 }
87 
90 
91  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
93 
94  jacobian(0, 0) = 1.;
95  jacobian(1, 1) = 1.;
96  jacobian(2, 2) = 1.;
97  jacobian(3, 3) = 1.;
98  jacobian(7, 6) = 1.;
99 
100  jacobian(4, 4) = -sinTheta * sinPhi;
101  jacobian(4, 5) = cosTheta * cosPhi;
102  jacobian(5, 4) = sinTheta * cosPhi;
103  jacobian(5, 5) = cosTheta * sinPhi;
104  jacobian(6, 5) = -sinTheta;
105  return jacobian;
106 }
107 
110 
111  auto [cosPhi, sinPhi, cosTheta, sinTheta, invSinTheta] =
113 
114  jacobian(0, 0) = 1.;
115  jacobian(1, 1) = 1.;
116  jacobian(2, 2) = 1.;
117  jacobian(3, 3) = 1.;
118  jacobian(6, 7) = 1.;
119 
120  jacobian(4, 4) = -sinPhi * invSinTheta;
121  jacobian(4, 5) = cosPhi * invSinTheta;
122  jacobian(5, 4) = cosPhi * cosTheta;
123  jacobian(5, 5) = sinPhi * cosTheta;
124  jacobian(5, 6) = -sinTheta;
125 
126  return jacobian;
127 }
128 
130  const GeometryContext& geoContext, const FreeVector& freeParameters,
131  const BoundToFreeMatrix& boundToFreeJacobian,
132  const FreeMatrix& freeTransportJacobian,
133  const FreeVector& freeToPathDerivatives, const Surface& surface) {
134  // Calculate the derivative of path length at the final surface or the
135  // point-of-closest approach w.r.t. free parameters
136  const FreeToPathMatrix freeToPath =
137  surface.freeToPathDerivative(geoContext, freeParameters);
138  // Calculate the jacobian from free to bound at the final surface
139  FreeToBoundMatrix freeToBoundJacobian =
140  surface.freeToBoundJacobian(geoContext, freeParameters);
141  // Calculate the full jacobian from the local/bound parameters at the start
142  // surface to local/bound parameters at the final surface
143  return freeToBoundJacobian *
144  (FreeMatrix::Identity() + freeToPathDerivatives * freeToPath) *
145  freeTransportJacobian * boundToFreeJacobian;
146 }
147 
149  const Vector3& direction, const BoundToFreeMatrix& boundToFreeJacobian,
150  const FreeMatrix& freeTransportJacobian,
151  const FreeVector& freeToPathDerivatives) {
152  // Calculate the derivative of path length at the curvilinear surface
153  // w.r.t. free parameters
154  FreeToPathMatrix freeToPath = FreeToPathMatrix::Zero();
155  freeToPath.segment<3>(eFreePos0) = -1.0 * direction;
156  // Calculate the jacobian from global to local at the curvilinear surface
157  FreeToBoundMatrix freeToBoundJacobian = freeToCurvilinearJacobian(direction);
158  // Calculate the full jacobian from the local parameters at the start surface
159  // to curvilinear parameters
160  return freeToBoundJacobian *
161  (FreeMatrix::Identity() + freeToPathDerivatives * freeToPath) *
162  freeTransportJacobian * boundToFreeJacobian;
163 }
164 
166  const BoundToFreeMatrix& boundToFreeJacobian,
167  const FreeMatrix& freeTransportJacobian) {
168  // Calculate the full jacobian, in this case simple a product of
169  // jacobian(transport in free) * jacobian(bound to free)
170  return (freeTransportJacobian * boundToFreeJacobian);
171 }
172 
174  const GeometryContext& geoContext, const FreeVector& freeParameters,
177  const FreeMatrix& freeTransportJacobian,
178  const FreeVector& freeToPathDerivatives, const Surface& surface) {
179  // Calculate the jacobian from free to bound at the final surface
180  FreeToBoundMatrix freeToBoundJacobian =
181  surface.freeToBoundJacobian(geoContext, freeParameters);
182  // Calculate the form factors for the derivatives
183  auto transport = freeTransportJacobian * anglesToDirectionJacobian;
184  FreeToPathMatrix sVec =
185  surface.freeToPathDerivative(geoContext, freeParameters);
186  // Return the jacobian to local
187  return freeToBoundJacobian *
188  (transport + freeToPathDerivatives * sVec * transport) *
189  directionToAnglesJacobian;
190 }
191 
193  const Vector3& direction, const ActsMatrix<7, 8>& directionToAnglesJacobian,
195  const FreeMatrix& freeTransportJacobian,
196  const FreeVector& freeToPathDerivatives) {
197  const ActsMatrix<8, 7> transport =
198  freeTransportJacobian * anglesToDirectionJacobian;
199  auto sfactors =
200  direction.transpose() * transport.template topLeftCorner<3, 7>();
201 
202  // Since the jacobian to local needs to calculated for the bound parameters
203  // here, it is convenient to do the same here
204  return freeToCurvilinearJacobian(direction) *
205  (transport - freeToPathDerivatives * sfactors) *
206  directionToAnglesJacobian;
207 }
208 
212  const FreeMatrix& freeTransportJacobian) {
213  return freeTransportJacobian * anglesToDirectionJacobian *
215 }
216 
217 } // namespace detail
218 } // namespace Acts