CMS 3D CMS Logo

Functions
ALPAKA_ACCELERATOR_NAMESPACE::riemannFit Namespace Reference

Functions

template<typename TAcc , typename M2xN >
ALPAKA_FN_ACC ALPAKA_FN_INLINE int32_t charge (const TAcc &acc, const M2xN &p2D, const Vector3d &par_uvr)
 Find particle q considering the sign of cross product between particles velocity (estimated by the first 2 hits) and the vector radius between the first hit and the center of the fitted circle. More...
 
template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE CircleFit circleFit (const TAcc &acc, const M2xN &hits2D, const Matrix2Nd< N > &hits_cov2D, const V4 &fast_fit, const VectorNd< N > &rad, const double bField, const bool error)
 Fit a generic number of 2D points with a circle using Riemann-Chernov algorithm. Covariance matrix of fitted parameter is optionally computed. Multiple scattering (currently only in barrel layer) is optionally handled. More...
 
template<typename TAcc , typename VNd1 , typename VNd2 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void computeRadLenUniformMaterial (const TAcc &acc, const VNd1 &length_values, VNd2 &rad_lengths)
 
template<typename TAcc , typename M2xN , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd< Ncov_carttorad (const TAcc &acc, const M2xN &p2D, const Matrix2Nd< N > &cov_cart, const VectorNd< N > &rad)
 Transform covariance matrix from Cartesian coordinates (only transverse plane component) to radial coordinates (both radial and tangential component but only diagonal terms, correlation between different point are not managed). More...
 
template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd< Ncov_carttorad_prefit (const TAcc &acc, const M2xN &p2D, const Matrix2Nd< N > &cov_cart, V4 &fast_fit, const VectorNd< N > &rad)
 Transform covariance matrix from Cartesian coordinates (only transverse plane component) to coordinates system orthogonal to the pre-fitted circle in each point. Further information in attached documentation. More...
 
template<typename TAcc , typename M2xN , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE Matrix2Nd< Ncov_radtocart (const TAcc &acc, const M2xN &p2D, const MatrixNd< N > &cov_rad, const VectorNd< N > &rad)
 Transform covariance matrix from radial (only tangential component) to Cartesian coordinates (only transverse plane component). More...
 
template<typename TAcc >
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. More...
 
template<typename TAcc , typename M3xN , typename V4 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void fastFit (const TAcc &acc, const M3xN &hits, V4 &result)
 A very fast helix fit: it fits a circle by three points (first, middle and last point) and a line by two points (first and last). More...
 
template<typename TAcc >
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. More...
 
template<typename TAcc , typename M3xN , typename M6xN , typename V4 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE LineFit lineFit (const TAcc &acc, const M3xN &hits, const M6xN &hits_ge, const CircleFit &circle, const V4 &fast_fit, const double bField, const bool error)
 Perform an ordinary least square fit in the s-z plane to compute the parameters cotTheta and Zip. More...
 
template<typename TAcc , typename M6xNf , typename M3xNd >
ALPAKA_FN_ACC void loadCovariance (const TAcc &acc, M6xNf const &ge, M3xNd &hits_cov)
 
template<typename TAcc , typename M6xNf , typename M2Nd >
ALPAKA_FN_ACC void loadCovariance2D (const TAcc &acc, M6xNf const &ge, M2Nd &hits_cov)
 
template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector2d min_eigen2D (const TAcc &acc, const Matrix2d &aMat, double &chi2)
 2D version of min_eigen3D(). More...
 
template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector3d min_eigen3D (const TAcc &acc, const Matrix3d &A, double &chi2)
 Compute the eigenvector associated to the minimum eigenvalue. More...
 
template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector3d min_eigen3D_fast (const TAcc &acc, const Matrix3d &A)
 A faster version of min_eigen3D() where double precision is not needed. More...
 
template<typename TAcc >
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. More...
 
template<typename TAcc , class C >
ALPAKA_FN_ACC void printIt (const TAcc &acc, C *m, const char *prefix="")
 
template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE MatrixNd< Nscatter_cov_rad (const TAcc &acc, const M2xN &p2D, const V4 &fast_fit, VectorNd< N > const &rad, double B)
 Compute the covariance matrix (in radial coordinates) of points in the transverse plane due to multiple Coulomb scattering. More...
 
template<typename TAcc , typename V4 , typename VNd1 , typename VNd2 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE auto scatterCovLine (const TAcc &acc, Matrix2d const *cov_sz, const V4 &fast_fit, VNd1 const &s_arcs, VNd2 const &z_values, const double theta, const double bField, MatrixNd< N > &ret)
 Compute the covariance matrix along cartesian S-Z of points due to multiple Coulomb scattering to be used in the line_fit, for the barrel and forward cases. The input covariance matrix is in the variables s-z, original and unrotated. The multiple scattering component is computed in the usual linear approximation, using the 3D path which is computed as the squared root of the squared sum of the s and z components passed in. Internally a rotation by theta is performed and the covariance matrix returned is the one in the direction orthogonal to the rotated S3D axis, i.e. along the rotated Z axis. The choice of the rotation is not arbitrary, but derived from the fact that putting the horizontal axis along the S3D direction allows the usage of the ordinary least squared fitting techiques with the trivial parametrization y = mx + q, avoiding the patological case with m = +/- inf, that would correspond to the case at eta = 0. More...
 
template<typename T >
constexpr T sqr (const T a)
 raise to square. More...
 
template<typename TAcc , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd< NweightCircle (const TAcc &acc, const MatrixNd< N > &cov_rad_inv)
 Compute the points' weights' vector for the circle fit when multiple scattering is managed. Further information in attached documentation. More...
 

Function Documentation

◆ charge()

template<typename TAcc , typename M2xN >
ALPAKA_FN_ACC ALPAKA_FN_INLINE int32_t ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::charge ( const TAcc &  acc,
const M2xN &  p2D,
const Vector3d &  par_uvr 
)

Find particle q considering the sign of cross product between particles velocity (estimated by the first 2 hits) and the vector radius between the first hit and the center of the fitted circle.

Parameters
p2D2D points in transverse plane.
par_uvrresult of the circle fit in this form: (X0,Y0,R).
Returns
q int 1 or -1.

Definition at line 297 of file RiemannFit.h.

Referenced by circleFit().

297  {
298  return ((p2D(0, 1) - p2D(0, 0)) * (par_uvr.y() - p2D(1, 0)) - (p2D(1, 1) - p2D(1, 0)) * (par_uvr.x() - p2D(0, 0)) >
299  0)
300  ? -1
301  : 1;
302  }

◆ circleFit()

template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE CircleFit ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::circleFit ( const TAcc &  acc,
const M2xN &  hits2D,
const Matrix2Nd< N > &  hits_cov2D,
const V4 &  fast_fit,
const VectorNd< N > &  rad,
const double  bField,
const bool  error 
)

Fit a generic number of 2D points with a circle using Riemann-Chernov algorithm. Covariance matrix of fitted parameter is optionally computed. Multiple scattering (currently only in barrel layer) is optionally handled.

Parameters
hits2D2D points to be fitted.
hits_cov2Dcovariance matrix of 2D points.
fast_fitpre-fit result in this form: (X0,Y0,R,tan(theta)). (tan(theta) is not used).
bFieldmagnetic field
errorflag for error computation.
scatteringflag for multiple scattering
Returns
circle circle_fit: -par parameter of the fitted circle in this form (X0,Y0,R);
-cov covariance matrix of the fitted parameter (not initialized if error = false);
-q charge of the particle;
-chi2.
Warning
hits must be passed ordered from inner to outer layer (double hits on the same layer must be ordered too) so that multiple scattering is treated properly.
Multiple scattering for barrel is still not tested.
Multiple scattering for endcap hits is not handled (yet). Do not fit endcap hits with scattering = true !

Definition at line 465 of file RiemannFit.h.

References a, funct::abs(), b, Calorimetry_cff::bField, charge(), nano_mu_local_reco_cff::chi2, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), cov_carttorad_prefit(), cov_radtocart(), dumpMFGeometry_cfg::delta, geometryDiff::epsilon, relativeConstraints::error, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, mps_fire::i, l1tstage2_dqm_sourceclient-live_cfg::invert, dqmiolumiharvest::j, dqmdumpme::k, MainPageGenerator::l, CaloTowersParam_cfi::mc, min_eigen3D(), min_eigen3D_fast(), N, dqmiodumpmetadata::n, printIt(), scatter_cov_rad(), Validation_hcalonly_cfi::sign, sqr(), mathSSE::sqrt(), submitPVValidationJobs::t, FrontierCondition_GT_autoExpress_cfi::t0, RandomServiceHelper::t1, createJobs::tmp, parallelization::uint, mps_merge::weight, and weightCircle().

