CMS 3D CMS Logo

Classes | Typedefs | Functions | Variables
riemannFit Namespace Reference

Classes

struct  CircleFit
 
struct  HelixFit
 
struct  LineFit
 

Typedefs

template<int N>
using Array2xNd = Eigen::Array< double, 2, N >
 
template<int N>
using ArrayNd = Eigen::Array< double, N, N >
 
using Map3x4d = Eigen::Map< Matrix3x4d, 0, Eigen::Stride< 3 *stride, stride > >
 
template<int N>
using Map3xNd = Eigen::Map< Matrix3xNd< N >, 0, Eigen::Stride< 3 *stride, stride > >
 
using Map4d = Eigen::Map< Vector4d, 0, Eigen::InnerStride< stride > >
 
using Map6x4f = Eigen::Map< Matrix6x4f, 0, Eigen::Stride< 6 *stride, stride > >
 
template<int N>
using Map6xNf = Eigen::Map< Matrix6xNf< N >, 0, Eigen::Stride< 6 *stride, stride > >
 
using Matrix2d = Eigen::Matrix2d
 
template<int N>
using Matrix2Nd = Eigen::Matrix< double, 2 *N, 2 *N >
 
using Matrix2x3d = Eigen::Matrix< double, 2, 3 >
 
template<int N>
using Matrix2xNd = Eigen::Matrix< double, 2, N >
 
using Matrix3d = Eigen::Matrix3d
 
using Matrix3f = Eigen::Matrix3f
 
template<int N>
using Matrix3Nd = Eigen::Matrix< double, 3 *N, 3 *N >
 
using Matrix3x4d = Eigen::Matrix< double, 3, 4 >
 
template<int N>
using Matrix3xNd = Eigen::Matrix< double, 3, N >
 
using Matrix4d = Eigen::Matrix4d
 
using Matrix5d = Eigen::Matrix< double, 5, 5 >
 
using Matrix6d = Eigen::Matrix< double, 6, 6 >
 
using Matrix6x4f = Eigen::Matrix< float, 6, 4 >
 
template<int N>
using Matrix6xNf = Eigen::Matrix< float, 6, N >
 
template<int N>
using MatrixNd = Eigen::Matrix< double, N, N >
 
template<int N>
using MatrixNplusONEd = Eigen::Matrix< double, N+1, N+1 >
 
template<int N>
using MatrixNx3d = Eigen::Matrix< double, N, 3 >
 
template<int N>
using MatrixNx5d = Eigen::Matrix< double, N, 5 >
 
using MatrixXd = Eigen::MatrixXd
 
template<int N>
using RowVector2Nd = Eigen::Matrix< double, 1, 2 *N >
 
template<int N>
using RowVectorNd = Eigen::Matrix< double, 1, 1, N >
 
using Vector2d = Eigen::Vector2d
 
template<int N>
using Vector2Nd = Eigen::Matrix< double, 2 *N, 1 >
 
using Vector3d = Eigen::Vector3d
 
using Vector3f = Eigen::Vector3f
 
template<int N>
using Vector3Nd = Eigen::Matrix< double, 3 *N, 1 >
 
using Vector4d = Eigen::Vector4d
 
using Vector4f = Eigen::Vector4f
 
using Vector5d = Eigen::Matrix< double, 5, 1 >
 
using Vector6f = Eigen::Matrix< double, 6, 1 >
 
template<int N>
using VectorNd = Eigen::Matrix< double, N, 1 >
 
template<int N>
using VectorNplusONEd = Eigen::Matrix< double, N+1, 1 >
 
using VectorXd = Eigen::VectorXd
 

Functions

template<typename M2xN >
__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 first 2 hits) and the vector radius between the first hit and the center of the fitted circle. More...
 
