EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HelicalTrackLinearizer.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HelicalTrackLinearizer.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 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 
11 template <typename propagator_t, typename propagator_options_t>
14  const BoundTrackParameters& params, const Vector4D& linPoint,
16  const Acts::MagneticFieldContext& mctx, State& state) const {
17  Vector3D linPointPos = VectorHelpers::position(linPoint);
18 
19  const std::shared_ptr<PerigeeSurface> perigeeSurface =
20  Surface::makeShared<PerigeeSurface>(linPointPos);
21 
22  // Create propagator options
23  auto logger = getDefaultLogger("HelTrkLinProp", Logging::INFO);
24  propagator_options_t pOptions(gctx, mctx, LoggerWrapper{*logger});
25  pOptions.direction = backward;
26 
27  const BoundTrackParameters* endParams = nullptr;
28  // Do the propagation to linPointPos
29  auto result = m_cfg.propagator->propagate(params, *perigeeSurface, pOptions);
30  if (result.ok()) {
31  endParams = (*result).endParameters.get();
32 
33  } else {
34  return result.error();
35  }
36 
37  BoundVector paramsAtPCA = endParams->parameters();
38  Vector4D positionAtPCA = Vector4D::Zero();
39  {
40  auto pos = endParams->position(gctx);
41  positionAtPCA[ePos0] = pos[ePos0];
42  positionAtPCA[ePos1] = pos[ePos1];
43  positionAtPCA[ePos2] = pos[ePos2];
44  positionAtPCA[eTime] = endParams->time();
45  }
46  BoundSymMatrix parCovarianceAtPCA = *(endParams->covariance());
47 
48  if (endParams->covariance()->determinant() == 0) {
49  // Use the original parameters
50  paramsAtPCA = params.parameters();
51  auto pos = endParams->position(gctx);
52  positionAtPCA[ePos0] = pos[ePos0];
53  positionAtPCA[ePos1] = pos[ePos1];
54  positionAtPCA[ePos2] = pos[ePos2];
55  parCovarianceAtPCA = *(params.covariance());
56  }
57 
58  // phiV and functions
59  double phiV = paramsAtPCA(BoundIndices::eBoundPhi);
60  double sinPhiV = std::sin(phiV);
61  double cosPhiV = std::cos(phiV);
62 
63  // theta and functions
64  double th = paramsAtPCA(BoundIndices::eBoundTheta);
65  const double sinTh = std::sin(th);
66  const double tanTh = std::tan(th);
67 
68  // q over p
69  double qOvP = paramsAtPCA(BoundIndices::eBoundQOverP);
70  double sgnH = (qOvP < 0.) ? -1 : 1;
71 
72  Vector3D momentumAtPCA(phiV, th, qOvP);
73 
74  // get B-field z-component at current position
75  double Bz = m_cfg.bField.getField(VectorHelpers::position(positionAtPCA),
76  state.fieldCache)[eZ];
77  double rho;
78  // Curvature is infinite w/o b field
79  if (Bz == 0. || std::abs(qOvP) < m_cfg.minQoP) {
80  rho = m_cfg.maxRho;
81  } else {
82  rho = sinTh * (1. / qOvP) / Bz;
83  }
84 
85  // Eq. 5.34 in Ref(1) (see .hpp)
86  double X = positionAtPCA(0) - linPointPos.x() + rho * sinPhiV;
87  double Y = positionAtPCA(1) - linPointPos.y() - rho * cosPhiV;
88  const double S2 = (X * X + Y * Y);
89  const double S = std::sqrt(S2);
90 
94  BoundVector predParamsAtPCA;
95 
96  int sgnX = (X < 0.) ? -1 : 1;
97  int sgnY = (Y < 0.) ? -1 : 1;
98 
99  double phiAtPCA;
100  if (std::abs(X) > std::abs(Y)) {
101  phiAtPCA = sgnH * sgnX * std::acos(-sgnH * Y / S);
102  } else {
103  phiAtPCA = std::asin(sgnH * X / S);
104  if ((sgnH * sgnY) > 0) {
105  phiAtPCA = sgnH * sgnX * M_PI - phiAtPCA;
106  }
107  }
108 
109  // Eq. 5.33 in Ref(1) (see .hpp)
110  predParamsAtPCA[0] = rho - sgnH * S;
111  predParamsAtPCA[1] =
112  positionAtPCA[eZ] - linPointPos.z() + rho * (phiV - phiAtPCA) / tanTh;
113  predParamsAtPCA[2] = phiAtPCA;
114  predParamsAtPCA[3] = th;
115  predParamsAtPCA[4] = qOvP;
116  predParamsAtPCA[5] = 0.;
117 
118  // Fill position jacobian (D_k matrix), Eq. 5.36 in Ref(1)
120  positionJacobian.setZero();
121  // First row
122  positionJacobian(0, 0) = -sgnH * X / S;
123  positionJacobian(0, 1) = -sgnH * Y / S;
124 
125  const double S2tanTh = S2 * tanTh;
126 
127  // Second row
128  positionJacobian(1, 0) = rho * Y / S2tanTh;
129  positionJacobian(1, 1) = -rho * X / S2tanTh;
130  positionJacobian(1, 2) = 1.;
131 
132  // Third row
133  positionJacobian(2, 0) = -Y / S2;
134  positionJacobian(2, 1) = X / S2;
135 
136  // TODO: include timing in track linearization
137  // Last row
138  positionJacobian(5, 3) = 1;
139 
140  // Fill momentum jacobian (E_k matrix), Eq. 5.37 in Ref(1)
141  ActsMatrixD<eBoundSize, 3> momentumJacobian;
142  momentumJacobian.setZero();
143 
144  double R = X * cosPhiV + Y * sinPhiV;
145  double Q = X * sinPhiV - Y * cosPhiV;
146  double dPhi = phiAtPCA - phiV;
147 
148  // First row
149  momentumJacobian(0, 0) = -sgnH * rho * R / S;
150 
151  double qOvSred = 1 - sgnH * Q / S;
152 
153  momentumJacobian(0, 1) = qOvSred * rho / tanTh;
154  momentumJacobian(0, 2) = -qOvSred * rho / qOvP;
155 
156  const double rhoOverS2 = rho / S2;
157 
158  // Second row
159  momentumJacobian(1, 0) = (1 - rhoOverS2 * Q) * rho / tanTh;
160  momentumJacobian(1, 1) = (dPhi + rho * R / (S2tanTh * tanTh)) * rho;
161  momentumJacobian(1, 2) = (dPhi - rhoOverS2 * R) * rho / (qOvP * tanTh);
162 
163  // Third row
164  momentumJacobian(2, 0) = rhoOverS2 * Q;
165  momentumJacobian(2, 1) = -rho * R / S2tanTh;
166  momentumJacobian(2, 2) = rhoOverS2 * R / qOvP;
167 
168  // Last two rows:
169  momentumJacobian(3, 1) = 1.;
170  momentumJacobian(4, 2) = 1.;
171 
172  // const term F(V_0, p_0) in Talyor expansion
173  BoundVector constTerm = predParamsAtPCA - positionJacobian * positionAtPCA -
174  momentumJacobian * momentumAtPCA;
175 
176  // The parameter weight
177  ActsSymMatrixD<5> parWeight =
178  (parCovarianceAtPCA.block<5, 5>(0, 0)).inverse();
179 
180  BoundSymMatrix weightAtPCA{BoundSymMatrix::Identity()};
181  weightAtPCA.block<5, 5>(0, 0) = parWeight;
182 
183  return LinearizedTrack(paramsAtPCA, parCovarianceAtPCA, weightAtPCA, linPoint,
184  positionJacobian, momentumJacobian, positionAtPCA,
185  momentumAtPCA, constTerm);
186 }