Referenced by ALPAKA_ACCELERATOR_NAMESPACE::Kernel_CircleFit< N, TrackerTraits >::operator()(), and riemannFit::helixFit< N >::operator()().

471  {
472 #ifdef RFIT_DEBUG
473  printf("circle_fit - enter\n");
474 #endif
475  // INITIALIZATION
476  Matrix2Nd<N> vMat = hits_cov2D;
477  constexpr uint n = N;
478  printIt(&hits2D, "circle_fit - hits2D:");
479  printIt(&hits_cov2D, "circle_fit - hits_cov2D:");
480 
481 #ifdef RFIT_DEBUG
482  printf("circle_fit - WEIGHT COMPUTATION\n");
483 #endif
484  // WEIGHT COMPUTATION
485  VectorNd<N> weight;
486  MatrixNd<N> gMat;
487  double renorm;
488  {
489  MatrixNd<N> cov_rad = cov_carttorad_prefit(acc, hits2D, vMat, fast_fit, rad).asDiagonal();
490  MatrixNd<N> scatterCovRadMat = scatter_cov_rad(acc, hits2D, fast_fit, rad, bField);
491  printIt(&scatterCovRadMat, "circle_fit - scatter_cov_rad:");
492  printIt(&hits2D, "circle_fit - hits2D bis:");
493 #ifdef RFIT_DEBUG
494  printf("Address of hits2D: a) %p\n", &hits2D);
495 #endif
496  vMat += cov_radtocart(acc, hits2D, scatterCovRadMat, rad);
497  printIt(&vMat, "circle_fit - V:");
498  cov_rad += scatterCovRadMat;
499  printIt(&cov_rad, "circle_fit - cov_rad:");
500  math::cholesky::invert(cov_rad, gMat);
501  // gMat = cov_rad.inverse();
502  renorm = gMat.sum();
503  gMat *= 1. / renorm;
504  weight = weightCircle(acc, gMat);
505  }
506  printIt(&weight, "circle_fit - weight:");
507 
508  // SPACE TRANSFORMATION
509 #ifdef RFIT_DEBUG
510  printf("circle_fit - SPACE TRANSFORMATION\n");
511 #endif
512 
513  // center
514 #ifdef RFIT_DEBUG
515  printf("Address of hits2D: b) %p\n", &hits2D);
516 #endif
517  const Vector2d hCentroid = hits2D.rowwise().mean(); // centroid
518  printIt(&hCentroid, "circle_fit - h_:");
519  Matrix3xNd<N> p3D;
520  p3D.block(0, 0, 2, n) = hits2D.colwise() - hCentroid;
521  printIt(&p3D, "circle_fit - p3D: a)");
522  Vector2Nd<N> mc; // centered hits, used in error computation
523  mc << p3D.row(0).transpose(), p3D.row(1).transpose();
524  printIt(&mc, "circle_fit - mc(centered hits):");
525 
526  // scale
527  const double tempQ = mc.squaredNorm();
528  const double tempS = sqrt(n * 1. / tempQ); // scaling factor
529  p3D.block(0, 0, 2, n) *= tempS;
530 
531  // project on paraboloid
532  p3D.row(2) = p3D.block(0, 0, 2, n).colwise().squaredNorm();
533  printIt(&p3D, "circle_fit - p3D: b)");
534 
535 #ifdef RFIT_DEBUG
536  printf("circle_fit - COST FUNCTION\n");
537 #endif
538  // COST FUNCTION
539 
540  // compute
541  Vector3d r0;
542  r0.noalias() = p3D * weight; // center of gravity
543  const Matrix3xNd<N> xMat = p3D.colwise() - r0;
544  Matrix3d aMat = xMat * gMat * xMat.transpose();
545  printIt(&aMat, "circle_fit - A:");
546 
547 #ifdef RFIT_DEBUG
548  printf("circle_fit - MINIMIZE\n");
549 #endif
550  // minimize
551  double chi2;
552  Vector3d vVec = min_eigen3D(acc, aMat, chi2);
553 #ifdef RFIT_DEBUG
554  printf("circle_fit - AFTER MIN_EIGEN\n");
555 #endif
556  printIt(&vVec, "v BEFORE INVERSION");
557  vVec *= (vVec(2) > 0) ? 1 : -1; // TO FIX dovrebbe essere N(3)>0
558  printIt(&vVec, "v AFTER INVERSION");
559  // This hack to be able to run on GPU where the automatic assignment to a
560  // double from the vector multiplication is not working.
561 #ifdef RFIT_DEBUG
562  printf("circle_fit - AFTER MIN_EIGEN 1\n");
563 #endif
564  Eigen::Matrix<double, 1, 1> cm;
565 #ifdef RFIT_DEBUG
566  printf("circle_fit - AFTER MIN_EIGEN 2\n");
567 #endif
568  cm = -vVec.transpose() * r0;
569 #ifdef RFIT_DEBUG
570  printf("circle_fit - AFTER MIN_EIGEN 3\n");
571 #endif
572  const double tempC = cm(0, 0);
573 
574 #ifdef RFIT_DEBUG
575  printf("circle_fit - COMPUTE CIRCLE PARAMETER\n");
576 #endif
577  // COMPUTE CIRCLE PARAMETER
578 
579  // auxiliary quantities
580  const double tempH = sqrt(1. - sqr(vVec(2)) - 4. * tempC * vVec(2));
581  const double v2x2_inv = 1. / (2. * vVec(2));
582  const double s_inv = 1. / tempS;
583  Vector3d par_uvr; // used in error propagation
584  par_uvr << -vVec(0) * v2x2_inv, -vVec(1) * v2x2_inv, tempH * v2x2_inv;
585 
586  CircleFit circle;
587  circle.par << par_uvr(0) * s_inv + hCentroid(0), par_uvr(1) * s_inv + hCentroid(1), par_uvr(2) * s_inv;
588  circle.qCharge = charge(acc, hits2D, circle.par);
589  circle.chi2 = abs(chi2) * renorm / sqr(2 * vVec(2) * par_uvr(2) * tempS);
590  printIt(&circle.par, "circle_fit - CIRCLE PARAMETERS:");
591  printIt(&circle.cov, "circle_fit - CIRCLE COVARIANCE:");
592 #ifdef RFIT_DEBUG
593  printf("circle_fit - CIRCLE CHARGE: %d\n", circle.qCharge);
594 #endif
595 
596 #ifdef RFIT_DEBUG
597  printf("circle_fit - ERROR PROPAGATION\n");
598 #endif
599  // ERROR PROPAGATION
600  if (error) {
601 #ifdef RFIT_DEBUG
602  printf("circle_fit - ERROR PRPAGATION ACTIVATED\n");
603 #endif
604  ArrayNd<N> vcsMat[2][2]; // cov matrix of center & scaled points
605  MatrixNd<N> cMat[3][3]; // cov matrix of 3D transformed points
606 #ifdef RFIT_DEBUG
607  printf("circle_fit - ERROR PRPAGATION ACTIVATED 2\n");
608 #endif
609  {
610  Eigen::Matrix<double, 1, 1> cm;
611  Eigen::Matrix<double, 1, 1> cm2;
612  cm = mc.transpose() * vMat * mc;
613  const double tempC2 = cm(0, 0);
614  Matrix2Nd<N> tempVcsMat;
615  tempVcsMat.template triangularView<Eigen::Upper>() =
616  (sqr(tempS) * vMat + sqr(sqr(tempS)) * 1. / (4. * tempQ * n) *
617  (2. * vMat.squaredNorm() + 4. * tempC2) * // mc.transpose() * V * mc) *
618  (mc * mc.transpose()));
619 
620  printIt(&tempVcsMat, "circle_fit - Vcs:");
621  cMat[0][0] = tempVcsMat.block(0, 0, n, n).template selfadjointView<Eigen::Upper>();
622  vcsMat[0][1] = tempVcsMat.block(0, n, n, n);
623  cMat[1][1] = tempVcsMat.block(n, n, n, n).template selfadjointView<Eigen::Upper>();
624  vcsMat[1][0] = vcsMat[0][1].transpose();
625  printIt(&tempVcsMat, "circle_fit - Vcs:");
626  }
627 
628  {
629  const ArrayNd<N> t0 = (VectorXd::Constant(n, 1.) * p3D.row(0));
630  const ArrayNd<N> t1 = (VectorXd::Constant(n, 1.) * p3D.row(1));
631  const ArrayNd<N> t00 = p3D.row(0).transpose() * p3D.row(0);
632  const ArrayNd<N> t01 = p3D.row(0).transpose() * p3D.row(1);
633  const ArrayNd<N> t11 = p3D.row(1).transpose() * p3D.row(1);
634  const ArrayNd<N> t10 = t01.transpose();
635  vcsMat[0][0] = cMat[0][0];
636  cMat[0][1] = vcsMat[0][1];
637  cMat[0][2] = 2. * (vcsMat[0][0] * t0 + vcsMat[0][1] * t1);
638  vcsMat[1][1] = cMat[1][1];
639  cMat[1][2] = 2. * (vcsMat[1][0] * t0 + vcsMat[1][1] * t1);
640  MatrixNd<N> tmp;
641  tmp.template triangularView<Eigen::Upper>() =
642  (2. * (vcsMat[0][0] * vcsMat[0][0] + vcsMat[0][0] * vcsMat[0][1] + vcsMat[1][1] * vcsMat[1][0] +
643  vcsMat[1][1] * vcsMat[1][1]) +
644  4. * (vcsMat[0][0] * t00 + vcsMat[0][1] * t01 + vcsMat[1][0] * t10 + vcsMat[1][1] * t11))
645  .matrix();
646  cMat[2][2] = tmp.template selfadjointView<Eigen::Upper>();
647  }
648  printIt(&cMat[0][0], "circle_fit - C[0][0]:");
649 
650  Matrix3d c0Mat; // cov matrix of center of gravity (r0.x,r0.y,r0.z)
651  for (uint i = 0; i < 3; ++i) {
652  for (uint j = i; j < 3; ++j) {
653  Eigen::Matrix<double, 1, 1> tmp;
654  tmp = weight.transpose() * cMat[i][j] * weight;
655  // Workaround to get things working in GPU
656  const double tempC = tmp(0, 0);
657  c0Mat(i, j) = tempC; //weight.transpose() * C[i][j] * weight;
658  c0Mat(j, i) = c0Mat(i, j);
659  }
660  }
661  printIt(&c0Mat, "circle_fit - C0:");
662 
663  const MatrixNd<N> wMat = weight * weight.transpose();
664  const MatrixNd<N> hMat = MatrixNd<N>::Identity().rowwise() - weight.transpose();
665  const MatrixNx3d<N> s_v = hMat * p3D.transpose();
666  printIt(&wMat, "circle_fit - W:");
667  printIt(&hMat, "circle_fit - H:");
668  printIt(&s_v, "circle_fit - s_v:");
669 
670  MatrixNd<N> dMat[3][3]; // cov(s_v)
671  dMat[0][0] = (hMat * cMat[0][0] * hMat.transpose()).cwiseProduct(wMat);
672  dMat[0][1] = (hMat * cMat[0][1] * hMat.transpose()).cwiseProduct(wMat);
673  dMat[0][2] = (hMat * cMat[0][2] * hMat.transpose()).cwiseProduct(wMat);
674  dMat[1][1] = (hMat * cMat[1][1] * hMat.transpose()).cwiseProduct(wMat);
675  dMat[1][2] = (hMat * cMat[1][2] * hMat.transpose()).cwiseProduct(wMat);
676  dMat[2][2] = (hMat * cMat[2][2] * hMat.transpose()).cwiseProduct(wMat);
677  dMat[1][0] = dMat[0][1].transpose();
678  dMat[2][0] = dMat[0][2].transpose();
679  dMat[2][1] = dMat[1][2].transpose();
680  printIt(&dMat[0][0], "circle_fit - D_[0][0]:");
681 
682  constexpr uint nu[6][2] = {{0, 0}, {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 2}};
683 
684  Matrix6d eMat; // cov matrix of the 6 independent elements of A
685  for (uint a = 0; a < 6; ++a) {
686  const uint i = nu[a][0], j = nu[a][1];
687  for (uint b = a; b < 6; ++b) {
688  const uint k = nu[b][0], l = nu[b][1];
689  VectorNd<N> t0(n);
690  VectorNd<N> t1(n);
691  if (l == k) {
692  t0 = 2. * dMat[j][l] * s_v.col(l);
693  if (i == j)
694  t1 = t0;
695  else
696  t1 = 2. * dMat[i][l] * s_v.col(l);
697  } else {
698  t0 = dMat[j][l] * s_v.col(k) + dMat[j][k] * s_v.col(l);
699  if (i == j)
700  t1 = t0;
701  else
702  t1 = dMat[i][l] * s_v.col(k) + dMat[i][k] * s_v.col(l);
703  }
704 
705  if (i == j) {
706  Eigen::Matrix<double, 1, 1> cm;
707  cm = s_v.col(i).transpose() * (t0 + t1);
708  // Workaround to get things working in GPU
709  const double tempC = cm(0, 0);
710  eMat(a, b) = 0. + tempC;
711  } else {
712  Eigen::Matrix<double, 1, 1> cm;
713  cm = (s_v.col(i).transpose() * t0) + (s_v.col(j).transpose() * t1);
714  // Workaround to get things working in GPU
715  const double tempC = cm(0, 0);
716  eMat(a, b) = 0. + tempC; //(s_v.col(i).transpose() * t0) + (s_v.col(j).transpose() * t1);
717  }
718  if (b != a)
719  eMat(b, a) = eMat(a, b);
720  }
721  }
722  printIt(&eMat, "circle_fit - E:");
723 
724  Eigen::Matrix<double, 3, 6> j2Mat; // Jacobian of min_eigen() (numerically computed)
725  for (uint a = 0; a < 6; ++a) {
726  const uint i = nu[a][0], j = nu[a][1];
727  Matrix3d delta = Matrix3d::Zero();
728  delta(i, j) = delta(j, i) = abs(aMat(i, j) * epsilon);
729  j2Mat.col(a) = min_eigen3D_fast(acc, aMat + delta);
730  const int sign = (j2Mat.col(a)(2) > 0) ? 1 : -1;
731  j2Mat.col(a) = (j2Mat.col(a) * sign - vVec) / delta(i, j);
732  }
733  printIt(&j2Mat, "circle_fit - J2:");
734 
735  Matrix4d cvcMat; // joint cov matrix of (v0,v1,v2,c)
736  {
737  Matrix3d t0 = j2Mat * eMat * j2Mat.transpose();
738  Vector3d t1 = -t0 * r0;
739  cvcMat.block(0, 0, 3, 3) = t0;
740  cvcMat.block(0, 3, 3, 1) = t1;
741  cvcMat.block(3, 0, 1, 3) = t1.transpose();
742  Eigen::Matrix<double, 1, 1> cm1;
743  Eigen::Matrix<double, 1, 1> cm3;
744  cm1 = (vVec.transpose() * c0Mat * vVec);
745  // cm2 = (c0Mat.cwiseProduct(t0)).sum();
746  cm3 = (r0.transpose() * t0 * r0);
747  // Workaround to get things working in GPU
748  const double tempC = cm1(0, 0) + (c0Mat.cwiseProduct(t0)).sum() + cm3(0, 0);
749  cvcMat(3, 3) = tempC;
750  // (v.transpose() * c0Mat * v) + (c0Mat.cwiseProduct(t0)).sum() + (r0.transpose() * t0 * r0);
751  }
752  printIt(&cvcMat, "circle_fit - Cvc:");
753 
754  Eigen::Matrix<double, 3, 4> j3Mat; // Jacobian (v0,v1,v2,c)->(X0,Y0,R)
755  {
756  const double t = 1. / tempH;
757  j3Mat << -v2x2_inv, 0, vVec(0) * sqr(v2x2_inv) * 2., 0, 0, -v2x2_inv, vVec(1) * sqr(v2x2_inv) * 2., 0,
758  vVec(0) * v2x2_inv * t, vVec(1) * v2x2_inv * t,
759  -tempH * sqr(v2x2_inv) * 2. - (2. * tempC + vVec(2)) * v2x2_inv * t, -t;
760  }
761  printIt(&j3Mat, "circle_fit - J3:");
762 
763  const RowVector2Nd<N> Jq = mc.transpose() * tempS * 1. / n; // var(q)
764  printIt(&Jq, "circle_fit - Jq:");
765 
766  Matrix3d cov_uvr = j3Mat * cvcMat * j3Mat.transpose() * sqr(s_inv) // cov(X0,Y0,R)
767  + (par_uvr * par_uvr.transpose()) * (Jq * vMat * Jq.transpose());
768 
769  circle.cov = cov_uvr;
770  }
771 
772  printIt(&circle.cov, "Circle cov:");
773 #ifdef RFIT_DEBUG
774  printf("circle_fit - exit\n");
775 #endif
776  return circle;
777  }
Eigen::Vector3d Vector3d
Definition: FitResult.h:11
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
__host__ __device__ VectorNd< N > cov_carttorad_prefit(const M2xN &p2D, const Matrix2Nd< N > &cov_cart, V4 &fast_fit, const VectorNd< N > &rad)
Transform covariance matrix from Cartesian coordinates (only transverse plane component) to coordinat...
Definition: RiemannFit.h:242
Definition: weight.py:1
Eigen::Matrix< double, 6, 6 > Matrix6d
Definition: FitResult.h:18
T sqrt(T t)
Definition: SSEVec.h:19
Eigen::Matrix4d Matrix4d
Definition: FitResult.h:16
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
__host__ __device__ Vector3d min_eigen3D(const Matrix3d &A, double &chi2)
Compute the eigenvector associated to the minimum eigenvalue.
Definition: RiemannFit.h:313
Polynomial< 0 > Constant
Definition: Constant.h:6
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
__host__ __device__ VectorNd< N > weightCircle(const MatrixNd< N > &cov_rad_inv)
Compute the points&#39; weights&#39; vector for the circle fit when multiple scattering is managed...
Definition: RiemannFit.h:278
__host__ __device__ Vector3d min_eigen3D_fast(const Matrix3d &A)
A faster version of min_eigen3D() where double precision is not needed.
Definition: RiemannFit.h:338
#define N
Definition: blowfish.cc:9
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
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:14
__host__ __device__ MatrixNd< N > scatter_cov_rad(const M2xN &p2D, const V4 &fast_fit, VectorNd< N > const &rad, double B)
Compute the covariance matrix (in radial coordinates) of points in the transverse plane due to multip...
Definition: RiemannFit.h:126
__host__ __device__ Matrix2Nd< N > cov_radtocart(const M2xN &p2D, const MatrixNd< N > &cov_rad, const VectorNd< N > &rad)
Transform covariance matrix from radial (only tangential component) to Cartesian coordinates (only tr...
Definition: RiemannFit.h:174
__host__ __device__ int32_t charge(const M2xN &p2D, const Vector3d &par_uvr)
Find particle q considering the sign of cross product between particles velocity (estimated by the fi...
Definition: RiemannFit.h:291
tmp
align.sh
Definition: createJobs.py:716

◆ computeRadLenUniformMaterial()

template<typename TAcc , typename VNd1 , typename VNd2 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::computeRadLenUniformMaterial ( const TAcc &  acc,
const VNd1 &  length_values,
VNd2 &  rad_lengths 
)

Compute the Radiation length in the uniform hypothesis

The Pixel detector, barrel and forward, is considered as an homogeneous cylinder of material, whose radiation lengths has been derived from the TDR plot that shows that 16cm correspond to 0.06 radiation lengths. Therefore one radiation length corresponds to 16cm/0.06 =~ 267 cm. All radiation lengths are computed using this unique number, in both regions, barrel and endcap.

NB: no angle corrections nor projections are computed inside this routine. It is therefore the responsibility of the caller to supply the proper lengths in input. These lengths are the path traveled by the particle along its trajectory, namely the so called S of the helix in 3D space.

Parameters
length_valuesvector of incremental distances that will be translated into radiation length equivalent. Each radiation length i is computed incrementally with respect to the previous length i-1. The first length has no reference point (i.e. it has the dca).
Returns
incremental radiation lengths that correspond to each segment.

Definition at line 38 of file RiemannFit.h.

References funct::abs(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), dqmiolumiharvest::j, dqmiodumpmetadata::n, and parallelization::uint.

Referenced by scatter_cov_rad(), and scatterCovLine().

40  {
41  // Radiation length of the pixel detector in the uniform assumption, with
42  // 0.06 rad_len at 16 cm
43  constexpr double xx_0_inv = 0.06 / 16.;
44  uint n = length_values.rows();
45  rad_lengths(0) = length_values(0) * xx_0_inv;
46  for (uint j = 1; j < n; ++j) {
47  rad_lengths(j) = alpaka::math::abs(acc, length_values(j) - length_values(j - 1)) * xx_0_inv;
48  }
49  }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22

◆ cov_carttorad()

template<typename TAcc , typename M2xN , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd<N> ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::cov_carttorad ( const TAcc &  acc,
const M2xN &  p2D,
const Matrix2Nd< N > &  cov_cart,
const VectorNd< N > &  rad 
)

Transform covariance matrix from Cartesian coordinates (only transverse plane component) to radial coordinates (both radial and tangential component but only diagonal terms, correlation between different point are not managed).

Parameters
p2D2D points in transverse plane.
cov_cartcovariance matrix in Cartesian coordinates.
Returns
cov_rad covariance matrix in raidal coordinate.
Warning
correlation between different point are not computed.

< in case you have (0,0) to avoid dividing by 0 radius

Definition at line 218 of file RiemannFit.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), MillePedeFileConverter_cfg::e, mps_fire::i, N, dqmiodumpmetadata::n, sqr(), and parallelization::uint.

221  {
222  constexpr uint n = N;
223  VectorNd<N> cov_rad;
224  const VectorNd<N> rad_inv2 = rad.cwiseInverse().array().square();
225  for (uint i = 0; i < n; ++i) {
227  if (rad(i) < 1.e-4)
228  cov_rad(i) = cov_cart(i, i);
229  else {
230  cov_rad(i) = rad_inv2(i) * (cov_cart(i, i) * sqr(p2D(1, i)) + cov_cart(i + n, i + n) * sqr(p2D(0, i)) -
231  2. * cov_cart(i, i + n) * p2D(0, i) * p2D(1, i));
232  }
233  }
234  return cov_rad;
235  }
#define N
Definition: blowfish.cc:9
Square< F >::type sqr(const F &f)
Definition: Square.h:14

◆ cov_carttorad_prefit()

template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd<N> ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::cov_carttorad_prefit ( const TAcc &  acc,
const M2xN &  p2D,
const Matrix2Nd< N > &  cov_cart,
V4 &  fast_fit,
const VectorNd< N > &  rad 
)

Transform covariance matrix from Cartesian coordinates (only transverse plane component) to coordinates system orthogonal to the pre-fitted circle in each point. Further information in attached documentation.

Parameters
p2D2D points in transverse plane.
cov_cartcovariance matrix in Cartesian coordinates.
fast_fitfast_fit Vector4d result of the previous pre-fit structured in this form:(X0, Y0, R, tan(theta))).
Returns
cov_rad covariance matrix in the pre-fitted circle's orthogonal system.