template<typename M2xN , typename V4 , int N>
__host__ __device__ CircleFit circleFit (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 VNd1 , typename VNd2 >
__host__ __device__ void computeRadLenUniformMaterial (const VNd1 &length_values, VNd2 &rad_lengths)
 
template<typename M2xN , int N>
__host__ __device__ VectorNd< Ncov_carttorad (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 M2xN , typename V4 , int N>
__host__ __device__ VectorNd< Ncov_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 coordinates system orthogonal to the pre-fitted circle in each point. Further information in attached documentation. More...
 
template<typename M2xN , int N>
__host__ __device__ Matrix2Nd< Ncov_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 transverse plane component). More...
 
__host__ __device__ double cross2D (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 M3xN , typename V4 >
__host__ __device__ void fastFit (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...
 
__host__ __device__ void fromCircleToPerigee (CircleFit &circle)
 Transform circle parameter from (X0,Y0,R) to (phi,Tip,q/R) and consequently covariance matrix. More...
 
template<int N>
HelixFit helixFit (const Matrix3xNd< N > &hits, const Eigen::Matrix< float, 6, N > &hits_ge, const double bField, const bool error)
 Helix fit by three step: -fast pre-fit (see Fast_fit() for further info);
-circle fit of hits projected in the transverse plane by Riemann-Chernov algorithm (see Circle_fit() for further info);
-line fit of hits projected on cylinder surface by orthogonal distance regression (see Line_fit for further info).
Points must be passed ordered (from inner to outer layer). More...
 
template<typename M3xN , typename M6xN , typename V4 >
__host__ __device__ LineFit lineFit (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 M6xNf , typename M3xNd >
__host__ __device__ void loadCovariance (M6xNf const &ge, M3xNd &hits_cov)
 
template<typename M6xNf , typename M2Nd >
__host__ __device__ void loadCovariance2D (M6xNf const &ge, M2Nd &hits_cov)
 
__host__ __device__ Vector2d min_eigen2D (const Matrix2d &aMat, double &chi2)
 2D version of min_eigen3D(). More...
 
__host__ __device__ Vector3d min_eigen3D (const Matrix3d &A, double &chi2)
 Compute the eigenvector associated to the minimum eigenvalue. More...
 
__host__ __device__ Vector3d min_eigen3D_fast (const Matrix3d &A)
 A faster version of min_eigen3D() where double precision is not needed. More...
 
__host__ __device__ void par_uvrtopak (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<class C >
__host__ __device__ void printIt (C *m, const char *prefix="")
 
template<auto Start, auto End, auto Inc, class F >
constexpr void rolling_fits (F &&f)
 
template<typename M2xN , typename V4 , int N>
__host__ __device__ MatrixNd< Nscatter_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 multiple Coulomb scattering. More...
 
template<typename V4 , typename VNd1 , typename VNd2 , int N>
__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 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 VI5 , typename MI5 , typename VO5 , typename MO5 >
__host__ __device__ void transformToPerigeePlane (VI5 const &ip, MI5 const &icov, VO5 &op, MO5 &ocov)
 
template<int N>
__host__ __device__ VectorNd< NweightCircle (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...
 

Variables

constexpr double epsilon = 1.e-4
 used in numerical derivative (J2 in Circle_fit()) More...
 
constexpr uint32_t maxNumberOfConcurrentFits = 32 * 1024
 
constexpr uint32_t stride = maxNumberOfConcurrentFits
 

Typedef Documentation

◆ Array2xNd

template<int N>
using riemannFit::Array2xNd = typedef Eigen::Array<double, 2, N>

Definition at line 27 of file FitUtils.h.

◆ ArrayNd

template<int N>
using riemannFit::ArrayNd = typedef Eigen::Array<double, N, N>

Definition at line 19 of file FitUtils.h.

◆ Map3x4d

using riemannFit::Map3x4d = typedef Eigen::Map<Matrix3x4d, 0, Eigen::Stride<3 * stride, stride> >

Definition at line 16 of file HelixFitOnGPU.h.

◆ Map3xNd

template<int N>
using riemannFit::Map3xNd = typedef Eigen::Map<Matrix3xNd<N>, 0, Eigen::Stride<3 * stride, stride> >

Definition at line 24 of file HelixFitOnGPU.h.

◆ Map4d

using riemannFit::Map4d = typedef Eigen::Map<Vector4d, 0, Eigen::InnerStride<stride> >

Definition at line 31 of file HelixFitOnGPU.h.

◆ Map6x4f

using riemannFit::Map6x4f = typedef Eigen::Map<Matrix6x4f, 0, Eigen::Stride<6 * stride, stride> >

Definition at line 18 of file HelixFitOnGPU.h.

◆ Map6xNf

template<int N>
using riemannFit::Map6xNf = typedef Eigen::Map<Matrix6xNf<N>, 0, Eigen::Stride<6 * stride, stride> >

Definition at line 29 of file HelixFitOnGPU.h.

◆ Matrix2d

using riemannFit::Matrix2d = typedef Eigen::Matrix2d

Definition at line 17 of file FitResult.h.

◆ Matrix2Nd

template<int N>
using riemannFit::Matrix2Nd = typedef Eigen::Matrix<double, 2 * N, 2 * N>

Definition at line 21 of file FitUtils.h.

◆ Matrix2x3d

using riemannFit::Matrix2x3d = typedef Eigen::Matrix<double, 2, 3>

Definition at line 45 of file FitUtils.h.

◆ Matrix2xNd

template<int N>
using riemannFit::Matrix2xNd = typedef Eigen::Matrix<double, 2, N>

Definition at line 25 of file FitUtils.h.

◆ Matrix3d

using riemannFit::Matrix3d = typedef Eigen::Matrix3d

Definition at line 18 of file FitResult.h.

◆ Matrix3f

using riemannFit::Matrix3f = typedef Eigen::Matrix3f

Definition at line 47 of file FitUtils.h.

◆ Matrix3Nd

template<int N>
using riemannFit::Matrix3Nd = typedef Eigen::Matrix<double, 3 * N, 3 * N>

Definition at line 23 of file FitUtils.h.

◆ Matrix3x4d

using riemannFit::Matrix3x4d = typedef Eigen::Matrix<double, 3, 4>

Definition at line 15 of file HelixFitOnGPU.h.

◆ Matrix3xNd

template<int N>
using riemannFit::Matrix3xNd = typedef Eigen::Matrix<double, 3, N>

Definition at line 22 of file HelixFitOnGPU.h.

◆ Matrix4d

using riemannFit::Matrix4d = typedef Eigen::Matrix4d

Definition at line 19 of file FitResult.h.

◆ Matrix5d

using riemannFit::Matrix5d = typedef Eigen::Matrix<double, 5, 5>

Definition at line 20 of file FitResult.h.

◆ Matrix6d

using riemannFit::Matrix6d = typedef Eigen::Matrix<double, 6, 6>

Definition at line 21 of file FitResult.h.

◆ Matrix6x4f

using riemannFit::Matrix6x4f = typedef Eigen::Matrix<float, 6, 4>

Definition at line 17 of file HelixFitOnGPU.h.

◆ Matrix6xNf

template<int N>
using riemannFit::Matrix6xNf = typedef Eigen::Matrix<float, 6, N>

Definition at line 27 of file HelixFitOnGPU.h.

◆ MatrixNd

template<int N>
using riemannFit::MatrixNd = typedef Eigen::Matrix<double, N, N>

Definition at line 15 of file FitUtils.h.

◆ MatrixNplusONEd

template<int N>
using riemannFit::MatrixNplusONEd = typedef Eigen::Matrix<double, N + 1, N + 1>

Definition at line 17 of file FitUtils.h.

◆ MatrixNx3d

template<int N>
using riemannFit::MatrixNx3d = typedef Eigen::Matrix<double, N, 3>

Definition at line 29 of file FitUtils.h.

◆ MatrixNx5d

template<int N>
using riemannFit::MatrixNx5d = typedef Eigen::Matrix<double, N, 5>

Definition at line 31 of file FitUtils.h.

◆ MatrixXd

using riemannFit::MatrixXd = typedef Eigen::MatrixXd

Definition at line 13 of file FitUtils.h.

◆ RowVector2Nd

template<int N>
using riemannFit::RowVector2Nd = typedef Eigen::Matrix<double, 1, 2 * N>

Definition at line 43 of file FitUtils.h.

◆ RowVectorNd

template<int N>
using riemannFit::RowVectorNd = typedef Eigen::Matrix<double, 1, 1, N>

Definition at line 41 of file FitUtils.h.

◆ Vector2d

using riemannFit::Vector2d = typedef Eigen::Vector2d

Definition at line 13 of file FitResult.h.

◆ Vector2Nd

template<int N>
using riemannFit::Vector2Nd = typedef Eigen::Matrix<double, 2 * N, 1>

Definition at line 37 of file FitUtils.h.

◆ Vector3d

using riemannFit::Vector3d = typedef Eigen::Vector3d

Definition at line 14 of file FitResult.h.

◆ Vector3f

using riemannFit::Vector3f = typedef Eigen::Vector3f

Definition at line 48 of file FitUtils.h.

◆ Vector3Nd

template<int N>
using riemannFit::Vector3Nd = typedef Eigen::Matrix<double, 3 * N, 1>

Definition at line 39 of file FitUtils.h.

◆ Vector4d

using riemannFit::Vector4d = typedef Eigen::Vector4d

Definition at line 15 of file FitResult.h.

◆ Vector4f

using riemannFit::Vector4f = typedef Eigen::Vector4f

Definition at line 49 of file FitUtils.h.

◆ Vector5d

using riemannFit::Vector5d = typedef Eigen::Matrix<double, 5, 1>

Definition at line 16 of file FitResult.h.

◆ Vector6f

using riemannFit::Vector6f = typedef Eigen::Matrix<double, 6, 1>

Definition at line 50 of file FitUtils.h.

◆ VectorNd

template<int N>
using riemannFit::VectorNd = typedef Eigen::Matrix<double, N, 1>

Definition at line 33 of file FitUtils.h.

◆ VectorNplusONEd

template<int N>
using riemannFit::VectorNplusONEd = typedef Eigen::Matrix<double, N + 1, 1>

Definition at line 35 of file FitUtils.h.

◆ VectorXd

using riemannFit::VectorXd = typedef Eigen::VectorXd

Definition at line 12 of file FitUtils.h.

Function Documentation

◆ charge()

template<typename M2xN >
__host__ __device__ int32_t riemannFit::charge ( const M2xN &  p2D,
const Vector3d par_uvr 
)
inline

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 288 of file RiemannFit.h.

Referenced by circleFit().

288  {
289  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)) >
290  0)
291  ? -1
292  : 1;
293  }

◆ circleFit()

template<typename M2xN , typename V4 , int N>
__host__ __device__ CircleFit riemannFit::circleFit ( const M2xN &  hits2D,
const Matrix2Nd< N > &  hits_cov2D,
const V4 &  fast_fit,
const VectorNd< N > &  rad,
const double  bField,
const bool  error 
)
inline

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 455 of file RiemannFit.h.

References a, funct::abs(), b, Calorimetry_cff::bField, charge(), riemannFit::CircleFit::chi2, nano_mu_local_reco_cff::chi2, riemannFit::CircleFit::cov, cov_carttorad_prefit(), cov_radtocart(), dumpMFGeometry_cfg::delta, epsilon, relativeConstraints::error, 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, riemannFit::CircleFit::par, printIt(), riemannFit::CircleFit::qCharge, 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 helixFit().

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

◆ computeRadLenUniformMaterial()

template<typename VNd1 , typename VNd2 >
__host__ __device__ void riemannFit::computeRadLenUniformMaterial ( const VNd1 &  length_values,
VNd2 &  rad_lengths 
)
inline

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 31 of file RiemannFit.h.

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

Referenced by scatter_cov_rad(), and scatterCovLine().

31  {
32  // Radiation length of the pixel detector in the uniform assumption, with
33  // 0.06 rad_len at 16 cm
34  constexpr double xx_0_inv = 0.06 / 16.;
35  uint n = length_values.rows();
36  rad_lengths(0) = length_values(0) * xx_0_inv;
37  for (uint j = 1; j < n; ++j) {
38  rad_lengths(j) = std::abs(length_values(j) - length_values(j - 1)) * xx_0_inv;
39  }
40  }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22

◆ cov_carttorad()

template<typename M2xN , int N>
__host__ __device__ VectorNd<N> riemannFit::cov_carttorad ( const M2xN &  p2D,
const Matrix2Nd< N > &  cov_cart,
const VectorNd< N > &  rad 
)
inline

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 208 of file RiemannFit.h.

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

210  {
211  constexpr uint n = N;
212  VectorNd<N> cov_rad;
213  const VectorNd<N> rad_inv2 = rad.cwiseInverse().array().square();
214  for (uint i = 0; i < n; ++i) {
216  if (rad(i) < 1.e-4)
217  cov_rad(i) = cov_cart(i, i);
218  else {
219  cov_rad(i) = rad_inv2(i) * (cov_cart(i, i) * sqr(p2D(1, i)) + cov_cart(i + n, i + n) * sqr(p2D(0, i)) -
220  2. * cov_cart(i, i + n) * p2D(0, i) * p2D(1, i));
221  }
222  }
223  return cov_rad;
224  }
#define N
Definition: blowfish.cc:9
Square< F >::type sqr(const F &f)
Definition: Square.h:14

◆ cov_carttorad_prefit()

template<typename M2xN , typename V4 , int N>
__host__ __device__ VectorNd<N> riemannFit::cov_carttorad_prefit ( const M2xN &  p2D,
const Matrix2Nd< N > &  cov_cart,
V4 &  fast_fit,
const VectorNd< N > &  rad 
)
inline

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 239 of file RiemannFit.h.

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

Referenced by circleFit().

242  {
243  constexpr uint n = N;
244  VectorNd<N> cov_rad;
245  for (uint i = 0; i < n; ++i) {
247  if (rad(i) < 1.e-4)
248  cov_rad(i) = cov_cart(i, i); // TO FIX
249  else {
250  Vector2d a = p2D.col(i);
251  Vector2d b = p2D.col(i) - fast_fit.head(2);
252  const double x2 = a.dot(b);
253  const double y2 = cross2D(a, b);
254  const double tan_c = -y2 / x2;
255  const double tan_c2 = sqr(tan_c);
256  cov_rad(i) =
257  1. / (1. + tan_c2) * (cov_cart(i, i) + cov_cart(i + n, i + n) * tan_c2 + 2 * cov_cart(i, i + n) * tan_c);
258  }
259  }
260  return cov_rad;
261  }
__host__ __device__ double cross2D(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:79
Eigen::Vector2d Vector2d
Definition: FitResult.h:13
#define N
Definition: blowfish.cc:9
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 M2xN , int N>
__host__ __device__ Matrix2Nd<N> riemannFit::cov_radtocart ( const M2xN &  p2D,
const MatrixNd< N > &  cov_rad,
const VectorNd< N > &  rad 
)
inline

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 171 of file RiemannFit.h.

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

Referenced by circleFit().

173  {
174 #ifdef RFIT_DEBUG
175  printf("Address of p2D: %p\n", &p2D);
176 #endif
177  printIt(&p2D, "cov_radtocart - p2D:");
178  constexpr uint n = N;
179  Matrix2Nd<N> cov_cart = Matrix2Nd<N>::Zero();
180  VectorNd<N> rad_inv = rad.cwiseInverse();
181  printIt(&rad_inv, "cov_radtocart - rad_inv:");
182  for (uint i = 0; i < n; ++i) {
183  for (uint j = i; j < n; ++j) {
184  cov_cart(i, j) = cov_rad(i, j) * p2D(1, i) * rad_inv(i) * p2D(1, j) * rad_inv(j);
185  cov_cart(i + n, j + n) = cov_rad(i, j) * p2D(0, i) * rad_inv(i) * p2D(0, j) * rad_inv(j);
186  cov_cart(i, j + n) = -cov_rad(i, j) * p2D(1, i) * rad_inv(i) * p2D(0, j) * rad_inv(j);
187  cov_cart(i + n, j) = -cov_rad(i, j) * p2D(0, i) * rad_inv(i) * p2D(1, j) * rad_inv(j);
188  cov_cart(j, i) = cov_cart(i, j);
189  cov_cart(j + n, i + n) = cov_cart(i + n, j + n);
190  cov_cart(j + n, i) = cov_cart(i, j + n);
191  cov_cart(j, i + n) = cov_cart(i + n, j);
192  }
193  }
194  return cov_cart;
195  }
#define N
Definition: blowfish.cc:9
__host__ __device__ void printIt(C *m, const char *prefix="")
Definition: FitUtils.h:53

◆ cross2D()

__host__ __device__ double riemannFit::cross2D ( const Vector2d a,
const Vector2d b 
)
inline

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 79 of file FitUtils.h.

References a, and b.

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

79  {
80  return a.x() * b.y() - a.y() * b.x();
81  }
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121

◆ fastFit()

template<typename M3xN , typename V4 >
__host__ __device__ void riemannFit::fastFit ( const M3xN &  hits,
V4 &  result 
)
inline

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 375 of file RiemannFit.h.

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

Referenced by for(), and helixFit().

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

◆ fromCircleToPerigee()

__host__ __device__ void riemannFit::fromCircleToPerigee ( CircleFit circle)
inline

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 196 of file FitUtils.h.

References riemannFit::CircleFit::cov, riemannFit::CircleFit::par, riemannFit::CircleFit::qCharge, sqr(), and mathSSE::sqrt().

196  {
197  Vector3d par_pak;
198  const double temp0 = circle.par.head(2).squaredNorm();
199  const double temp1 = sqrt(temp0);
200  par_pak << atan2(circle.qCharge * circle.par(0), -circle.qCharge * circle.par(1)),
201  circle.qCharge * (temp1 - circle.par(2)), circle.qCharge / circle.par(2);
202 
203  const double temp2 = sqr(circle.par(0)) * 1. / temp0;
204  const double temp3 = 1. / temp1 * circle.qCharge;
205  Matrix3d j4Mat;
206  j4Mat << -circle.par(1) * temp2 * 1. / sqr(circle.par(0)), temp2 * 1. / circle.par(0), 0., circle.par(0) * temp3,
207  circle.par(1) * temp3, -circle.qCharge, 0., 0., -circle.qCharge / (circle.par(2) * circle.par(2));
208  circle.cov = j4Mat * circle.cov * j4Mat.transpose();
209 
210  circle.par = par_pak;
211  }
T sqrt(T t)
Definition: SSEVec.h:19
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:18
Eigen::Vector3d Vector3d
Definition: FitResult.h:14

◆ helixFit()

template<int N>
HelixFit riemannFit::helixFit ( const Matrix3xNd< N > &  hits,
const Eigen::Matrix< float, 6, N > &  hits_ge,
const double  bField,
const bool  error 
)
inline

Helix fit by three step: -fast pre-fit (see Fast_fit() for further info);
-circle fit of hits projected in the transverse plane by Riemann-Chernov algorithm (see Circle_fit() for further info);
-line fit of hits projected on cylinder surface by orthogonal distance regression (see Line_fit for further info).
Points must be passed ordered (from inner to outer layer).

Parameters
hitsMatrix3xNd hits coordinates in this form:
|x0|x1|x2|...|xn|
|y0|y1|y2|...|yn|
|z0|z1|z2|...|zn|
hits_covMatrix3Nd covariance matrix in this form (()->cov()):
|(x0,x0)|(x1,x0)|(x2,x0)|.|(y0,x0)|(y1,x0)|(y2,x0)|.|(z0,x0)|(z1,x0)|(z2,x0)|
|(x0,x1)|(x1,x1)|(x2,x1)|.|(y0,x1)|(y1,x1)|(y2,x1)|.|(z0,x1)|(z1,x1)|(z2,x1)|
|(x0,x2)|(x1,x2)|(x2,x2)|.|(y0,x2)|(y1,x2)|(y2,x2)|.|(z0,x2)|(z1,x2)|(z2,x2)|
. . . . . . . . . . .
|(x0,y0)|(x1,y0)|(x2,y0)|.|(y0,y0)|(y1,y0)|(y2,x0)|.|(z0,y0)|(z1,y0)|(z2,y0)|
|(x0,y1)|(x1,y1)|(x2,y1)|.|(y0,y1)|(y1,y1)|(y2,x1)|.|(z0,y1)|(z1,y1)|(z2,y1)|
|(x0,y2)|(x1,y2)|(x2,y2)|.|(y0,y2)|(y1,y2)|(y2,x2)|.|(z0,y2)|(z1,y2)|(z2,y2)|
. . . . . . . . . . .
|(x0,z0)|(x1,z0)|(x2,z0)|.|(y0,z0)|(y1,z0)|(y2,z0)|.|(z0,z0)|(z1,z0)|(z2,z0)|
|(x0,z1)|(x1,z1)|(x2,z1)|.|(y0,z1)|(y1,z1)|(y2,z1)|.|(z0,z1)|(z1,z1)|(z2,z1)|
|(x0,z2)|(x1,z2)|(x2,z2)|.|(y0,z2)|(y1,z2)|(y2,z2)|.|(z0,z2)|(z1,z2)|(z2,z2)|
bFieldmagnetic field in the center of the detector in Gev/cm/c unit, in order to perform pt calculation.
errorflag for error computation.
scatteringflag for multiple scattering treatment. (see Circle_fit() documentation for further info).
Warning
see Circle_fit(), Line_fit() and Fast_fit() warnings.

Definition at line 975 of file RiemannFit.h.

References Calorimetry_cff::bField, riemannFit::CircleFit::chi2, riemannFit::HelixFit::chi2_circle, riemannFit::HelixFit::chi2_line, circleFit(), riemannFit::CircleFit::cov, riemannFit::HelixFit::cov, relativeConstraints::error, fastFit(), hfClusterShapes_cfi::hits, mps_splice::line, lineFit(), loadCovariance2D(), N, dqmiodumpmetadata::n, riemannFit::CircleFit::par, riemannFit::HelixFit::par, par_uvrtopak(), riemannFit::CircleFit::qCharge, riemannFit::HelixFit::qCharge, and parallelization::uint.

Referenced by PixelNtupletsFitter::run().

978  {
979  constexpr uint n = N;
980  VectorNd<4> rad = (hits.block(0, 0, 2, n).colwise().norm());
981 
982  // Fast_fit gives back (X0, Y0, R, theta) w/o errors, using only 3 points.
983  Vector4d fast_fit;
984  fastFit(hits, fast_fit);
985  riemannFit::Matrix2Nd<N> hits_cov = MatrixXd::Zero(2 * n, 2 * n);
986  riemannFit::loadCovariance2D(hits_ge, hits_cov);
987  CircleFit circle = circleFit(hits.block(0, 0, 2, n), hits_cov, fast_fit, rad, bField, error);
988  LineFit line = lineFit(hits, hits_ge, circle, fast_fit, bField, error);
989 
990  par_uvrtopak(circle, bField, error);
991 
992  HelixFit helix;
993  helix.par << circle.par, line.par;
994  if (error) {
995  helix.cov = MatrixXd::Zero(5, 5);
996  helix.cov.block(0, 0, 3, 3) = circle.cov;
997  helix.cov.block(3, 3, 2, 2) = line.cov;
998  }
999  helix.qCharge = circle.qCharge;
1000  helix.chi2_circle = circle.chi2;
1001  helix.chi2_line = line.chi2;
1002 
1003  return helix;
1004  }
__host__ __device__ LineFit lineFit(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...
Definition: RiemannFit.h:785
__host__ __device__ CircleFit circleFit(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...
Definition: RiemannFit.h:455
__host__ __device__ void par_uvrtopak(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:173
Eigen::Matrix< double, 2 *N, 2 *N > Matrix2Nd
Definition: FitUtils.h:21
#define N
Definition: blowfish.cc:9
Eigen::Vector4d Vector4d
Definition: FitResult.h:15
__host__ __device__ void loadCovariance2D(M6xNf const &ge, M2Nd &hits_cov)
Definition: FitUtils.h:88
__host__ __device__ void fastFit(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 ...
Definition: RiemannFit.h:375

◆ lineFit()

template<typename M3xN , typename M6xN , typename V4 >
__host__ __device__ LineFit riemannFit::lineFit ( const M3xN &  hits,
const M6xN &  hits_ge,
const CircleFit circle,
const V4 &  fast_fit,
const double  bField,
const bool  error 
)
inline

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 785 of file RiemannFit.h.

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

Referenced by helixFit().

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

◆ loadCovariance()

template<typename M6xNf , typename M3xNd >
__host__ __device__ void riemannFit::loadCovariance ( M6xNf const &  ge,
M3xNd &  hits_cov 
)

Definition at line 120 of file FitUtils.h.

References mps_fire::i, dqmiolumiharvest::j, and MainPageGenerator::l.

120  {
121  // Index numerology:
122  // i: index of the hits/point (0,..,3)
123  // j: index of space component (x,y,z)
124  // l: index of space components (x,y,z)
125  // ge is always in sync with the index i and is formatted as:
126  // ge[] ==> [xx, xy, yy, xz, yz, zz]
127  // in (j,l) notation, we have:
128  // ge[] ==> [(0,0), (0,1), (1,1), (0,2), (1,2), (2,2)]
129  // so the index ge_idx corresponds to the matrix elements:
130  // | 0 1 3 |
131  // | 1 2 4 |
132  // | 3 4 5 |
133  constexpr uint32_t hits_in_fit = M6xNf::ColsAtCompileTime;
134  for (uint32_t i = 0; i < hits_in_fit; ++i) {
135  {
136  constexpr uint32_t ge_idx = 0, j = 0, l = 0;
137  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
138  }
139  {
140  constexpr uint32_t ge_idx = 2, j = 1, l = 1;
141  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
142  }
143  {
144  constexpr uint32_t ge_idx = 5, j = 2, l = 2;
145  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
146  }
147  {
148  constexpr uint32_t ge_idx = 1, j = 1, l = 0;
149  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
150  ge.col(i)[ge_idx];
151  }
152  {
153  constexpr uint32_t ge_idx = 3, j = 2, l = 0;
154  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
155  ge.col(i)[ge_idx];
156  }
157  {
158  constexpr uint32_t ge_idx = 4, j = 2, l = 1;
159  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
160  ge.col(i)[ge_idx];
161  }
162  }
163  }

◆ loadCovariance2D()

template<typename M6xNf , typename M2Nd >
__host__ __device__ void riemannFit::loadCovariance2D ( M6xNf const &  ge,
M2Nd &  hits_cov 
)

load error in CMSSW format to our formalism

Definition at line 88 of file FitUtils.h.

References mps_fire::i, dqmiolumiharvest::j, and MainPageGenerator::l.

Referenced by helixFit().

88  {
89  // Index numerology:
90  // i: index of the hits/point (0,..,3)
91  // j: index of space component (x,y,z)
92  // l: index of space components (x,y,z)
93  // ge is always in sync with the index i and is formatted as:
94  // ge[] ==> [xx, xy, yy, xz, yz, zz]
95  // in (j,l) notation, we have:
96  // ge[] ==> [(0,0), (0,1), (1,1), (0,2), (1,2), (2,2)]
97  // so the index ge_idx corresponds to the matrix elements:
98  // | 0 1 3 |
99  // | 1 2 4 |
100  // | 3 4 5 |
101  constexpr uint32_t hits_in_fit = M6xNf::ColsAtCompileTime;
102  for (uint32_t i = 0; i < hits_in_fit; ++i) {
103  {
104  constexpr uint32_t ge_idx = 0, j = 0, l = 0;
105  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
106  }
107  {
108  constexpr uint32_t ge_idx = 2, j = 1, l = 1;
109  hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) = ge.col(i)[ge_idx];
110  }
111  {
112  constexpr uint32_t ge_idx = 1, j = 1, l = 0;
113  hits_cov(i + l * hits_in_fit, i + j * hits_in_fit) = hits_cov(i + j * hits_in_fit, i + l * hits_in_fit) =
114  ge.col(i)[ge_idx];
115  }
116  }
117  }

◆ min_eigen2D()

__host__ __device__ Vector2d riemannFit::min_eigen2D ( const Matrix2d aMat,
double &  chi2 
)
inline

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 353 of file RiemannFit.h.

References nano_mu_local_reco_cff::chi2.

353  {
354  Eigen::SelfAdjointEigenSolver<Matrix2d> solver(2);
355  solver.computeDirect(aMat);
356  int min_index;
357  chi2 = solver.eigenvalues().minCoeff(&min_index);
358  return solver.eigenvectors().col(min_index);
359  }

◆ min_eigen3D()

__host__ __device__ Vector3d riemannFit::min_eigen3D ( const Matrix3d A,
double &  chi2 
)
inline

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 310 of file RiemannFit.h.

References A, and nano_mu_local_reco_cff::chi2.

Referenced by circleFit().

310  {
311 #ifdef RFIT_DEBUG
312  printf("min_eigen3D - enter\n");
313 #endif
314  Eigen::SelfAdjointEigenSolver<Matrix3d> solver(3);
315  solver.computeDirect(A);
316  int min_index;
317  chi2 = solver.eigenvalues().minCoeff(&min_index);
318 #ifdef RFIT_DEBUG
319  printf("min_eigen3D - exit\n");
320 #endif
321  return solver.eigenvectors().col(min_index);
322  }
Definition: APVGainStruct.h:7

◆ min_eigen3D_fast()

__host__ __device__ Vector3d riemannFit::min_eigen3D_fast ( const Matrix3d A)
inline

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 335 of file RiemannFit.h.

References A.

Referenced by circleFit().

335  {
336  Eigen::SelfAdjointEigenSolver<Matrix3f> solver(3);
337  solver.computeDirect(A.cast<float>());
338  int min_index;
339  solver.eigenvalues().minCoeff(&min_index);
340  return solver.eigenvectors().col(min_index).cast<double>();
341  }
Definition: APVGainStruct.h:7

◆ par_uvrtopak()

__host__ __device__ void riemannFit::par_uvrtopak ( CircleFit circle,
const double  B,
const bool  error 
)
inline

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 173 of file FitUtils.h.

References B, riemannFit::CircleFit::cov, relativeConstraints::error, riemannFit::CircleFit::par, riemannFit::CircleFit::qCharge, sqr(), and mathSSE::sqrt().

Referenced by helixFit().

173  {
174  Vector3d par_pak;
175  const double temp0 = circle.par.head(2).squaredNorm();
176  const double temp1 = sqrt(temp0);
177  par_pak << atan2(circle.qCharge * circle.par(0), -circle.qCharge * circle.par(1)),
178  circle.qCharge * (temp1 - circle.par(2)), circle.par(2) * B;
179  if (error) {
180  const double temp2 = sqr(circle.par(0)) * 1. / temp0;
181  const double temp3 = 1. / temp1 * circle.qCharge;
182  Matrix3d j4Mat;
183  j4Mat << -circle.par(1) * temp2 * 1. / sqr(circle.par(0)), temp2 * 1. / circle.par(0), 0., circle.par(0) * temp3,
184  circle.par(1) * temp3, -circle.qCharge, 0., 0., B;
185  circle.cov = j4Mat * circle.cov * j4Mat.transpose();
186  }
187  circle.par = par_pak;
188  }
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
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:18
Eigen::Vector3d Vector3d
Definition: FitResult.h:14

◆ printIt()

template<class C >
__host__ __device__ void riemannFit::printIt ( C *  m,
const char *  prefix = "" 
)

◆ rolling_fits()

template<auto Start, auto End, auto Inc, class F >
constexpr void riemannFit::rolling_fits ( F &&  f)

Definition at line 34 of file HelixFitOnGPU.h.

References PixelRegions::End, and f.

34  {
35  if constexpr (Start < End) {
36  f(std::integral_constant<decltype(Start), Start>());
37  rolling_fits<Start + Inc, End, Inc>(f);
38  }
39  }
double f[11][100]

◆ scatter_cov_rad()

template<typename M2xN , typename V4 , int N>
__host__ __device__ MatrixNd<N> riemannFit::scatter_cov_rad ( const M2xN &  p2D,
const V4 &  fast_fit,
VectorNd< N > const &  rad,
double  B 
)
inline

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 123 of file RiemannFit.h.

References funct::abs(), B, computeRadLenUniformMaterial(), cross(), cross2D(), dot(), 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().

126  {
127  constexpr uint n = N;
128  double p_t = std::min(20., fast_fit(2) * B); // limit pt to avoid too small error!!!
129  double p_2 = p_t * p_t * (1. + 1. / sqr(fast_fit(3)));
130  double theta = atan(fast_fit(3));
131  theta = theta < 0. ? theta + M_PI : theta;
132  VectorNd<N> s_values;
133  VectorNd<N> rad_lengths;
134  const Vector2d oVec(fast_fit(0), fast_fit(1));
135 
136  // associated Jacobian, used in weights and errors computation
137  for (uint i = 0; i < n; ++i) { // x
138  Vector2d pVec = p2D.block(0, i, 2, 1) - oVec;
139  const double cross = cross2D(-oVec, pVec);
140  const double dot = (-oVec).dot(pVec);
141  const double tempAtan2 = atan2(cross, dot);
142  s_values(i) = std::abs(tempAtan2 * fast_fit(2));
143  }
144  computeRadLenUniformMaterial(s_values * sqrt(1. + 1. / sqr(fast_fit(3))), rad_lengths);
145  MatrixNd<N> scatter_cov_rad = MatrixNd<N>::Zero();
146  VectorNd<N> sig2 = (1. + 0.038 * rad_lengths.array().log()).abs2() * rad_lengths.array();
147  sig2 *= 0.000225 / (p_2 * sqr(sin(theta)));
148  for (uint k = 0; k < n; ++k) {
149  for (uint l = k; l < n; ++l) {
150  for (uint i = 0; i < std::min(k, l); ++i) {
151  scatter_cov_rad(k, l) += (rad(k) - rad(i)) * (rad(l) - rad(i)) * sig2(i);
152  }
154  }
155  }
156 #ifdef RFIT_DEBUG
157  riemannFit::printIt(&scatter_cov_rad, "Scatter_cov_rad - scatter_cov_rad: ");
158 #endif
159  return scatter_cov_rad;
160  }
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
__host__ __device__ double cross2D(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:79
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
Eigen::Vector2d Vector2d
Definition: FitResult.h:13
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:31
#define M_PI
#define N
Definition: blowfish.cc:9
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:123
Geom::Theta< T > theta() const
__host__ __device__ void printIt(C *m, const char *prefix="")
Definition: FitUtils.h:53

◆ scatterCovLine()

template<typename V4 , typename VNd1 , typename VNd2 , int N>
__host__ __device__ auto riemannFit::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 
)
inline

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 62 of file RiemannFit.h.

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

Referenced by lineFit().

68  {
69 #ifdef RFIT_DEBUG
70  riemannFit::printIt(&s_arcs, "Scatter_cov_line - s_arcs: ");
71 #endif
72  constexpr uint n = N;
73  double p_t = std::min(20., fast_fit(2) * bField); // limit pt to avoid too small error!!!
74  double p_2 = p_t * p_t * (1. + 1. / sqr(fast_fit(3)));
75  VectorNd<N> rad_lengths_S;
76  // See documentation at http://eigen.tuxfamily.org/dox/group__TutorialArrayClass.html
77  // Basically, to perform cwise operations on Matrices and Vectors, you need
78  // to transform them into Array-like objects.
79  VectorNd<N> s_values = s_arcs.array() * s_arcs.array() + z_values.array() * z_values.array();
80  s_values = s_values.array().sqrt();
81  computeRadLenUniformMaterial(s_values, rad_lengths_S);
82  VectorNd<N> sig2_S;
83  sig2_S = .000225 / p_2 * (1. + 0.038 * rad_lengths_S.array().log()).abs2() * rad_lengths_S.array();
84 #ifdef RFIT_DEBUG
85  riemannFit::printIt(cov_sz, "Scatter_cov_line - cov_sz: ");
86 #endif
87  Matrix2Nd<N> tmp = Matrix2Nd<N>::Zero();
88  for (uint k = 0; k < n; ++k) {
89  tmp(k, k) = cov_sz[k](0, 0);
90  tmp(k + n, k + n) = cov_sz[k](1, 1);
91  tmp(k, k + n) = tmp(k + n, k) = cov_sz[k](0, 1);
92  }
93  for (uint k = 0; k < n; ++k) {
94  for (uint l = k; l < n; ++l) {
95  for (uint i = 0; i < std::min(k, l); ++i) {
96  tmp(k + n, l + n) += std::abs(s_values(k) - s_values(i)) * std::abs(s_values(l) - s_values(i)) * sig2_S(i);
97  }
98  tmp(l + n, k + n) = tmp(k + n, l + n);
99  }
100  }
101  // We are interested only in the errors orthogonal to the rotated s-axis
102  // which, in our formalism, are in the lower square matrix.
103 #ifdef RFIT_DEBUG
104  riemannFit::printIt(&tmp, "Scatter_cov_line - tmp: ");
105 #endif
106  ret = tmp.block(n, n, n, n);
107  }
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:31
#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 riemannFit::sqr ( const T  a)

◆ transformToPerigeePlane()

template<typename VI5 , typename MI5 , typename VO5 , typename MO5 >
__host__ __device__ void riemannFit::transformToPerigeePlane ( VI5 const &  ip,
MI5 const &  icov,
VO5 &  op,
MO5 &  ocov 
)
inline

Definition at line 218 of file FitUtils.h.

References findAndChange::op, and mathSSE::sqrt().

Referenced by L2TauNNProducer::impactParameter(), SeedProducerFromSoAT< TrackerTraits >::produce(), and PixelTrackProducerFromSoAT< TrackerTraits >::produce().

218  {
219  auto sinTheta2 = 1. / (1. + ip(3) * ip(3));
220  auto sinTheta = std::sqrt(sinTheta2);
221  auto cosTheta = ip(3) * sinTheta;
222 
223  op(0) = sinTheta * ip(2);
224  op(1) = 0.;
225  op(2) = -ip(3);
226  op(3) = ip(1);
227  op(4) = -ip(4);
228 
229  Matrix5d jMat = Matrix5d::Zero();
230 
231  jMat(0, 2) = sinTheta;
232  jMat(0, 3) = -sinTheta2 * cosTheta * ip(2);
233  jMat(1, 0) = 1.;
234  jMat(2, 3) = -1.;
235  jMat(3, 1) = 1.;
236  jMat(4, 4) = -1;
237 
238  ocov = jMat * icov * jMat.transpose();
239  }
T sqrt(T t)
Definition: SSEVec.h:19
Eigen::Matrix< double, 5, 5 > Matrix5d
Definition: FitResult.h:20

◆ weightCircle()

template<int N>
__host__ __device__ VectorNd<N> riemannFit::weightCircle ( const MatrixNd< N > &  cov_rad_inv)
inline

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 275 of file RiemannFit.h.

Referenced by circleFit().

275  {
276  return cov_rad_inv.colwise().sum().transpose();
277  }

Variable Documentation

◆ epsilon

constexpr double riemannFit::epsilon = 1.e-4

used in numerical derivative (J2 in Circle_fit())

Definition at line 10 of file FitUtils.h.

Referenced by circleFit().

◆ maxNumberOfConcurrentFits

constexpr uint32_t riemannFit::maxNumberOfConcurrentFits = 32 * 1024

Definition at line 13 of file HelixFitOnGPU.h.

◆ stride

constexpr uint32_t riemannFit::stride = maxNumberOfConcurrentFits

Definition at line 14 of file HelixFitOnGPU.h.