CMS 3D CMS Logo

FitUtils.h
Go to the documentation of this file.
1 #ifndef RecoTracker_PixelTrackFitting_interface_alpaka_FitUtils_h
2 #define RecoTracker_PixelTrackFitting_interface_alpaka_FitUtils_h
3 
4 #include <alpaka/alpaka.hpp>
5 
6 #include <Eigen/Core>
7 
11 
12 namespace riemannFit {
13 
14  constexpr double epsilon = 1.e-4;
15 
18  template <int N>
19  using MatrixNd = Eigen::Matrix<double, N, N>;
20  template <int N>
21  using MatrixNplusONEd = Eigen::Matrix<double, N + 1, N + 1>;
22  template <int N>
23  using ArrayNd = Eigen::Array<double, N, N>;
24  template <int N>
25  using Matrix2Nd = Eigen::Matrix<double, 2 * N, 2 * N>;
26  template <int N>
27  using Matrix3Nd = Eigen::Matrix<double, 3 * N, 3 * N>;
28  template <int N>
29  using Matrix2xNd = Eigen::Matrix<double, 2, N>;
30  template <int N>
31  using Array2xNd = Eigen::Array<double, 2, N>;
32  template <int N>
33  using MatrixNx3d = Eigen::Matrix<double, N, 3>;
34  template <int N>
35  using MatrixNx5d = Eigen::Matrix<double, N, 5>;
36  template <int N>
37  using VectorNd = Eigen::Matrix<double, N, 1>;
38  template <int N>
39  using VectorNplusONEd = Eigen::Matrix<double, N + 1, 1>;
40  template <int N>
41  using Vector2Nd = Eigen::Matrix<double, 2 * N, 1>;
42  template <int N>
43  using Vector3Nd = Eigen::Matrix<double, 3 * N, 1>;
44  template <int N>
45  using RowVectorNd = Eigen::Matrix<double, 1, 1, N>;
46  template <int N>
47  using RowVector2Nd = Eigen::Matrix<double, 1, 2 * N>;
48 
49  using Matrix2x3d = Eigen::Matrix<double, 2, 3>;
50 
54  using Vector6f = Eigen::Matrix<double, 6, 1>;
55  // transformation between the "perigee" to cmssw localcoord frame
56  // the plane of the latter is the perigee plane...
57  // from //!<(phi,Tip,q/pt,cotan(theta)),Zip)
58  // to q/p,dx/dz,dy/dz,x,z
59  template <typename VI5, typename MI5, typename VO5, typename MO5>
60  inline void transformToPerigeePlane(VI5 const& ip, MI5 const& icov, VO5& op, MO5& ocov) {
61  auto sinTheta2 = 1. / (1. + ip(3) * ip(3));
62  auto sinTheta = std::sqrt(sinTheta2);
63  auto cosTheta = ip(3) * sinTheta;
64 
65  op(0) = sinTheta * ip(2);
66  op(1) = 0.;
67  op(2) = -ip(3);
68  op(3) = ip(1);
69  op(4) = -ip(4);
70 
71  Matrix5d jMat = Matrix5d::Zero();
72 
73  jMat(0, 2) = sinTheta;
74  jMat(0, 3) = -sinTheta2 * cosTheta * ip(2);
75  jMat(1, 0) = 1.;
76  jMat(2, 3) = -1.;
77  jMat(3, 1) = 1.;
78  jMat(4, 4) = -1;
79 
80  ocov = jMat * icov * jMat.transpose();
81  }
82 
83 } // namespace riemannFit
84 
86  namespace riemannFit {
87  using namespace ::riemannFit;
88 
89  template <typename TAcc, class C>
90  ALPAKA_FN_ACC void printIt(const TAcc& acc, C* m, const char* prefix = "") {
91 #ifdef RFIT_DEBUG
92  for (uint r = 0; r < m->rows(); ++r) {
93  for (uint c = 0; c < m->cols(); ++c) {
94  printf("%s Matrix(%d,%d) = %g\n", prefix, r, c, (*m)(r, c));
95  }
96  }
97 #endif
98  }
99 
103  template <typename T>
104  constexpr T sqr(const T a) {
105  return a * a;
106  }
107 
116  template <typename TAcc>
117  ALPAKA_FN_ACC ALPAKA_FN_INLINE double cross2D(const TAcc& acc, const Vector2d& a, const Vector2d& b) {
118  return a.x() * b.y() - a.y() * b.x();
119  }
120 
125  template <typename TAcc, typename M6xNf, typename M2Nd>
126  ALPAKA_FN_ACC void loadCovariance2D(const TAcc& acc, M6xNf const& ge, M2Nd& hits_cov) {
127  // Index numerology:
128  // i: index of the hits/point (0,..,3)
129  // j: index of space component (x,y,z)
130  // l: index of space components (x,y,z)
131  // ge is always in sync with the index i and is formatted as:
132  // ge[] ==> [xx, xy, yy, xz, yz, zz]
133  // in (j,l) notation, we have:
134  // ge[] ==> [(0,0), (0,1), (1,1), (0,2), (1,2), (2,2)]
135  // so the index ge_idx corresponds to the matrix elements:
136  // | 0 1 3 |
137  // | 1 2 4 |
138  // | 3 4 5 |
139  constexpr uint32_t hits_in_fit = M6xNf::ColsAtCompileTime;
140  for (uint32_t i = 0; i < hits_in_fit; ++i) {
141  {
142  constexpr uint32_t ge_idx = 0, j = 0, l = 0;
143  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
144  }
145  {
146  constexpr uint32_t ge_idx = 2, j = 1, l = 1;
147  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
148  }
149  {
150  constexpr uint32_t ge_idx = 1, j = 1, l = 0;
151  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
152  ge.col(i)[ge_idx];
153  }
154  }
155  }
156 
157  template <typename TAcc, typename M6xNf, typename M3xNd>
158  ALPAKA_FN_ACC void loadCovariance(const TAcc& acc, M6xNf const& ge, M3xNd& hits_cov) {
159  // Index numerology:
160  // i: index of the hits/point (0,..,3)
161  // j: index of space component (x,y,z)
162  // l: index of space components (x,y,z)
163  // ge is always in sync with the index i and is formatted as:
164  // ge[] ==> [xx, xy, yy, xz, yz, zz]
165  // in (j,l) notation, we have:
166  // ge[] ==> [(0,0), (0,1), (1,1), (0,2), (1,2), (2,2)]
167  // so the index ge_idx corresponds to the matrix elements:
168  // | 0 1 3 |
169  // | 1 2 4 |
170  // | 3 4 5 |
171  constexpr uint32_t hits_in_fit = M6xNf::ColsAtCompileTime;
172  for (uint32_t i = 0; i < hits_in_fit; ++i) {
173  {
174  constexpr uint32_t ge_idx = 0, j = 0, l = 0;
175  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
176  }
177  {
178  constexpr uint32_t ge_idx = 2, j = 1, l = 1;
179  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
180  }
181  {
182  constexpr uint32_t ge_idx = 5, j = 2, l = 2;
183  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
184  }
185  {
186  constexpr uint32_t ge_idx = 1, j = 1, l = 0;
187  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
188  ge.col(i)[ge_idx];
189  }
190  {
191  constexpr uint32_t ge_idx = 3, j = 2, l = 0;
192  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
193  ge.col(i)[ge_idx];
194  }
195  {
196  constexpr uint32_t ge_idx = 4, j = 2, l = 1;
197  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
198  ge.col(i)[ge_idx];
199  }
200  }
201  }
202 
211  template <typename TAcc>
212  ALPAKA_FN_ACC ALPAKA_FN_INLINE void par_uvrtopak(const TAcc& acc,
213  CircleFit& circle,
214  const double B,
215  const bool error) {
216  Vector3d par_pak;
217  const double temp0 = circle.par.head(2).squaredNorm();
218  const double temp1 = alpaka::math::sqrt(acc, temp0);
219  par_pak << alpaka::math::atan2(acc, circle.qCharge * circle.par(0), -circle.qCharge * circle.par(1)),
220  circle.qCharge * (temp1 - circle.par(2)), circle.par(2) * B;
221  if (error) {
222  const double temp2 = sqr(circle.par(0)) * 1. / temp0;
223  const double temp3 = 1. / temp1 * circle.qCharge;
224  Matrix3d j4Mat;
225  j4Mat << -circle.par(1) * temp2 * 1. / sqr(circle.par(0)), temp2 * 1. / circle.par(0), 0.,
226  circle.par(0) * temp3, circle.par(1) * temp3, -circle.qCharge, 0., 0., B;
227  circle.cov = j4Mat * circle.cov * j4Mat.transpose();
228  }
229  circle.par = par_pak;
230  }
231 
238  template <typename TAcc>
239  ALPAKA_FN_ACC ALPAKA_FN_INLINE void fromCircleToPerigee(const TAcc& acc, CircleFit& circle) {
240  Vector3d par_pak;
241  const double temp0 = circle.par.head(2).squaredNorm();
242  const double temp1 = alpaka::math::sqrt(acc, temp0);
243  par_pak << alpaka::math::atan2(acc, circle.qCharge * circle.par(0), -circle.qCharge * circle.par(1)),
244  circle.qCharge * (temp1 - circle.par(2)), circle.qCharge / circle.par(2);
245 
246  const double temp2 = sqr(circle.par(0)) * 1. / temp0;
247  const double temp3 = 1. / temp1 * circle.qCharge;
248  Matrix3d j4Mat;
249  j4Mat << -circle.par(1) * temp2 * 1. / sqr(circle.par(0)), temp2 * 1. / circle.par(0), 0., circle.par(0) * temp3,
250  circle.par(1) * temp3, -circle.qCharge, 0., 0., -circle.qCharge / (circle.par(2) * circle.par(2));
251  circle.cov = j4Mat * circle.cov * j4Mat.transpose();
252 
253  circle.par = par_pak;
254  }
255 
256  } // namespace riemannFit
257 
258 } // namespace ALPAKA_ACCELERATOR_NAMESPACE
259 
260 #endif // RecoTracker_PixelTrackFitting_interface_alpaka_FitUtils_h
Eigen::Matrix< double, 2, N > Matrix2xNd
Definition: FitUtils.h:29
Eigen::Matrix< double, 6, 1 > Vector6f
Definition: FitUtils.h:54
Eigen::Vector3d Vector3d
Definition: FitResult.h:11
Eigen::Matrix< double, 3 *N, 1 > Vector3Nd
Definition: FitUtils.h:43
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
Eigen::Matrix< double, 5, 5 > Matrix5d
Definition: FitResult.h:17
Eigen::Matrix< double, 1, 2 *N > RowVector2Nd
Definition: FitUtils.h:47
Definition: APVGainStruct.h:7
ALPAKA_FN_ACC void loadCovariance2D(const TAcc &acc, M6xNf const &ge, M2Nd &hits_cov)
Definition: FitUtils.h:126
Eigen::Matrix< double, 2 *N, 1 > Vector2Nd
Definition: FitUtils.h:41
Eigen::Matrix< double, 2, 3 > Matrix2x3d
Definition: FitUtils.h:49
Eigen::Matrix< double, 3 *N, 3 *N > Matrix3Nd
Definition: FitUtils.h:27
Eigen::VectorXd VectorXd
Definition: FitUtils.h:16
ALPAKA_FN_ACC ALPAKA_FN_INLINE double cross2D(const TAcc &acc, const Vector2d &a, const Vector2d &b)
Compute cross product of two 2D vector (assuming z component 0), returning z component of the result...
Definition: FitUtils.h:117
ALPAKA_FN_ACC ALPAKA_FN_INLINE void par_uvrtopak(const TAcc &acc, CircleFit &circle, const double B, const bool error)
Transform circle parameter from (X0,Y0,R) to (phi,Tip,p_t) and consequently covariance matrix...
Definition: FitUtils.h:212
Eigen::Array< double, N, N > ArrayNd
Definition: FitUtils.h:23
Eigen::Matrix< double, N+1, 1 > VectorNplusONEd
Definition: FitUtils.h:39
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:104
void transformToPerigeePlane(VI5 const &ip, MI5 const &icov, VO5 &op, MO5 &ocov)
Definition: FitUtils.h:60
Eigen::Matrix< double, N, 1 > VectorNd
Definition: FitUtils.h:37
T sqrt(T t)
Definition: SSEVec.h:23
Eigen::Matrix< double, N, N > MatrixNd
Definition: FitUtils.h:19
constexpr double epsilon
used in numerical derivative (J2 in Circle_fit())
Definition: FitUtils.h:14
Eigen::Matrix3f Matrix3f
Definition: FitUtils.h:51
ALPAKA_FN_ACC ALPAKA_FN_INLINE void fromCircleToPerigee(const TAcc &acc, CircleFit &circle)
Transform circle parameter from (X0,Y0,R) to (phi,Tip,q/R) and consequently covariance matrix...
Definition: FitUtils.h:239
Eigen::MatrixXd MatrixXd
Definition: FitUtils.h:17
Eigen::Matrix< double, N, 5 > MatrixNx5d
Definition: FitUtils.h:35
Eigen::Matrix< double, 2 *N, 2 *N > Matrix2Nd
Definition: FitUtils.h:25
ALPAKA_FN_ACC void loadCovariance(const TAcc &acc, M6xNf const &ge, M3xNd &hits_cov)
Definition: FitUtils.h:158
Eigen::Array< double, 2, N > Array2xNd
Definition: FitUtils.h:31
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
ALPAKA_FN_ACC void printIt(const TAcc &acc, C *m, const char *prefix="")
Definition: FitUtils.h:90
double b
Definition: hdecay.h:120
Eigen::Matrix< double, N, 3 > MatrixNx3d
Definition: FitUtils.h:33
Eigen::Matrix< double, N+1, N+1 > MatrixNplusONEd
Definition: FitUtils.h:21
double a
Definition: hdecay.h:121
Eigen::Matrix< double, 1, 1, N > RowVectorNd
Definition: FitUtils.h:45
Eigen::Vector3f Vector3f
Definition: FitUtils.h:52
long double T
Eigen::Vector4f Vector4f
Definition: FitUtils.h:53
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648