< in case you have (0,0) to avoid dividing by 0 radius

Definition at line 250 of file RiemannFit.h.

References a, b, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), cross2D(), MillePedeFileConverter_cfg::e, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, mps_fire::i, N, dqmiodumpmetadata::n, sqr(), parallelization::uint, and testProducerWithPsetDescEmpty_cfi::y2.

Referenced by circleFit().

251  {
252  constexpr uint n = N;
253  VectorNd<N> cov_rad;
254  for (uint i = 0; i < n; ++i) {
256  if (rad(i) < 1.e-4)
257  cov_rad(i) = cov_cart(i, i); // TO FIX
258  else {
259  Vector2d a = p2D.col(i);
260  Vector2d b = p2D.col(i) - fast_fit.head(2);
261  const double x2 = a.dot(b);
262  const double y2 = cross2D(acc, a, b);
263  const double tan_c = -y2 / x2;
264  const double tan_c2 = sqr(tan_c);
265  cov_rad(i) =
266  1. / (1. + tan_c2) * (cov_cart(i, i) + cov_cart(i + n, i + n) * tan_c2 + 2 * cov_cart(i, i + n) * tan_c);
267  }
268  }
269  return cov_rad;
270  }
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 const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
#define N
Definition: blowfish.cc:9
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:14

