File indexing completed on 2024-04-06 12:28:36
0001 #ifndef RecoTracker_PixelTrackFitting_interface_alpaka_BrokenLine_h
0002 #define RecoTracker_PixelTrackFitting_interface_alpaka_BrokenLine_h
0003
0004 #include <alpaka/alpaka.hpp>
0005
0006 #include <Eigen/Core>
0007
0008 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0009 #include "RecoTracker/PixelTrackFitting/interface/alpaka/FitUtils.h"
0010
0011 namespace ALPAKA_ACCELERATOR_NAMESPACE::brokenline {
0012
0013 using namespace cms::alpakatools;
0014 using namespace ::riemannFit;
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 using karimaki_circle_fit = riemannFit::CircleFit;
0025
0026
0027
0028
0029 template <int n>
0030 struct PreparedBrokenLineData {
0031 int qCharge;
0032 riemannFit::Matrix2xNd<n> radii;
0033 riemannFit::VectorNd<n> sTransverse;
0034
0035 riemannFit::VectorNd<n> sTotal;
0036 riemannFit::VectorNd<n> zInSZplane;
0037 riemannFit::VectorNd<n> varBeta;
0038 };
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template <typename TAcc>
0060 ALPAKA_FN_ACC ALPAKA_FN_INLINE double multScatt(
0061 const TAcc& acc, const double& length, const double bField, const double radius, int layer, double slope) {
0062
0063 auto pt2 = alpaka::math::min(acc, 20., bField * radius);
0064 pt2 *= pt2;
0065 constexpr double inv_X0 = 0.06 / 16.;
0066
0067
0068
0069
0070
0071 constexpr double geometry_factor = 0.7;
0072 constexpr double fact = geometry_factor * riemannFit::sqr(13.6 / 1000.);
0073 return fact / (pt2 * (1. + riemannFit::sqr(slope))) * (alpaka::math::abs(acc, length) * inv_X0) *
0074 riemannFit::sqr(1. + 0.038 * log(alpaka::math::abs(acc, length) * inv_X0));
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084 template <typename TAcc>
0085 ALPAKA_FN_ACC ALPAKA_FN_INLINE riemannFit::Matrix2d rotationMatrix(const TAcc& acc, double slope) {
0086 riemannFit::Matrix2d rot;
0087 rot(0, 0) = 1. / alpaka::math::sqrt(acc, 1. + riemannFit::sqr(slope));
0088 rot(0, 1) = slope * rot(0, 0);
0089 rot(1, 0) = -rot(0, 1);
0090 rot(1, 1) = rot(0, 0);
0091 return rot;
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 template <typename TAcc>
0106 ALPAKA_FN_ACC ALPAKA_FN_INLINE void translateKarimaki(
0107 const TAcc& acc, karimaki_circle_fit& circle, double x0, double y0, riemannFit::Matrix3d& jacobian) {
0108
0109 using scalar = typename std::remove_reference<decltype(circle.par(0))>::type;
0110 scalar phi = circle.par(0);
0111 scalar dee = circle.par(1);
0112 scalar rho = circle.par(2);
0113
0114
0115 scalar sinPhi = alpaka::math::sin(acc, phi);
0116 scalar cosPhi = alpaka::math::cos(acc, phi);
0117
0118
0119 scalar deltaPara = x0 * cosPhi + y0 * sinPhi;
0120 scalar deltaOrth = x0 * sinPhi - y0 * cosPhi + dee;
0121 scalar tempSmallU = 1 + rho * dee;
0122 scalar tempC = -rho * y0 + tempSmallU * cosPhi;
0123 scalar tempB = rho * x0 + tempSmallU * sinPhi;
0124 scalar tempA = 2. * deltaOrth + rho * (riemannFit::sqr(deltaOrth) + riemannFit::sqr(deltaPara));
0125 scalar tempU = alpaka::math::sqrt(acc, 1. + rho * tempA);
0126
0127
0128 scalar xi = 1. / (riemannFit::sqr(tempB) + riemannFit::sqr(tempC));
0129 scalar tempV = 1. + rho * deltaOrth;
0130 scalar lambda = (0.5 * tempA) / (riemannFit::sqr(1. + tempU) * tempU);
0131 scalar mu = 1. / (tempU * (1. + tempU)) + rho * lambda;
0132 scalar zeta = riemannFit::sqr(deltaOrth) + riemannFit::sqr(deltaPara);
0133 jacobian << xi * tempSmallU * tempV, -xi * riemannFit::sqr(rho) * deltaOrth, xi * deltaPara,
0134 2. * mu * tempSmallU * deltaPara, 2. * mu * tempV, mu * zeta - lambda * tempA, 0, 0, 1.;
0135
0136
0137
0138 circle.par(0) = alpaka::math::atan2(acc, tempB, tempC);
0139
0140 circle.par(1) = tempA / (1 + tempU);
0141
0142
0143
0144
0145 circle.cov = jacobian * circle.cov * jacobian.transpose();
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 template <typename TAcc, typename M3xN, typename V4, int n>
0157 ALPAKA_FN_ACC ALPAKA_FN_INLINE void __attribute__((always_inline)) prepareBrokenLineData(
0158 const TAcc& acc, const M3xN& hits, const V4& fast_fit, const double bField, PreparedBrokenLineData<n>& results) {
0159 riemannFit::Vector2d dVec;
0160 riemannFit::Vector2d eVec;
0161
0162 int mId = 1;
0163
0164 if constexpr (n > 3) {
0165 riemannFit::Vector2d middle = 0.5 * (hits.block(0, n - 1, 2, 1) + hits.block(0, 0, 2, 1));
0166 auto d1 = (hits.block(0, n / 2, 2, 1) - middle).squaredNorm();
0167 auto d2 = (hits.block(0, n / 2 - 1, 2, 1) - middle).squaredNorm();
0168 mId = d1 < d2 ? n / 2 : n / 2 - 1;
0169 }
0170
0171 dVec = hits.block(0, mId, 2, 1) - hits.block(0, 0, 2, 1);
0172 eVec = hits.block(0, n - 1, 2, 1) - hits.block(0, mId, 2, 1);
0173 results.qCharge = riemannFit::cross2D(acc, dVec, eVec) > 0 ? -1 : 1;
0174
0175 const double slope = -results.qCharge / fast_fit(3);
0176
0177 riemannFit::Matrix2d rotMat = rotationMatrix(acc, slope);
0178
0179
0180 results.radii = hits.block(0, 0, 2, n) - fast_fit.head(2) * riemannFit::MatrixXd::Constant(1, n, 1);
0181 eVec = -fast_fit(2) * fast_fit.head(2) / fast_fit.head(2).norm();
0182 for (u_int i = 0; i < n; i++) {
0183 dVec = results.radii.block(0, i, 2, 1);
0184 results.sTransverse(i) =
0185 results.qCharge * fast_fit(2) *
0186 alpaka::math::atan2(acc, riemannFit::cross2D(acc, dVec, eVec), dVec.dot(eVec));
0187 }
0188 riemannFit::VectorNd<n> zVec = hits.block(2, 0, 1, n).transpose();
0189
0190
0191 riemannFit::Matrix2xNd<n> pointsSZ = riemannFit::Matrix2xNd<n>::Zero();
0192 for (u_int i = 0; i < n; i++) {
0193 pointsSZ(0, i) = results.sTransverse(i);
0194 pointsSZ(1, i) = zVec(i);
0195 pointsSZ.block(0, i, 2, 1) = rotMat * pointsSZ.block(0, i, 2, 1);
0196 }
0197 results.sTotal = pointsSZ.block(0, 0, 1, n).transpose();
0198 results.zInSZplane = pointsSZ.block(1, 0, 1, n).transpose();
0199
0200
0201 results.varBeta(0) = results.varBeta(n - 1) = 0;
0202 for (u_int i = 1; i < n - 1; i++) {
0203 results.varBeta(i) =
0204 multScatt(acc, results.sTotal(i + 1) - results.sTotal(i), bField, fast_fit(2), i + 2, slope) +
0205 multScatt(acc, results.sTotal(i) - results.sTotal(i - 1), bField, fast_fit(2), i + 1, slope);
0206 }
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 template <typename TAcc, int n>
0222 ALPAKA_FN_ACC ALPAKA_FN_INLINE riemannFit::MatrixNd<n> matrixC_u(const TAcc& acc,
0223 const riemannFit::VectorNd<n>& weights,
0224 const riemannFit::VectorNd<n>& sTotal,
0225 const riemannFit::VectorNd<n>& varBeta) {
0226 riemannFit::MatrixNd<n> c_uMat = riemannFit::MatrixNd<n>::Zero();
0227 for (u_int i = 0; i < n; i++) {
0228 c_uMat(i, i) = weights(i);
0229 if (i > 1)
0230 c_uMat(i, i) += 1. / (varBeta(i - 1) * riemannFit::sqr(sTotal(i) - sTotal(i - 1)));
0231 if (i > 0 && i < n - 1)
0232 c_uMat(i, i) +=
0233 (1. / varBeta(i)) * riemannFit::sqr((sTotal(i + 1) - sTotal(i - 1)) /
0234 ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))));
0235 if (i < n - 2)
0236 c_uMat(i, i) += 1. / (varBeta(i + 1) * riemannFit::sqr(sTotal(i + 1) - sTotal(i)));
0237
0238 if (i > 0 && i < n - 1)
0239 c_uMat(i, i + 1) =
0240 1. / (varBeta(i) * (sTotal(i + 1) - sTotal(i))) *
0241 (-(sTotal(i + 1) - sTotal(i - 1)) / ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))));
0242 if (i < n - 2)
0243 c_uMat(i, i + 1) +=
0244 1. / (varBeta(i + 1) * (sTotal(i + 1) - sTotal(i))) *
0245 (-(sTotal(i + 2) - sTotal(i)) / ((sTotal(i + 2) - sTotal(i + 1)) * (sTotal(i + 1) - sTotal(i))));
0246
0247 if (i < n - 2)
0248 c_uMat(i, i + 2) = 1. / (varBeta(i + 1) * (sTotal(i + 2) - sTotal(i + 1)) * (sTotal(i + 1) - sTotal(i)));
0249
0250 c_uMat(i, i) *= 0.5;
0251 }
0252 return c_uMat + c_uMat.transpose();
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 template <typename TAcc, typename M3xN, typename V4>
0266 ALPAKA_FN_ACC ALPAKA_FN_INLINE void fastFit(const TAcc& acc, const M3xN& hits, V4& result) {
0267 constexpr uint32_t n = M3xN::ColsAtCompileTime;
0268
0269 int mId = 1;
0270
0271 if constexpr (n > 3) {
0272 riemannFit::Vector2d middle = 0.5 * (hits.block(0, n - 1, 2, 1) + hits.block(0, 0, 2, 1));
0273 auto d1 = (hits.block(0, n / 2, 2, 1) - middle).squaredNorm();
0274 auto d2 = (hits.block(0, n / 2 - 1, 2, 1) - middle).squaredNorm();
0275 mId = d1 < d2 ? n / 2 : n / 2 - 1;
0276 }
0277
0278 const riemannFit::Vector2d a = hits.block(0, mId, 2, 1) - hits.block(0, 0, 2, 1);
0279 const riemannFit::Vector2d b = hits.block(0, n - 1, 2, 1) - hits.block(0, mId, 2, 1);
0280 const riemannFit::Vector2d c = hits.block(0, 0, 2, 1) - hits.block(0, n - 1, 2, 1);
0281
0282 auto tmp = 0.5 / riemannFit::cross2D(acc, c, a);
0283 result(0) = hits(0, 0) - (a(1) * c.squaredNorm() + c(1) * a.squaredNorm()) * tmp;
0284 result(1) = hits(1, 0) + (a(0) * c.squaredNorm() + c(0) * a.squaredNorm()) * tmp;
0285
0286
0287 result(2) = alpaka::math::sqrt(acc, a.squaredNorm() * b.squaredNorm() * c.squaredNorm()) /
0288 (2. * alpaka::math::abs(acc, riemannFit::cross2D(acc, b, a)));
0289
0290
0291 const riemannFit::Vector2d d = hits.block(0, 0, 2, 1) - result.head(2);
0292 const riemannFit::Vector2d e = hits.block(0, n - 1, 2, 1) - result.head(2);
0293
0294 result(3) = result(2) * atan2(riemannFit::cross2D(acc, d, e), d.dot(e)) / (hits(2, n - 1) - hits(2, 0));
0295
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 template <typename TAcc, typename M3xN, typename M6xN, typename V4, int n>
0323 ALPAKA_FN_ACC ALPAKA_FN_INLINE void circleFit(const TAcc& acc,
0324 const M3xN& hits,
0325 const M6xN& hits_ge,
0326 const V4& fast_fit,
0327 const double bField,
0328 PreparedBrokenLineData<n>& data,
0329 karimaki_circle_fit& circle_results) {
0330 circle_results.qCharge = data.qCharge;
0331 auto& radii = data.radii;
0332 const auto& sTransverse = data.sTransverse;
0333 const auto& sTotal = data.sTotal;
0334 auto& zInSZplane = data.zInSZplane;
0335 auto& varBeta = data.varBeta;
0336 const double slope = -circle_results.qCharge / fast_fit(3);
0337 varBeta *= 1. + riemannFit::sqr(slope);
0338
0339 for (u_int i = 0; i < n; i++) {
0340 zInSZplane(i) = radii.block(0, i, 2, 1).norm() - fast_fit(2);
0341 }
0342
0343 riemannFit::Matrix2d vMat;
0344 riemannFit::VectorNd<n> weightsVec;
0345 riemannFit::Matrix2d rotMat;
0346 for (u_int i = 0; i < n; i++) {
0347 vMat(0, 0) = hits_ge.col(i)[0];
0348 vMat(0, 1) = vMat(1, 0) = hits_ge.col(i)[1];
0349 vMat(1, 1) = hits_ge.col(i)[2];
0350 rotMat = rotationMatrix(acc, -radii(0, i) / radii(1, i));
0351 weightsVec(i) =
0352 1. / ((rotMat * vMat * rotMat.transpose())(1, 1));
0353 }
0354
0355 riemannFit::VectorNplusONEd<n> r_uVec;
0356 r_uVec(n) = 0;
0357 for (u_int i = 0; i < n; i++) {
0358 r_uVec(i) = weightsVec(i) * zInSZplane(i);
0359 }
0360
0361 riemannFit::MatrixNplusONEd<n> c_uMat;
0362 c_uMat.block(0, 0, n, n) = matrixC_u(acc, weightsVec, sTransverse, varBeta);
0363 c_uMat(n, n) = 0;
0364
0365 for (u_int i = 0; i < n; i++) {
0366 c_uMat(i, n) = 0;
0367 if (i > 0 && i < n - 1) {
0368 c_uMat(i, n) +=
0369 -(sTransverse(i + 1) - sTransverse(i - 1)) * (sTransverse(i + 1) - sTransverse(i - 1)) /
0370 (2. * varBeta(i) * (sTransverse(i + 1) - sTransverse(i)) * (sTransverse(i) - sTransverse(i - 1)));
0371 }
0372 if (i > 1) {
0373 c_uMat(i, n) +=
0374 (sTransverse(i) - sTransverse(i - 2)) / (2. * varBeta(i - 1) * (sTransverse(i) - sTransverse(i - 1)));
0375 }
0376 if (i < n - 2) {
0377 c_uMat(i, n) +=
0378 (sTransverse(i + 2) - sTransverse(i)) / (2. * varBeta(i + 1) * (sTransverse(i + 1) - sTransverse(i)));
0379 }
0380 c_uMat(n, i) = c_uMat(i, n);
0381 if (i > 0 && i < n - 1)
0382 c_uMat(n, n) += riemannFit::sqr(sTransverse(i + 1) - sTransverse(i - 1)) / (4. * varBeta(i));
0383 }
0384
0385 #ifdef CPP_DUMP
0386 std::cout << "CU5\n" << c_uMat << std::endl;
0387 #endif
0388 riemannFit::MatrixNplusONEd<n> iMat;
0389 math::cholesky::invert(c_uMat, iMat);
0390 #ifdef CPP_DUMP
0391 std::cout << "I5\n" << iMat << std::endl;
0392 #endif
0393 riemannFit::VectorNplusONEd<n> uVec = iMat * r_uVec;
0394
0395
0396
0397 radii.block(0, 0, 2, 1) /= radii.block(0, 0, 2, 1).norm();
0398 radii.block(0, 1, 2, 1) /= radii.block(0, 1, 2, 1).norm();
0399
0400 riemannFit::Vector2d dVec = hits.block(0, 0, 2, 1) + (-zInSZplane(0) + uVec(0)) * radii.block(0, 0, 2, 1);
0401 riemannFit::Vector2d eVec = hits.block(0, 1, 2, 1) + (-zInSZplane(1) + uVec(1)) * radii.block(0, 1, 2, 1);
0402 auto eMinusd = eVec - dVec;
0403 auto eMinusd2 = eMinusd.squaredNorm();
0404 auto tmp1 = 1. / eMinusd2;
0405 auto tmp2 = alpaka::math::sqrt(acc, riemannFit::sqr(fast_fit(2)) - 0.25 * eMinusd2);
0406
0407 circle_results.par << atan2(eMinusd(1), eMinusd(0)), circle_results.qCharge * (tmp2 - fast_fit(2)),
0408 circle_results.qCharge * (1. / fast_fit(2) + uVec(n));
0409
0410 tmp2 = 1. / tmp2;
0411
0412 riemannFit::Matrix3d jacobian;
0413 jacobian << (radii(1, 0) * eMinusd(0) - eMinusd(1) * radii(0, 0)) * tmp1,
0414 (radii(1, 1) * eMinusd(0) - eMinusd(1) * radii(0, 1)) * tmp1, 0,
0415 circle_results.qCharge * (eMinusd(0) * radii(0, 0) + eMinusd(1) * radii(1, 0)) * tmp2,
0416 circle_results.qCharge * (eMinusd(0) * radii(0, 1) + eMinusd(1) * radii(1, 1)) * tmp2, 0, 0, 0,
0417 circle_results.qCharge;
0418
0419 circle_results.cov << iMat(0, 0), iMat(0, 1), iMat(0, n), iMat(1, 0), iMat(1, 1), iMat(1, n), iMat(n, 0),
0420 iMat(n, 1), iMat(n, n);
0421
0422 circle_results.cov = jacobian * circle_results.cov * jacobian.transpose();
0423
0424
0425
0426 translateKarimaki(acc, circle_results, 0.5 * eMinusd(0), 0.5 * eMinusd(1), jacobian);
0427 circle_results.cov(0, 0) +=
0428 (1 + riemannFit::sqr(slope)) * multScatt(acc, sTotal(1) - sTotal(0), bField, fast_fit(2), 2, slope);
0429
0430
0431
0432 translateKarimaki(acc, circle_results, dVec(0), dVec(1), jacobian);
0433
0434
0435 circle_results.chi2 = 0;
0436 for (u_int i = 0; i < n; i++) {
0437 circle_results.chi2 += weightsVec(i) * riemannFit::sqr(zInSZplane(i) - uVec(i));
0438 if (i > 0 && i < n - 1)
0439 circle_results.chi2 +=
0440 riemannFit::sqr(uVec(i - 1) / (sTransverse(i) - sTransverse(i - 1)) -
0441 uVec(i) * (sTransverse(i + 1) - sTransverse(i - 1)) /
0442 ((sTransverse(i + 1) - sTransverse(i)) * (sTransverse(i) - sTransverse(i - 1))) +
0443 uVec(i + 1) / (sTransverse(i + 1) - sTransverse(i)) +
0444 (sTransverse(i + 1) - sTransverse(i - 1)) * uVec(n) / 2) /
0445 varBeta(i);
0446 }
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471 template <typename TAcc, typename V4, typename M6xN, int n>
0472 ALPAKA_FN_ACC ALPAKA_FN_INLINE void lineFit(const TAcc& acc,
0473 const M6xN& hits_ge,
0474 const V4& fast_fit,
0475 const double bField,
0476 const PreparedBrokenLineData<n>& data,
0477 riemannFit::LineFit& line_results) {
0478 const auto& radii = data.radii;
0479 const auto& sTotal = data.sTotal;
0480 const auto& zInSZplane = data.zInSZplane;
0481 const auto& varBeta = data.varBeta;
0482
0483 const double slope = -data.qCharge / fast_fit(3);
0484 riemannFit::Matrix2d rotMat = rotationMatrix(acc, slope);
0485
0486 riemannFit::Matrix3d vMat = riemannFit::Matrix3d::Zero();
0487 riemannFit::Matrix2x3d jacobXYZtosZ =
0488 riemannFit::Matrix2x3d::Zero();
0489 riemannFit::VectorNd<n> weights = riemannFit::VectorNd<n>::Zero();
0490 for (u_int i = 0; i < n; i++) {
0491 vMat(0, 0) = hits_ge.col(i)[0];
0492 vMat(0, 1) = vMat(1, 0) = hits_ge.col(i)[1];
0493 vMat(0, 2) = vMat(2, 0) = hits_ge.col(i)[3];
0494 vMat(1, 1) = hits_ge.col(i)[2];
0495 vMat(2, 1) = vMat(1, 2) = hits_ge.col(i)[4];
0496 vMat(2, 2) = hits_ge.col(i)[5];
0497 auto tmp = 1. / radii.block(0, i, 2, 1).norm();
0498 jacobXYZtosZ(0, 0) = radii(1, i) * tmp;
0499 jacobXYZtosZ(0, 1) = -radii(0, i) * tmp;
0500 jacobXYZtosZ(1, 2) = 1.;
0501 weights(i) = 1. / ((rotMat * jacobXYZtosZ * vMat * jacobXYZtosZ.transpose() * rotMat.transpose())(
0502 1, 1));
0503 }
0504
0505 riemannFit::VectorNd<n> r_u;
0506 for (u_int i = 0; i < n; i++) {
0507 r_u(i) = weights(i) * zInSZplane(i);
0508 }
0509 #ifdef CPP_DUMP
0510 std::cout << "CU4\n" << matrixC_u(w, sTotal, varBeta) << std::endl;
0511 #endif
0512 riemannFit::MatrixNd<n> iMat;
0513 math::cholesky::invert(matrixC_u(acc, weights, sTotal, varBeta), iMat);
0514 #ifdef CPP_DUMP
0515 std::cout << "I4\n" << iMat << std::endl;
0516 #endif
0517
0518 riemannFit::VectorNd<n> uVec = iMat * r_u;
0519
0520
0521 line_results.par << (uVec(1) - uVec(0)) / (sTotal(1) - sTotal(0)), uVec(0);
0522 auto idiff = 1. / (sTotal(1) - sTotal(0));
0523 line_results.cov << (iMat(0, 0) - 2 * iMat(0, 1) + iMat(1, 1)) * riemannFit::sqr(idiff) +
0524 multScatt(acc, sTotal(1) - sTotal(0), bField, fast_fit(2), 2, slope),
0525 (iMat(0, 1) - iMat(0, 0)) * idiff, (iMat(0, 1) - iMat(0, 0)) * idiff, iMat(0, 0);
0526
0527
0528 riemannFit::Matrix2d jacobian;
0529 jacobian(0, 0) = 1.;
0530 jacobian(0, 1) = 0;
0531 jacobian(1, 0) = -sTotal(0);
0532 jacobian(1, 1) = 1.;
0533 line_results.par(1) += -line_results.par(0) * sTotal(0);
0534 line_results.cov = jacobian * line_results.cov * jacobian.transpose();
0535
0536
0537 auto tmp = rotMat(0, 0) - line_results.par(0) * rotMat(0, 1);
0538 jacobian(1, 1) = 1. / tmp;
0539 jacobian(0, 0) = jacobian(1, 1) * jacobian(1, 1);
0540 jacobian(0, 1) = 0;
0541 jacobian(1, 0) = line_results.par(1) * rotMat(0, 1) * jacobian(0, 0);
0542 line_results.par(1) = line_results.par(1) * jacobian(1, 1);
0543 line_results.par(0) = (rotMat(0, 1) + line_results.par(0) * rotMat(0, 0)) * jacobian(1, 1);
0544 line_results.cov = jacobian * line_results.cov * jacobian.transpose();
0545
0546
0547 line_results.chi2 = 0;
0548 for (u_int i = 0; i < n; i++) {
0549 line_results.chi2 += weights(i) * riemannFit::sqr(zInSZplane(i) - uVec(i));
0550 if (i > 0 && i < n - 1)
0551 line_results.chi2 += riemannFit::sqr(uVec(i - 1) / (sTotal(i) - sTotal(i - 1)) -
0552 uVec(i) * (sTotal(i + 1) - sTotal(i - 1)) /
0553 ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))) +
0554 uVec(i + 1) / (sTotal(i + 1) - sTotal(i))) /
0555 varBeta(i);
0556 }
0557 }
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594 template <int n>
0595 class helixFit {
0596 public:
0597 template <typename TAcc>
0598 ALPAKA_FN_ACC ALPAKA_FN_INLINE void operator()(const TAcc& acc,
0599 const riemannFit::Matrix3xNd<n>* hits,
0600 const Eigen::Matrix<float, 6, 4>* hits_ge,
0601 const double bField,
0602 riemannFit::HelixFit* helix) const {
0603 riemannFit::Vector4d fast_fit;
0604 fastFit(acc, *hits, fast_fit);
0605
0606 PreparedBrokenLineData<n> data;
0607 karimaki_circle_fit circle;
0608 riemannFit::LineFit line;
0609 riemannFit::Matrix3d jacobian;
0610
0611 prepareBrokenLineData(acc, *hits, fast_fit, bField, data);
0612 lineFit(acc, *hits_ge, fast_fit, bField, data, line);
0613 circleFit(acc, *hits, *hits_ge, fast_fit, bField, data, circle);
0614
0615
0616 jacobian << 1., 0, 0, 0, 1., 0, 0, 0,
0617 -alpaka::math::abs(acc, circle.par(2)) * bField / (riemannFit::sqr(circle.par(2)) * circle.par(2));
0618 circle.par(2) = bField / alpaka::math::abs(acc, circle.par(2));
0619 circle.cov = jacobian * circle.cov * jacobian.transpose();
0620
0621 helix->par << circle.par, line.par;
0622 helix->cov = riemannFit::MatrixXd::Zero(5, 5);
0623 helix->cov.block(0, 0, 3, 3) = circle.cov;
0624 helix->cov.block(3, 3, 2, 2) = line.cov;
0625 helix->qCharge = circle.qCharge;
0626 helix->chi2_circle = circle.chi2;
0627 helix->chi2_line = line.chi2;
0628 }
0629 };
0630
0631 }
0632
0633 #endif