◆ cov_radtocart()

template<typename TAcc , typename M2xN , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE Matrix2Nd<N> ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::cov_radtocart ( const TAcc &  acc,
const M2xN &  p2D,
const MatrixNd< N > &  cov_rad,
const VectorNd< N > &  rad 
)

Transform covariance matrix from radial (only tangential component) to Cartesian coordinates (only transverse plane component).

Parameters
p2D2D points in the transverse plane.
cov_radcovariance matrix in radial coordinate.
Returns
cov_cart covariance matrix in Cartesian coordinates.

Definition at line 180 of file RiemannFit.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), mps_fire::i, dqmiolumiharvest::j, N, dqmiodumpmetadata::n, printIt(), and parallelization::uint.

Referenced by circleFit().

183  {
184 #ifdef RFIT_DEBUG
185  printf("Address of p2D: %p\n", &p2D);
186 #endif
187  printIt(&p2D, "cov_radtocart - p2D:");
188  constexpr uint n = N;
189  Matrix2Nd<N> cov_cart = Matrix2Nd<N>::Zero();
190  VectorNd<N> rad_inv = rad.cwiseInverse();
191  printIt(&rad_inv, "cov_radtocart - rad_inv:");
192  for (uint i = 0; i < n; ++i) {
193  for (uint j = i; j < n; ++j) {
194  cov_cart(i, j) = cov_rad(i, j) * p2D(1, i) * rad_inv(i) * p2D(1, j) * rad_inv(j);
195  cov_cart(i + n, j + n) = cov_rad(i, j) * p2D(0, i) * rad_inv(i) * p2D(0, j) * rad_inv(j);
196  cov_cart(i, j + n) = -cov_rad(i, j) * p2D(1, i) * rad_inv(i) * p2D(0, j) * rad_inv(j);
197  cov_cart(i + n, j) = -cov_rad(i, j) * p2D(0, i) * rad_inv(i) * p2D(1, j) * rad_inv(j);
198  cov_cart(j, i) = cov_cart(i, j);
199  cov_cart(j + n, i + n) = cov_cart(i + n, j + n);
200  cov_cart(j + n, i) = cov_cart(i, j + n);
201  cov_cart(j, i + n) = cov_cart(i + n, j);
202  }
203  }
204  return cov_cart;
205  }
#define N
Definition: blowfish.cc:9
ALPAKA_FN_ACC void printIt(const TAcc &acc, C *m, const char *prefix="")
Definition: FitUtils.h:90

◆ cross2D()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE double ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::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.

Parameters
afirst 2D vector in the product.
bsecond 2D vector in the product.
Returns
z component of the cross product.

Definition at line 117 of file FitUtils.h.

References a, and b.

Referenced by cov_carttorad_prefit(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fastFit(), fastFit(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::for(), lineFit(), and scatter_cov_rad().

117  {
118  return a.x() * b.y() - a.y() * b.x();
119  }
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121

◆ fastFit()

template<typename TAcc , typename M3xN , typename V4 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::fastFit ( const TAcc &  acc,
const M3xN &  hits,
V4 &  result 
)

A very fast helix fit: it fits a circle by three points (first, middle and last point) and a line by two points (first and last).

Parameters
hitspoints to be fitted
Returns
result in this form: (X0,Y0,R,tan(theta)).
Warning
points must be passed ordered (from internal layer to external) in order to maximize accuracy and do not mistake tan(theta) sign.

This fast fit is used as pre-fit which is needed for:

  • weights estimation and chi2 computation in line fit (fundamental);
  • weights estimation and chi2 computation in circle fit (useful);
  • computation of error due to multiple scattering.

< in case b.x is 0 (2 hits with same x)

Definition at line 385 of file RiemannFit.h.

References funct::abs(), b2, nano_mu_digi_cff::bx, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), cross2D(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::dVec, PVValHelper::dz, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::eVec, HLT_2023v12_cff::flip, hfClusterShapes_cfi::hits, N, dqmiodumpmetadata::n, printIt(), mps_fire::result, sqr(), and mathSSE::sqrt().

Referenced by ALPAKA_ACCELERATOR_NAMESPACE::Kernel_FastFit< N, TrackerTraits >::operator()(), and riemannFit::helixFit< N >::operator()().

385  {
386  constexpr uint32_t N = M3xN::ColsAtCompileTime;
387  constexpr auto n = N; // get the number of hits
388  printIt(&hits, "Fast_fit - hits: ");
389 
390  // CIRCLE FIT
391  // Make segments between middle-to-first(b) and last-to-first(c) hits
392  const Vector2d bVec = hits.block(0, n / 2, 2, 1) - hits.block(0, 0, 2, 1);
393  const Vector2d cVec = hits.block(0, n - 1, 2, 1) - hits.block(0, 0, 2, 1);
394  printIt(&bVec, "Fast_fit - b: ");
395  printIt(&cVec, "Fast_fit - c: ");
396  // Compute their lengths
397  auto b2 = bVec.squaredNorm();
398  auto c2 = cVec.squaredNorm();
399  // The algebra has been verified (MR). The usual approach has been followed:
400  // * use an orthogonal reference frame passing from the first point.
401  // * build the segments (chords)
402  // * build orthogonal lines through mid points
403  // * make a system and solve for X0 and Y0.
404  // * add the initial point
405  bool flip = abs(bVec.x()) < abs(bVec.y());
406  auto bx = flip ? bVec.y() : bVec.x();
407  auto by = flip ? bVec.x() : bVec.y();
408  auto cx = flip ? cVec.y() : cVec.x();
409  auto cy = flip ? cVec.x() : cVec.y();
411  auto div = 2. * (cx * by - bx * cy);
412  // if aligned TO FIX
413  auto y0 = (cx * b2 - bx * c2) / div;
414  auto x0 = (0.5 * b2 - y0 * by) / bx;
415  result(0) = hits(0, 0) + (flip ? y0 : x0);
416  result(1) = hits(1, 0) + (flip ? x0 : y0);
417  result(2) = sqrt(sqr(x0) + sqr(y0));
418  printIt(&result, "Fast_fit - result: ");
419 
420  // LINE FIT
421  const Vector2d dVec = hits.block(0, 0, 2, 1) - result.head(2);
422  const Vector2d eVec = hits.block(0, n - 1, 2, 1) - result.head(2);
423  printIt(&eVec, "Fast_fit - e: ");
424  printIt(&dVec, "Fast_fit - d: ");
425  // Compute the arc-length between first and last point: L = R * theta = R * atan (tan (Theta) )
426  auto dr = result(2) * atan2(cross2D(acc, dVec, eVec), dVec.dot(eVec));
427  // Simple difference in Z between last and first hit
428  auto dz = hits(2, n - 1) - hits(2, 0);
429 
430  result(3) = (dr / dz);
431 
432 #ifdef RFIT_DEBUG
433  printf("Fast_fit: [%f, %f, %f, %f]\n", result(0), result(1), result(2), result(3));
434 #endif
435  }
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
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bias2_t b2[25]
Definition: b2.h:9
#define N
Definition: blowfish.cc:9
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
ALPAKA_FN_ACC void printIt(const TAcc &acc, C *m, const char *prefix="")
Definition: FitUtils.h:90
Square< F >::type sqr(const F &f)
Definition: Square.h:14

◆ fromCircleToPerigee()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::fromCircleToPerigee ( const TAcc &  acc,
CircleFit &  circle 
)

Transform circle parameter from (X0,Y0,R) to (phi,Tip,q/R) and consequently covariance matrix.

Parameters
circle_uvrparameter (X0,Y0,R), covariance matrix to be transformed and particle charge.

Definition at line 239 of file FitUtils.h.

References sqr(), and mathSSE::sqrt().

Referenced by ALPAKA_ACCELERATOR_NAMESPACE::Kernel_LineFit< N, TrackerTraits >::operator()().

239  {
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  }
Eigen::Vector3d Vector3d
Definition: FitResult.h:11
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
T sqrt(T t)
Definition: SSEVec.h:19
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67

◆ lineFit()

template<typename TAcc , typename M3xN , typename M6xN , typename V4 >
ALPAKA_FN_ACC ALPAKA_FN_INLINE LineFit ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::lineFit ( const TAcc &  acc,
const M3xN &  hits,
const M6xN &  hits_ge,
const CircleFit &  circle,
const V4 &  fast_fit,
const double  bField,
const bool  error 
)

Perform an ordinary least square fit in the s-z plane to compute the parameters cotTheta and Zip.

The fit is performed in the rotated S3D-Z' plane, following the formalism of Frodesen, Chapter 10, p. 259.

The system has been rotated to both try to use the combined errors in s-z along Z', as errors in the Y direction and to avoid the patological case of degenerate lines with angular coefficient m = +/- inf.

The rotation is using the information on the theta angle computed in the fast fit. The rotation is such that the S3D axis will be the X-direction, while the rotated Z-axis will be the Y-direction. This pretty much follows what is done in the same fit in the Broken Line approach.

Definition at line 796 of file RiemannFit.h.

References Calorimetry_cff::bField, nano_mu_local_reco_cff::chi2, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), funct::cos(), cross(), cross2D(), alignCSCRings::d_x, alignCSCRings::d_y, dot(), relativeConstraints::error, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, hfClusterShapes_cfi::hits, mps_fire::i, l1tstage2_dqm_sourceclient-live_cfg::invert, mps_splice::line, M_PI, N, dqmiodumpmetadata::n, printIt(), makeMuonMisalignmentScenario::rot, scatterCovLine(), funct::sin(), mkfit::Const::sol, sqr(), theta(), createJobs::tmp, and parallelization::uint.

Referenced by ALPAKA_ACCELERATOR_NAMESPACE::Kernel_LineFit< N, TrackerTraits >::operator()(), and riemannFit::helixFit< N >::operator()().

802  {
803  constexpr uint32_t N = M3xN::ColsAtCompileTime;
804  constexpr auto n = N;
805  double theta = -circle.qCharge * atan(fast_fit(3));
806  theta = theta < 0. ? theta + M_PI : theta;
807 
808  // Prepare the Rotation Matrix to rotate the points
809  Eigen::Matrix<double, 2, 2> rot;
810  rot << sin(theta), cos(theta), -cos(theta), sin(theta);
811 
812  // PROJECTION ON THE CILINDER
813  //
814  // p2D will be:
815  // [s1, s2, s3, ..., sn]
816  // [z1, z2, z3, ..., zn]
817  // s values will be ordinary x-values
818  // z values will be ordinary y-values
819 
820  Matrix2xNd<N> p2D = Matrix2xNd<N>::Zero();
821  Eigen::Matrix<double, 2, 6> jxMat;
822 
823 #ifdef RFIT_DEBUG
824  printf("Line_fit - B: %g\n", bField);
825  printIt(&hits, "Line_fit points: ");
826  printIt(&hits_ge, "Line_fit covs: ");
827  printIt(&rot, "Line_fit rot: ");
828 #endif
829  // x & associated Jacobian
830  // cfr https://indico.cern.ch/event/663159/contributions/2707659/attachments/1517175/2368189/Riemann_fit.pdf
831  // Slide 11
832  // a ==> -o i.e. the origin of the circle in XY plane, negative
833  // b ==> p i.e. distances of the points wrt the origin of the circle.
834  const Vector2d oVec(circle.par(0), circle.par(1));
835 
836  // associated Jacobian, used in weights and errors computation
837  Matrix6d covMat = Matrix6d::Zero();
838  Matrix2d cov_sz[N];
839  for (uint i = 0; i < n; ++i) {
840  Vector2d pVec = hits.block(0, i, 2, 1) - oVec;
841  const double cross = cross2D(acc, -oVec, pVec);
842  const double dot = (-oVec).dot(pVec);
843  // atan2(cross, dot) give back the angle in the transverse plane so tha the
844  // final equation reads: x_i = -q*R*theta (theta = angle returned by atan2)
845  const double tempQAtan2 = -circle.qCharge * atan2(cross, dot);
846  // p2D.coeffRef(1, i) = atan2_ * circle.par(2);
847  p2D(0, i) = tempQAtan2 * circle.par(2);
848 
849  // associated Jacobian, used in weights and errors- computation
850  const double temp0 = -circle.qCharge * circle.par(2) * 1. / (sqr(dot) + sqr(cross));
851  double d_X0 = 0., d_Y0 = 0., d_R = 0.; // good approximation for big pt and eta
852  if (error) {
853  d_X0 = -temp0 * ((pVec(1) + oVec(1)) * dot - (pVec(0) - oVec(0)) * cross);
854  d_Y0 = temp0 * ((pVec(0) + oVec(0)) * dot - (oVec(1) - pVec(1)) * cross);
855  d_R = tempQAtan2;
856  }
857  const double d_x = temp0 * (oVec(1) * dot + oVec(0) * cross);
858  const double d_y = temp0 * (-oVec(0) * dot + oVec(1) * cross);
859  jxMat << d_X0, d_Y0, d_R, d_x, d_y, 0., 0., 0., 0., 0., 0., 1.;
860 
861  covMat.block(0, 0, 3, 3) = circle.cov;
862  covMat(3, 3) = hits_ge.col(i)[0]; // x errors
863  covMat(4, 4) = hits_ge.col(i)[2]; // y errors
864  covMat(5, 5) = hits_ge.col(i)[5]; // z errors
865  covMat(3, 4) = covMat(4, 3) = hits_ge.col(i)[1]; // cov_xy
866  covMat(3, 5) = covMat(5, 3) = hits_ge.col(i)[3]; // cov_xz
867  covMat(4, 5) = covMat(5, 4) = hits_ge.col(i)[4]; // cov_yz
868  Matrix2d tmp = jxMat * covMat * jxMat.transpose();
869  cov_sz[i].noalias() = rot * tmp * rot.transpose();
870  }
871  // Math of d_{X0,Y0,R,x,y} all verified by hand
872  p2D.row(1) = hits.row(2);
873 
874  // The following matrix will contain errors orthogonal to the rotated S
875  // component only, with the Multiple Scattering properly treated!!
876  MatrixNd<N> cov_with_ms;
877  scatterCovLine(acc, cov_sz, fast_fit, p2D.row(0), p2D.row(1), theta, bField, cov_with_ms);
878 #ifdef RFIT_DEBUG
879  printIt(cov_sz, "line_fit - cov_sz:");
880  printIt(&cov_with_ms, "line_fit - cov_with_ms: ");
881 #endif
882 
883  // Rotate Points with the shape [2, n]
884  Matrix2xNd<N> p2D_rot = rot * p2D;
885 
886 #ifdef RFIT_DEBUG
887  printf("Fast fit Tan(theta): %g\n", fast_fit(3));
888  printf("Rotation angle: %g\n", theta);
889  printIt(&rot, "Rotation Matrix:");
890  printIt(&p2D, "Original Hits(s,z):");
891  printIt(&p2D_rot, "Rotated hits(S3D, Z'):");
892  printIt(&rot, "Rotation Matrix:");
893 #endif
894 
895  // Build the A Matrix
896  Matrix2xNd<N> aMat;
897  aMat << MatrixXd::Ones(1, n), p2D_rot.row(0); // rotated s values
898 
899 #ifdef RFIT_DEBUG
900  printIt(&aMat, "A Matrix:");
901 #endif
902 
903  // Build A^T V-1 A, where V-1 is the covariance of only the Y components.
904  MatrixNd<N> vyInvMat;
905  math::cholesky::invert(cov_with_ms, vyInvMat);
906  // MatrixNd<N> vyInvMat = cov_with_ms.inverse();
907  Eigen::Matrix<double, 2, 2> covParamsMat = aMat * vyInvMat * aMat.transpose();
908  // Compute the Covariance Matrix of the fit parameters
909  math::cholesky::invert(covParamsMat, covParamsMat);
910 
911  // Now Compute the Parameters in the form [2,1]
912  // The first component is q.
913  // The second component is m.
914  Eigen::Matrix<double, 2, 1> sol = covParamsMat * aMat * vyInvMat * p2D_rot.row(1).transpose();
915 
916 #ifdef RFIT_DEBUG
917  printIt(&sol, "Rotated solutions:");
918 #endif
919 
920  // We need now to transfer back the results in the original s-z plane
921  const auto sinTheta = sin(theta);
922  const auto cosTheta = cos(theta);
923  auto common_factor = 1. / (sinTheta - sol(1, 0) * cosTheta);
924  Eigen::Matrix<double, 2, 2> jMat;
925  jMat << 0., common_factor * common_factor, common_factor, sol(0, 0) * cosTheta * common_factor * common_factor;
926 
927  double tempM = common_factor * (sol(1, 0) * sinTheta + cosTheta);
928  double tempQ = common_factor * sol(0, 0);
929  auto cov_mq = jMat * covParamsMat * jMat.transpose();
930 
931  VectorNd<N> res = p2D_rot.row(1).transpose() - aMat.transpose() * sol;
932  double chi2 = res.transpose() * vyInvMat * res;
933 
934  LineFit line;
935  line.par << tempM, tempQ;
936  line.cov << cov_mq;
937  line.chi2 = chi2;
938 
939 #ifdef RFIT_DEBUG
940  printf("Common_factor: %g\n", common_factor);
941  printIt(&jMat, "Jacobian:");
942  printIt(&sol, "Rotated solutions:");
943  printIt(&covParamsMat, "Cov_params:");
944  printIt(&cov_mq, "Rotated Covariance Matrix:");
945  printIt(&(line.par), "Real Parameters:");
946  printIt(&(line.cov), "Real Covariance Matrix:");
947  printf("Chi2: %g\n", chi2);
948 #endif
949 
950  return line;
951  }
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or "cross" product, with a vector of same type.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
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
Definition: Electron.h:6
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
Eigen::Matrix< double, 6, 6 > Matrix6d
Definition: FitResult.h:18
Eigen::Matrix2d Matrix2d
Definition: FitResult.h:14
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
#define M_PI
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
constexpr float sol
Definition: Config.h:13
#define N
Definition: blowfish.cc:9
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
ALPAKA_FN_ACC void printIt(const TAcc &acc, C *m, const char *prefix="")
Definition: FitUtils.h:90
Square< F >::type sqr(const F &f)
Definition: Square.h:14
__host__ __device__ auto scatterCovLine(Matrix2d const *cov_sz, const V4 &fast_fit, VNd1 const &s_arcs, VNd2 const &z_values, const double theta, const double bField, MatrixNd< N > &ret)
Compute the covariance matrix along cartesian S-Z of points due to multiple Coulomb scattering to be ...
Definition: RiemannFit.h:65
tmp
align.sh
Definition: createJobs.py:716
Geom::Theta< T > theta() const

◆ loadCovariance()

template<typename TAcc , typename M6xNf , typename M3xNd >
ALPAKA_FN_ACC void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::loadCovariance ( const TAcc &  acc,
M6xNf const &  ge,
M3xNd &  hits_cov 
)

Definition at line 158 of file FitUtils.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), mps_fire::i, dqmiolumiharvest::j, and MainPageGenerator::l.

158  {
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  }

◆ loadCovariance2D()

template<typename TAcc , typename M6xNf , typename M2Nd >
ALPAKA_FN_ACC void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::loadCovariance2D ( const TAcc &  acc,
M6xNf const &  ge,
M2Nd &  hits_cov 
)

load error in CMSSW format to our formalism

Definition at line 126 of file FitUtils.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), mps_fire::i, dqmiolumiharvest::j, and MainPageGenerator::l.

Referenced by ALPAKA_ACCELERATOR_NAMESPACE::Kernel_CircleFit< N, TrackerTraits >::operator()(), and riemannFit::helixFit< N >::operator()().

126  {
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  }

◆ min_eigen2D()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector2d ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::min_eigen2D ( const TAcc &  acc,
const Matrix2d &  aMat,
double &  chi2 
)

2D version of min_eigen3D().

Parameters
aMatthe Matrix you want to know eigenvector and eigenvalue.
chi2the double were the chi2-related quantity will be stored
Returns
the eigenvector associated to the minimum eigenvalue. The computedDirect() method of SelfAdjointEigenSolver for 2x2 Matrix do not use special math function (just sqrt) therefore it doesn't speed up significantly in single precision.

Definition at line 363 of file RiemannFit.h.

References nano_mu_local_reco_cff::chi2.

363  {
364  Eigen::SelfAdjointEigenSolver<Matrix2d> solver(2);
365  solver.computeDirect(aMat);
366  int min_index;
367  chi2 = solver.eigenvalues().minCoeff(&min_index);
368  return solver.eigenvectors().col(min_index);
369  }

◆ min_eigen3D()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector3d ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::min_eigen3D ( const TAcc &  acc,
const Matrix3d &  A,
double &  chi2 
)

Compute the eigenvector associated to the minimum eigenvalue.

Parameters
Athe Matrix you want to know eigenvector and eigenvalue.
chi2the double were the chi2-related quantity will be stored.
Returns
the eigenvector associated to the minimum eigenvalue.
Warning
double precision is needed for a correct assessment of chi2.

The minimus eigenvalue is related to chi2. We exploit the fact that the matrix is symmetrical and small (2x2 for line fit and 3x3 for circle fit), so the SelfAdjointEigenSolver from Eigen library is used, with the computedDirect method (available only for 2x2 and 3x3 Matrix) wich computes eigendecomposition of given matrix using a fast closed-form algorithm. For this optimization the matrix type must be known at compiling time.

Definition at line 319 of file RiemannFit.h.

References A, and nano_mu_local_reco_cff::chi2.

Referenced by circleFit().

319  {
320 #ifdef RFIT_DEBUG
321  printf("min_eigen3D - enter\n");
322 #endif
323  Eigen::SelfAdjointEigenSolver<Matrix3d> solver(3);
324  solver.computeDirect(A);
325  int min_index;
326  chi2 = solver.eigenvalues().minCoeff(&min_index);
327 #ifdef RFIT_DEBUG
328  printf("min_eigen3D - exit\n");
329 #endif
330  return solver.eigenvectors().col(min_index);
331  }
Definition: APVGainStruct.h:7

◆ min_eigen3D_fast()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE Vector3d ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::min_eigen3D_fast ( const TAcc &  acc,
const Matrix3d &  A 
)

A faster version of min_eigen3D() where double precision is not needed.

Parameters
Athe Matrix you want to know eigenvector and eigenvalue.
chi2the double were the chi2-related quantity will be stored
Returns
the eigenvector associated to the minimum eigenvalue. The computedDirect() method of SelfAdjointEigenSolver for 3x3 Matrix indeed, use trigonometry function (it solves a third degree equation) which speed up in single precision.

Definition at line 345 of file RiemannFit.h.

References A.

Referenced by circleFit().

345  {
346  Eigen::SelfAdjointEigenSolver<Matrix3f> solver(3);
347  solver.computeDirect(A.cast<float>());
348  int min_index;
349  solver.eigenvalues().minCoeff(&min_index);
350  return solver.eigenvectors().col(min_index).cast<double>();
351  }
Definition: APVGainStruct.h:7

◆ par_uvrtopak()

template<typename TAcc >
ALPAKA_FN_ACC ALPAKA_FN_INLINE void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::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.

Parameters
circle_uvrparameter (X0,Y0,R), covariance matrix to be transformed and particle charge.
Bmagnetic field in Gev/cm/c unit.
errorflag for errors computation.

Definition at line 212 of file FitUtils.h.

References B, relativeConstraints::error, sqr(), and mathSSE::sqrt().

Referenced by riemannFit::helixFit< N >::operator()().

215  {
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  }
Eigen::Vector3d Vector3d
Definition: FitResult.h:11
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
Definition: APVGainStruct.h:7
T sqrt(T t)
Definition: SSEVec.h:19
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67

◆ printIt()

template<typename TAcc , class C >
ALPAKA_FN_ACC void ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::printIt ( const TAcc &  acc,
C *  m,
const char *  prefix = "" 
)

◆ scatter_cov_rad()

template<typename TAcc , typename M2xN , typename V4 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE MatrixNd<N> ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::scatter_cov_rad ( const TAcc &  acc,
const M2xN &  p2D,
const V4 &  fast_fit,
VectorNd< N > const &  rad,
double  B 
)

Compute the covariance matrix (in radial coordinates) of points in the transverse plane due to multiple Coulomb scattering.

Parameters
p2D2D points in the transverse plane.
fast_fitfast_fit Vector4d result of the previous pre-fit structured in this form:(X0, Y0, R, Tan(Theta))).
Bmagnetic field use to compute p
Returns
scatter_cov_rad errors due to multiple scattering.
Warning
input points must be ordered radially from the detector center (from inner layer to outer ones; points on the same layer must ordered too).

Only the tangential component is computed (the radial one is negligible).

Definition at line 134 of file RiemannFit.h.

References funct::abs(), B, computeRadLenUniformMaterial(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), cross(), cross2D(), dot(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, mps_fire::i, dqmdumpme::k, MainPageGenerator::l, M_PI, SiStripPI::min, N, dqmiodumpmetadata::n, printIt(), funct::sin(), sqr(), mathSSE::sqrt(), theta(), and parallelization::uint.

Referenced by circleFit().

135  {
136  constexpr uint n = N;
137  double p_t = alpaka::math::min(acc, 20., fast_fit(2) * B); // limit pt to avoid too small error!!!
138  double p_2 = p_t * p_t * (1. + 1. / sqr(fast_fit(3)));
139  double theta = atan(fast_fit(3));
140  theta = theta < 0. ? theta + M_PI : theta;
141  VectorNd<N> s_values;
142  VectorNd<N> rad_lengths;
143  const Vector2d oVec(fast_fit(0), fast_fit(1));
144 
145  // associated Jacobian, used in weights and errors computation
146  for (uint i = 0; i < n; ++i) { // x
147  Vector2d pVec = p2D.block(0, i, 2, 1) - oVec;
148  const double cross = cross2D(acc, -oVec, pVec);
149  const double dot = (-oVec).dot(pVec);
150  const double tempAtan2 = atan2(cross, dot);
151  s_values(i) = alpaka::math::abs(acc, tempAtan2 * fast_fit(2));
152  }
153  computeRadLenUniformMaterial(acc, s_values * sqrt(1. + 1. / sqr(fast_fit(3))), rad_lengths);
154  MatrixNd<N> scatter_cov_rad = MatrixNd<N>::Zero();
155  VectorNd<N> sig2 = (1. + 0.038 * rad_lengths.array().log()).abs2() * rad_lengths.array();
156  sig2 *= 0.000225 / (p_2 * sqr(sin(theta)));
157  for (uint k = 0; k < n; ++k) {
158  for (uint l = k; l < n; ++l) {
159  for (uint i = 0; i < uint(alpaka::math::min(acc, k, l)); ++i) {
160  scatter_cov_rad(k, l) += (rad(k) - rad(i)) * (rad(l) - rad(i)) * sig2(i);
161  }
163  }
164  }
165 #ifdef RFIT_DEBUG
166  riemannFit::printIt(&scatter_cov_rad, "Scatter_cov_rad - scatter_cov_rad: ");
167 #endif
168  return scatter_cov_rad;
169  }
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or "cross" product, with a vector of same type.
Definition: APVGainStruct.h:7
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
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
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
__host__ __device__ void computeRadLenUniformMaterial(const VNd1 &length_values, VNd2 &rad_lengths)
Definition: RiemannFit.h:34
#define M_PI
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
#define N
Definition: blowfish.cc:9
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
Square< F >::type sqr(const F &f)
Definition: Square.h:14
__host__ __device__ MatrixNd< N > scatter_cov_rad(const M2xN &p2D, const V4 &fast_fit, VectorNd< N > const &rad, double B)
Compute the covariance matrix (in radial coordinates) of points in the transverse plane due to multip...
Definition: RiemannFit.h:126
Geom::Theta< T > theta() const
__host__ __device__ void printIt(C *m, const char *prefix="")
Definition: FitUtils.h:53

◆ scatterCovLine()

template<typename TAcc , typename V4 , typename VNd1 , typename VNd2 , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE auto ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::scatterCovLine ( const TAcc &  acc,
Matrix2d const *  cov_sz,
const V4 &  fast_fit,
VNd1 const &  s_arcs,
VNd2 const &  z_values,
const double  theta,
const double  bField,
MatrixNd< N > &  ret 
)

Compute the covariance matrix along cartesian S-Z of points due to multiple Coulomb scattering to be used in the line_fit, for the barrel and forward cases. The input covariance matrix is in the variables s-z, original and unrotated. The multiple scattering component is computed in the usual linear approximation, using the 3D path which is computed as the squared root of the squared sum of the s and z components passed in. Internally a rotation by theta is performed and the covariance matrix returned is the one in the direction orthogonal to the rotated S3D axis, i.e. along the rotated Z axis. The choice of the rotation is not arbitrary, but derived from the fact that putting the horizontal axis along the S3D direction allows the usage of the ordinary least squared fitting techiques with the trivial parametrization y = mx + q, avoiding the patological case with m = +/- inf, that would correspond to the case at eta = 0.

Definition at line 71 of file RiemannFit.h.

References funct::abs(), Calorimetry_cff::bField, computeRadLenUniformMaterial(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, mps_fire::i, dqmdumpme::k, MainPageGenerator::l, SiStripPI::min, N, dqmiodumpmetadata::n, printIt(), runTheMatrix::ret, sqr(), createJobs::tmp, and parallelization::uint.

Referenced by lineFit().

78  {
79 #ifdef RFIT_DEBUG
80  riemannFit::printIt(&s_arcs, "Scatter_cov_line - s_arcs: ");
81 #endif
82  constexpr uint n = N;
83  double p_t = alpaka::math::min(acc, 20., fast_fit(2) * bField); // limit pt to avoid too small error!!!
84  double p_2 = p_t * p_t * (1. + 1. / sqr(fast_fit(3)));
85  VectorNd<N> rad_lengths_S;
86  // See documentation at http://eigen.tuxfamily.org/dox/group__TutorialArrayClass.html
87  // Basically, to perform cwise operations on Matrices and Vectors, you need
88  // to transform them into Array-like objects.
89  VectorNd<N> s_values = s_arcs.array() * s_arcs.array() + z_values.array() * z_values.array();
90  s_values = s_values.array().sqrt();
91  computeRadLenUniformMaterial(acc, s_values, rad_lengths_S);
92  VectorNd<N> sig2_S;
93  sig2_S = .000225 / p_2 * (1. + 0.038 * rad_lengths_S.array().log()).abs2() * rad_lengths_S.array();
94 #ifdef RFIT_DEBUG
95  riemannFit::printIt(cov_sz, "Scatter_cov_line - cov_sz: ");
96 #endif
97  Matrix2Nd<N> tmp = Matrix2Nd<N>::Zero();
98  for (uint k = 0; k < n; ++k) {
99  tmp(k, k) = cov_sz[k](0, 0);
100  tmp(k + n, k + n) = cov_sz[k](1, 1);
101  tmp(k, k + n) = tmp(k + n, k) = cov_sz[k](0, 1);
102  }
103  for (uint k = 0; k < n; ++k) {
104  for (uint l = k; l < n; ++l) {
105  for (uint i = 0; i < uint(alpaka::math::min(acc, k, l)); ++i) {
106  tmp(k + n, l + n) += alpaka::math::abs(acc, s_values(k) - s_values(i)) *
107  alpaka::math::abs(acc, s_values(l) - s_values(i)) * sig2_S(i);
108  }
109  tmp(l + n, k + n) = tmp(k + n, l + n);
110  }
111  }
112  // We are interested only in the errors orthogonal to the rotated s-axis
113  // which, in our formalism, are in the lower square matrix.
114 #ifdef RFIT_DEBUG
115  riemannFit::printIt(&tmp, "Scatter_cov_line - tmp: ");
116 #endif
117  ret = tmp.block(n, n, n, n);
118  }
ret
prodAgent to be discontinued
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
__host__ __device__ void computeRadLenUniformMaterial(const VNd1 &length_values, VNd2 &rad_lengths)
Definition: RiemannFit.h:34
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
#define N
Definition: blowfish.cc:9
Square< F >::type sqr(const F &f)
Definition: Square.h:14
tmp
align.sh
Definition: createJobs.py:716
__host__ __device__ void printIt(C *m, const char *prefix="")
Definition: FitUtils.h:53

◆ sqr()

template<typename T >
constexpr T ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::sqr ( const T  a)

◆ weightCircle()

template<typename TAcc , int N>
ALPAKA_FN_ACC ALPAKA_FN_INLINE VectorNd<N> ALPAKA_ACCELERATOR_NAMESPACE::riemannFit::weightCircle ( const TAcc &  acc,
const MatrixNd< N > &  cov_rad_inv 
)

Compute the points' weights' vector for the circle fit when multiple scattering is managed. Further information in attached documentation.

Parameters
cov_rad_invcovariance matrix inverse in radial coordinated (or, beter, pre-fitted circle's orthogonal system).
Returns
weight VectorNd points' weights' vector.

Definition at line 284 of file RiemannFit.h.

Referenced by circleFit().

284  {
285  return cov_rad_inv.colwise().sum().transpose();
286  }