CMS 3D CMS Logo

Classes | Typedefs | Functions
brokenline Namespace Reference

Classes

struct  PreparedBrokenLineData
 data needed for the Broken Line fit procedure. More...
 

Typedefs

using karimaki_circle_fit = riemannFit::CircleFit
 < Karimäki's parameters: (phi, d, k=1/R) More...
 

Functions

template<typename M3xN , typename M6xN , typename V4 , int n>
__host__ __device__ void circleFit (const M3xN &hits, const M6xN &hits_ge, const V4 &fast_fit, const double bField, PreparedBrokenLineData< n > &data, karimaki_circle_fit &circle_results)
 Performs the Broken Line fit in the curved track case (that is, the fit parameters are the interceptions u and the curvature correction ). More...
 
template<typename M3xN , typename V4 >
__host__ __device__ void fastFit (const M3xN &hits, V4 &result)
 A very fast helix fit. More...
 
template<int n>
riemannFit::HelixFit helixFit (const riemannFit::Matrix3xNd< n > &hits, const Eigen::Matrix< float, 6, 4 > &hits_ge, const double bField)
 Helix fit by three step: -fast pre-fit (see Fast_fit() for further info);
-circle fit of the hits projected in the transverse plane by Broken Line algorithm (see BL_Circle_fit() for further info);
-line fit of the hits projected on the (pre-fitted) cilinder surface by Broken Line algorithm (see BL_Line_fit() for further info);
Points must be passed ordered (from inner to outer layer). More...
 
template<typename V4 , typename M6xN , int n>
__host__ __device__ void lineFit (const M6xN &hits_ge, const V4 &fast_fit, const double bField, const PreparedBrokenLineData< n > &data, riemannFit::LineFit &line_results)
 Performs the Broken Line fit in the straight track case (that is, the fit parameters are only the interceptions u). More...
 
template<int n>
__host__ __device__ riemannFit::MatrixNd< n > matrixC_u (const riemannFit::VectorNd< n > &weights, const riemannFit::VectorNd< n > &sTotal, const riemannFit::VectorNd< n > &varBeta)
 Computes the n-by-n band matrix obtained minimizing the Broken Line's cost function w.r.t u. This is the whole matrix in the case of the line fit and the main n-by-n block in the case of the circle fit. More...
 
__host__ __device__ double multScatt (const double &length, const double bField, const double radius, int layer, double slope)
 Computes the Coulomb multiple scattering variance of the planar angle. More...
 
template<typename M3xN , typename V4 , int n>
__host__ __device__ void prepareBrokenLineData (const M3xN &hits, const V4 &fast_fit, const double bField, PreparedBrokenLineData< n > &results)
 Computes the data needed for the Broken Line fit procedure that are mainly common for the circle and the line fit. More...
 
__host__ __device__ riemannFit::Matrix2d rotationMatrix (double slope)
 Computes the 2D rotation matrix that transforms the line y=slope*x into the line y=0. More...
 
__host__ __device__ void translateKarimaki (karimaki_circle_fit &circle, double x0, double y0, riemannFit::Matrix3d &jacobian)
 Changes the Karimäki parameters (and consequently their covariance matrix) under a translation of the coordinate system, such that the old origin has coordinates (x0,y0) in the new coordinate system. The formulas are taken from Karimäki V., 1990, Effective circle fitting for particle trajectories, Nucl. Instr. and Meth. A305 (1991) 187. More...
 

Typedef Documentation

◆ karimaki_circle_fit

< Karimäki's parameters: (phi, d, k=1/R)

< covariance matrix:
|cov(phi,phi)|cov( d ,phi)|cov( k ,phi)|
|cov(phi, d )|cov( d , d )|cov( k , d )|
|cov(phi, k )|cov( d , k )|cov( k , k )|
as defined in Karimäki V., 1990, Effective circle fitting for particle trajectories, Nucl. Instr. and Meth. A305 (1991) 187.

Definition at line 19 of file BrokenLine.h.

Function Documentation

◆ circleFit()

template<typename M3xN , typename M6xN , typename V4 , int n>
__host__ __device__ void brokenline::circleFit ( const M3xN &  hits,
const M6xN &  hits_ge,
const V4 &  fast_fit,
const double  bField,
PreparedBrokenLineData< n > &  data,
karimaki_circle_fit circle_results 
)
inline

Performs the Broken Line fit in the curved track case (that is, the fit parameters are the interceptions u and the curvature correction ).

Parameters
hitshits coordinates.
hits_covhits covariance matrix.
fast_fitpre-fit result in the form (X0,Y0,R,tan(theta)).
bFieldmagnetic field in Gev/cm/c.
dataPreparedBrokenLineData.
circle_resultsstruct to be filled with the results in this form: -par parameter of the line in this form: (phi, d, k);
-cov covariance matrix of the fitted parameter;
-chi2 value of the cost function in the minimum.

The function implements the steps 2 and 3 of the Broken Line fit with the curvature correction.
The step 2 is the least square fit, done by imposing the minimum constraint on the cost function and solving the consequent linear system. It determines the fitted parameters u and and their covariance matrix. The step 3 is the correction of the fast pre-fitted parameters for the innermost part of the track. It is first done in a comfortable coordinate system (the one in which the first hit is the origin) and then the parameters and their covariance matrix are transformed to the original coordinate system.

Definition at line 315 of file BrokenLine.h.

References Matriplex::atan2(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::bField, riemannFit::CircleFit::chi2, gather_cfg::cout, riemannFit::CircleFit::cov, data, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::dVec, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::eVec, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::hits, mps_fire::i, l1tstage2_dqm_sourceclient-live_cfg::invert, matrixC_u(), multScatt(), create_idmaps::n, riemannFit::CircleFit::par, riemannFit::CircleFit::qCharge, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::radii, rotationMatrix(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::rotMat, slope, riemannFit::sqr(), mathSSE::sqrt(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::sTotal, translateKarimaki(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::varBeta(), and ALPAKA_ACCELERATOR_NAMESPACE::brokenline::zInSZplane.

Referenced by helixFit().

320  {
321  circle_results.qCharge = data.qCharge;
322  auto& radii = data.radii;
323  const auto& sTransverse = data.sTransverse;
324  const auto& sTotal = data.sTotal;
325  auto& zInSZplane = data.zInSZplane;
326  auto& varBeta = data.varBeta;
327  const double slope = -circle_results.qCharge / fast_fit(3);
328  varBeta *= 1. + riemannFit::sqr(slope); // the kink angles are projected!
329 
330  for (u_int i = 0; i < n; i++) {
331  zInSZplane(i) = radii.block(0, i, 2, 1).norm() - fast_fit(2);
332  }
333 
334  riemannFit::Matrix2d vMat; // covariance matrix
335  riemannFit::VectorNd<n> weightsVec; // weights
336  riemannFit::Matrix2d rotMat; // rotation matrix point by point
337  for (u_int i = 0; i < n; i++) {
338  vMat(0, 0) = hits_ge.col(i)[0]; // x errors
339  vMat(0, 1) = vMat(1, 0) = hits_ge.col(i)[1]; // cov_xy
340  vMat(1, 1) = hits_ge.col(i)[2]; // y errors
341  rotMat = rotationMatrix(-radii(0, i) / radii(1, i));
342  weightsVec(i) =
343  1. / ((rotMat * vMat * rotMat.transpose())(1, 1)); // compute the orthogonal weight point by point
344  }
345 
347  r_uVec(n) = 0;
348  for (u_int i = 0; i < n; i++) {
349  r_uVec(i) = weightsVec(i) * zInSZplane(i);
350  }
351 
353  c_uMat.block(0, 0, n, n) = matrixC_u(weightsVec, sTransverse, varBeta);
354  c_uMat(n, n) = 0;
355  //add the border to the c_uMat matrix
356  for (u_int i = 0; i < n; i++) {
357  c_uMat(i, n) = 0;
358  if (i > 0 && i < n - 1) {
359  c_uMat(i, n) +=
360  -(sTransverse(i + 1) - sTransverse(i - 1)) * (sTransverse(i + 1) - sTransverse(i - 1)) /
361  (2. * varBeta(i) * (sTransverse(i + 1) - sTransverse(i)) * (sTransverse(i) - sTransverse(i - 1)));
362  }
363  if (i > 1) {
364  c_uMat(i, n) +=
365  (sTransverse(i) - sTransverse(i - 2)) / (2. * varBeta(i - 1) * (sTransverse(i) - sTransverse(i - 1)));
366  }
367  if (i < n - 2) {
368  c_uMat(i, n) +=
369  (sTransverse(i + 2) - sTransverse(i)) / (2. * varBeta(i + 1) * (sTransverse(i + 1) - sTransverse(i)));
370  }
371  c_uMat(n, i) = c_uMat(i, n);
372  if (i > 0 && i < n - 1)
373  c_uMat(n, n) += riemannFit::sqr(sTransverse(i + 1) - sTransverse(i - 1)) / (4. * varBeta(i));
374  }
375 
376 #ifdef CPP_DUMP
377  std::cout << "CU5\n" << c_uMat << std::endl;
378 #endif
380  math::cholesky::invert(c_uMat, iMat);
381 #ifdef CPP_DUMP
382  std::cout << "I5\n" << iMat << std::endl;
383 #endif
384 
385  riemannFit::VectorNplusONEd<n> uVec = iMat * r_uVec; // obtain the fitted parameters by solving the linear system
386 
387  // compute (phi, d_ca, k) in the system in which the midpoint of the first two corrected hits is the origin...
388 
389  radii.block(0, 0, 2, 1) /= radii.block(0, 0, 2, 1).norm();
390  radii.block(0, 1, 2, 1) /= radii.block(0, 1, 2, 1).norm();
391 
392  riemannFit::Vector2d dVec = hits.block(0, 0, 2, 1) + (-zInSZplane(0) + uVec(0)) * radii.block(0, 0, 2, 1);
393  riemannFit::Vector2d eVec = hits.block(0, 1, 2, 1) + (-zInSZplane(1) + uVec(1)) * radii.block(0, 1, 2, 1);
394  auto eMinusd = eVec - dVec;
395  auto eMinusd2 = eMinusd.squaredNorm();
396  auto tmp1 = 1. / eMinusd2;
397  auto tmp2 = sqrt(riemannFit::sqr(fast_fit(2)) - 0.25 * eMinusd2);
398 
399  circle_results.par << atan2(eMinusd(1), eMinusd(0)), circle_results.qCharge * (tmp2 - fast_fit(2)),
400  circle_results.qCharge * (1. / fast_fit(2) + uVec(n));
401 
402  tmp2 = 1. / tmp2;
403 
404  riemannFit::Matrix3d jacobian;
405  jacobian << (radii(1, 0) * eMinusd(0) - eMinusd(1) * radii(0, 0)) * tmp1,
406  (radii(1, 1) * eMinusd(0) - eMinusd(1) * radii(0, 1)) * tmp1, 0,
407  circle_results.qCharge * (eMinusd(0) * radii(0, 0) + eMinusd(1) * radii(1, 0)) * tmp2,
408  circle_results.qCharge * (eMinusd(0) * radii(0, 1) + eMinusd(1) * radii(1, 1)) * tmp2, 0, 0, 0,
409  circle_results.qCharge;
410 
411  circle_results.cov << iMat(0, 0), iMat(0, 1), iMat(0, n), iMat(1, 0), iMat(1, 1), iMat(1, n), iMat(n, 0),
412  iMat(n, 1), iMat(n, n);
413 
414  circle_results.cov = jacobian * circle_results.cov * jacobian.transpose();
415 
416  //...Translate in the system in which the first corrected hit is the origin, adding the m.s. correction...
417 
418  translateKarimaki(circle_results, 0.5 * eMinusd(0), 0.5 * eMinusd(1), jacobian);
419  circle_results.cov(0, 0) +=
420  (1 + riemannFit::sqr(slope)) * multScatt(sTotal(1) - sTotal(0), bField, fast_fit(2), 2, slope);
421 
422  //...And translate back to the original system
423 
424  translateKarimaki(circle_results, dVec(0), dVec(1), jacobian);
425 
426  // compute chi2
427  circle_results.chi2 = 0;
428  for (u_int i = 0; i < n; i++) {
429  circle_results.chi2 += weightsVec(i) * riemannFit::sqr(zInSZplane(i) - uVec(i));
430  if (i > 0 && i < n - 1)
431  circle_results.chi2 +=
432  riemannFit::sqr(uVec(i - 1) / (sTransverse(i) - sTransverse(i - 1)) -
433  uVec(i) * (sTransverse(i + 1) - sTransverse(i - 1)) /
434  ((sTransverse(i + 1) - sTransverse(i)) * (sTransverse(i) - sTransverse(i - 1))) +
435  uVec(i + 1) / (sTransverse(i + 1) - sTransverse(i)) +
436  (sTransverse(i + 1) - sTransverse(i - 1)) * uVec(n) / 2) /
437  varBeta(i);
438  }
439  }
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN & hits
Definition: BrokenLine.h:158
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
static const double slope[3]
Eigen::Matrix< double, N+1, 1 > VectorNplusONEd
Definition: FitUtils.h:39
__host__ __device__ void translateKarimaki(karimaki_circle_fit &circle, double x0, double y0, riemannFit::Matrix3d &jacobian)
Changes the Karimäki parameters (and consequently their covariance matrix) under a translation of the...
Definition: BrokenLine.h:98
__host__ __device__ double multScatt(const double &length, const double bField, const double radius, int layer, double slope)
Computes the Coulomb multiple scattering variance of the planar angle.
Definition: BrokenLine.h:54
Eigen::Matrix< double, N, 1 > VectorNd
Definition: FitUtils.h:37
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double bField
Definition: BrokenLine.h:158
T sqrt(T t)
Definition: SSEVec.h:23
Eigen::Matrix2d Matrix2d
Definition: FitResult.h:14
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
__host__ __device__ riemannFit::Matrix2d rotationMatrix(double slope)
Computes the 2D rotation matrix that transforms the line y=slope*x into the line y=0.
Definition: BrokenLine.h:78
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
__host__ __device__ riemannFit::MatrixNd< n > matrixC_u(const riemannFit::VectorNd< n > &weights, const riemannFit::VectorNd< n > &sTotal, const riemannFit::VectorNd< n > &varBeta)
Computes the n-by-n band matrix obtained minimizing the Broken Line&#39;s cost function w...
Definition: BrokenLine.h:216
Eigen::Matrix< double, N+1, N+1 > MatrixNplusONEd
Definition: FitUtils.h:21
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648

◆ fastFit()

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

A very fast helix fit.

Parameters
hitsthe measured hits.
Returns
(X0,Y0,R,tan(theta)).
Warning
sign of theta is (intentionally, for now) mistaken for negative charges.

Definition at line 259 of file BrokenLine.h.

References a, funct::abs(), Matriplex::atan2(), b, DummyCfis::c, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), riemannFit::cross2D(), ztail::d, d1, MillePedeFileConverter_cfg::e, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::hits, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::mId, create_idmaps::n, mps_fire::result, mathSSE::sqrt(), and createJobs::tmp.

Referenced by for(), and helixFit().

259  {
260  constexpr uint32_t n = M3xN::ColsAtCompileTime;
261 
262  int mId = 1;
263 
264  if constexpr (n > 3) {
265  riemannFit::Vector2d middle = 0.5 * (hits.block(0, n - 1, 2, 1) + hits.block(0, 0, 2, 1));
266  auto d1 = (hits.block(0, n / 2, 2, 1) - middle).squaredNorm();
267  auto d2 = (hits.block(0, n / 2 - 1, 2, 1) - middle).squaredNorm();
268  mId = d1 < d2 ? n / 2 : n / 2 - 1;
269  }
270 
271  const riemannFit::Vector2d a = hits.block(0, mId, 2, 1) - hits.block(0, 0, 2, 1);
272  const riemannFit::Vector2d b = hits.block(0, n - 1, 2, 1) - hits.block(0, mId, 2, 1);
273  const riemannFit::Vector2d c = hits.block(0, 0, 2, 1) - hits.block(0, n - 1, 2, 1);
274 
275  auto tmp = 0.5 / riemannFit::cross2D(c, a);
276  result(0) = hits(0, 0) - (a(1) * c.squaredNorm() + c(1) * a.squaredNorm()) * tmp;
277  result(1) = hits(1, 0) + (a(0) * c.squaredNorm() + c(0) * a.squaredNorm()) * tmp;
278  // check Wikipedia for these formulas
279 
280  result(2) = sqrt(a.squaredNorm() * b.squaredNorm() * c.squaredNorm()) / (2. * std::abs(riemannFit::cross2D(b, a)));
281  // Using Math Olympiad's formula R=abc/(4A)
282 
283  const riemannFit::Vector2d d = hits.block(0, 0, 2, 1) - result.head(2);
284  const riemannFit::Vector2d e = hits.block(0, n - 1, 2, 1) - result.head(2);
285 
286  result(3) = result(2) * atan2(riemannFit::cross2D(d, e), d.dot(e)) / (hits(2, n - 1) - hits(2, 0));
287  // ds/dz slope between last and first point
288  }
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN & hits
Definition: BrokenLine.h:158
__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 sqrt(T t)
Definition: SSEVec.h:23
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
d
Definition: ztail.py:151
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
static constexpr float d1
tmp
align.sh
Definition: createJobs.py:716
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648

◆ helixFit()

template<int n>
riemannFit::HelixFit brokenline::helixFit ( const riemannFit::Matrix3xNd< n > &  hits,
const Eigen::Matrix< float, 6, 4 > &  hits_ge,
const double  bField 
)
inline

Helix fit by three step: -fast pre-fit (see Fast_fit() for further info);
-circle fit of the hits projected in the transverse plane by Broken Line algorithm (see BL_Circle_fit() for further info);
-line fit of the hits projected on the (pre-fitted) cilinder surface by Broken Line algorithm (see BL_Line_fit() for further info);
Points must be passed ordered (from inner to outer layer).

Parameters
hitsMatrix3xNd hits coordinates in this form:
|x1|x2|x3|...|xn|
|y1|y2|y3|...|yn|
|z1|z2|z3|...|zn|
hits_covMatrix3Nd covariance matrix in this form (()->cov()):
|(x1,x1)|(x2,x1)|(x3,x1)|(x4,x1)|.|(y1,x1)|(y2,x1)|(y3,x1)|(y4,x1)|.|(z1,x1)|(z2,x1)|(z3,x1)|(z4,x1)|
|(x1,x2)|(x2,x2)|(x3,x2)|(x4,x2)|.|(y1,x2)|(y2,x2)|(y3,x2)|(y4,x2)|.|(z1,x2)|(z2,x2)|(z3,x2)|(z4,x2)|
|(x1,x3)|(x2,x3)|(x3,x3)|(x4,x3)|.|(y1,x3)|(y2,x3)|(y3,x3)|(y4,x3)|.|(z1,x3)|(z2,x3)|(z3,x3)|(z4,x3)|
|(x1,x4)|(x2,x4)|(x3,x4)|(x4,x4)|.|(y1,x4)|(y2,x4)|(y3,x4)|(y4,x4)|.|(z1,x4)|(z2,x4)|(z3,x4)|(z4,x4)|
. . . . . . . . . . . . . . .
|(x1,y1)|(x2,y1)|(x3,y1)|(x4,y1)|.|(y1,y1)|(y2,y1)|(y3,x1)|(y4,y1)|.|(z1,y1)|(z2,y1)|(z3,y1)|(z4,y1)|
|(x1,y2)|(x2,y2)|(x3,y2)|(x4,y2)|.|(y1,y2)|(y2,y2)|(y3,x2)|(y4,y2)|.|(z1,y2)|(z2,y2)|(z3,y2)|(z4,y2)|
|(x1,y3)|(x2,y3)|(x3,y3)|(x4,y3)|.|(y1,y3)|(y2,y3)|(y3,x3)|(y4,y3)|.|(z1,y3)|(z2,y3)|(z3,y3)|(z4,y3)|
|(x1,y4)|(x2,y4)|(x3,y4)|(x4,y4)|.|(y1,y4)|(y2,y4)|(y3,x4)|(y4,y4)|.|(z1,y4)|(z2,y4)|(z3,y4)|(z4,y4)|
. . . . . . . . . . . . . . .
|(x1,z1)|(x2,z1)|(x3,z1)|(x4,z1)|.|(y1,z1)|(y2,z1)|(y3,z1)|(y4,z1)|.|(z1,z1)|(z2,z1)|(z3,z1)|(z4,z1)|
|(x1,z2)|(x2,z2)|(x3,z2)|(x4,z2)|.|(y1,z2)|(y2,z2)|(y3,z2)|(y4,z2)|.|(z1,z2)|(z2,z2)|(z3,z2)|(z4,z2)|
|(x1,z3)|(x2,z3)|(x3,z3)|(x4,z3)|.|(y1,z3)|(y2,z3)|(y3,z3)|(y4,z3)|.|(z1,z3)|(z2,z3)|(z3,z3)|(z4,z3)|
|(x1,z4)|(x2,z4)|(x3,z4)|(x4,z4)|.|(y1,z4)|(y2,z4)|(y3,z4)|(y4,z4)|.|(z1,z4)|(z2,z4)|(z3,z4)|(z4,z4)|
bFieldmagnetic field in the center of the detector in Gev/cm/c, in order to perform the p_t calculation.
Warning
see BL_Circle_fit(), BL_Line_fit() and Fast_fit() warnings.
Returns
(phi,Tip,p_t,cot(theta)),Zip), their covariance matrix and the chi2's of the circle and line fits.

Definition at line 585 of file BrokenLine.h.

References funct::abs(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::bField, riemannFit::CircleFit::chi2, riemannFit::HelixFit::chi2_circle, riemannFit::HelixFit::chi2_line, circleFit(), riemannFit::CircleFit::cov, riemannFit::HelixFit::cov, data, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, fastFit(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::hits, mps_splice::line, lineFit(), riemannFit::CircleFit::par, riemannFit::HelixFit::par, prepareBrokenLineData(), riemannFit::CircleFit::qCharge, riemannFit::HelixFit::qCharge, and riemannFit::sqr().

Referenced by PixelNtupletsFitter::run().

587  {
588  riemannFit::HelixFit helix;
591 
592  PreparedBrokenLineData<n> data;
593  karimaki_circle_fit circle;
595  riemannFit::Matrix3d jacobian;
596 
598  lineFit(hits_ge, fast_fit, bField, data, line);
599  circleFit(hits, hits_ge, fast_fit, bField, data, circle);
600 
601  // the circle fit gives k, but here we want p_t, so let's change the parameter and the covariance matrix
602  jacobian << 1., 0, 0, 0, 1., 0, 0, 0,
603  -std::abs(circle.par(2)) * bField / (riemannFit::sqr(circle.par(2)) * circle.par(2));
604  circle.par(2) = bField / std::abs(circle.par(2));
605  circle.cov = jacobian * circle.cov * jacobian.transpose();
606 
607  helix.par << circle.par, line.par;
608  helix.cov = riemannFit::MatrixXd::Zero(5, 5);
609  helix.cov.block(0, 0, 3, 3) = circle.cov;
610  helix.cov.block(3, 3, 2, 2) = line.cov;
611  helix.qCharge = circle.qCharge;
612  helix.chi2_circle = circle.chi2;
613  helix.chi2_line = line.chi2;
614 
615  return helix;
616  }
__host__ __device__ void lineFit(const M6xN &hits_ge, const V4 &fast_fit, const double bField, const PreparedBrokenLineData< n > &data, riemannFit::LineFit &line_results)
Performs the Broken Line fit in the straight track case (that is, the fit parameters are only the int...
Definition: BrokenLine.h:464
Eigen::Vector4d Vector4d
Definition: FitResult.h:12
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN & hits
Definition: BrokenLine.h:158
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
Vector5d par
(phi,Tip,pt,cotan(theta)),Zip)
Definition: FitResult.h:46
__host__ __device__ void prepareBrokenLineData(const M3xN &hits, const V4 &fast_fit, const double bField, PreparedBrokenLineData< n > &results)
Computes the data needed for the Broken Line fit procedure that are mainly common for the circle and ...
Definition: BrokenLine.h:151
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double bField
Definition: BrokenLine.h:158
int32_t qCharge
particle charge
Definition: FitResult.h:58
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
__host__ __device__ void fastFit(const M3xN &hits, V4 &result)
A very fast helix fit.
Definition: BrokenLine.h:259
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
riemannFit::CircleFit karimaki_circle_fit
< Karimäki&#39;s parameters: (phi, d, k=1/R)
Definition: BrokenLine.h:19
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
__host__ __device__ void circleFit(const M3xN &hits, const M6xN &hits_ge, const V4 &fast_fit, const double bField, PreparedBrokenLineData< n > &data, karimaki_circle_fit &circle_results)
Performs the Broken Line fit in the curved track case (that is, the fit parameters are the intercepti...
Definition: BrokenLine.h:315

◆ lineFit()

template<typename V4 , typename M6xN , int n>
__host__ __device__ void brokenline::lineFit ( const M6xN &  hits_ge,
const V4 &  fast_fit,
const double  bField,
const PreparedBrokenLineData< n > &  data,
riemannFit::LineFit line_results 
)
inline

Performs the Broken Line fit in the straight track case (that is, the fit parameters are only the interceptions u).

Parameters
hitshits coordinates.
fast_fitpre-fit result in the form (X0,Y0,R,tan(theta)).
bFieldmagnetic field in Gev/cm/c.
dataPreparedBrokenLineData.
line_resultsstruct to be filled with the results in this form: -par parameter of the line in this form: (cot(theta), Zip);
-cov covariance matrix of the fitted parameter;
-chi2 value of the cost function in the minimum.

The function implements the steps 2 and 3 of the Broken Line fit without the curvature correction.
The step 2 is the least square fit, done by imposing the minimum constraint on the cost function and solving the consequent linear system. It determines the fitted parameters u and their covariance matrix. The step 3 is the correction of the fast pre-fitted parameters for the innermost part of the track. It is first done in a comfortable coordinate system (the one in which the first hit is the origin) and then the parameters and their covariance matrix are transformed to the original coordinate system.

Definition at line 464 of file BrokenLine.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::bField, riemannFit::LineFit::chi2, gather_cfg::cout, riemannFit::LineFit::cov, data, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, mps_fire::i, l1tstage2_dqm_sourceclient-live_cfg::invert, matrixC_u(), multScatt(), create_idmaps::n, riemannFit::LineFit::par, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::radii, rotationMatrix(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::rotMat, slope, riemannFit::sqr(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::sTotal, createJobs::tmp, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::varBeta(), w(), hltDeepSecondaryVertexTagInfosPFPuppi_cfi::weights, and ALPAKA_ACCELERATOR_NAMESPACE::brokenline::zInSZplane.

Referenced by helixFit().

468  {
469  const auto& radii = data.radii;
470  const auto& sTotal = data.sTotal;
471  const auto& zInSZplane = data.zInSZplane;
472  const auto& varBeta = data.varBeta;
473 
474  const double slope = -data.qCharge / fast_fit(3);
476 
477  riemannFit::Matrix3d vMat = riemannFit::Matrix3d::Zero(); // covariance matrix XYZ
478  riemannFit::Matrix2x3d jacobXYZtosZ =
479  riemannFit::Matrix2x3d::Zero(); // jacobian for computation of the error on s (xyz -> sz)
481  for (u_int i = 0; i < n; i++) {
482  vMat(0, 0) = hits_ge.col(i)[0]; // x errors
483  vMat(0, 1) = vMat(1, 0) = hits_ge.col(i)[1]; // cov_xy
484  vMat(0, 2) = vMat(2, 0) = hits_ge.col(i)[3]; // cov_xz
485  vMat(1, 1) = hits_ge.col(i)[2]; // y errors
486  vMat(2, 1) = vMat(1, 2) = hits_ge.col(i)[4]; // cov_yz
487  vMat(2, 2) = hits_ge.col(i)[5]; // z errors
488  auto tmp = 1. / radii.block(0, i, 2, 1).norm();
489  jacobXYZtosZ(0, 0) = radii(1, i) * tmp;
490  jacobXYZtosZ(0, 1) = -radii(0, i) * tmp;
491  jacobXYZtosZ(1, 2) = 1.;
492  weights(i) = 1. / ((rotMat * jacobXYZtosZ * vMat * jacobXYZtosZ.transpose() * rotMat.transpose())(
493  1, 1)); // compute the orthogonal weight point by point
494  }
495 
497  for (u_int i = 0; i < n; i++) {
498  r_u(i) = weights(i) * zInSZplane(i);
499  }
500 #ifdef CPP_DUMP
501  std::cout << "CU4\n" << matrixC_u(w, sTotal, varBeta) << std::endl;
502 #endif
505 #ifdef CPP_DUMP
506  std::cout << "I4\n" << iMat << std::endl;
507 #endif
508 
509  riemannFit::VectorNd<n> uVec = iMat * r_u; // obtain the fitted parameters by solving the linear system
510 
511  // line parameters in the system in which the first hit is the origin and with axis along SZ
512  line_results.par << (uVec(1) - uVec(0)) / (sTotal(1) - sTotal(0)), uVec(0);
513  auto idiff = 1. / (sTotal(1) - sTotal(0));
514  line_results.cov << (iMat(0, 0) - 2 * iMat(0, 1) + iMat(1, 1)) * riemannFit::sqr(idiff) +
515  multScatt(sTotal(1) - sTotal(0), bField, fast_fit(2), 2, slope),
516  (iMat(0, 1) - iMat(0, 0)) * idiff, (iMat(0, 1) - iMat(0, 0)) * idiff, iMat(0, 0);
517 
518  // translate to the original SZ system
519  riemannFit::Matrix2d jacobian;
520  jacobian(0, 0) = 1.;
521  jacobian(0, 1) = 0;
522  jacobian(1, 0) = -sTotal(0);
523  jacobian(1, 1) = 1.;
524  line_results.par(1) += -line_results.par(0) * sTotal(0);
525  line_results.cov = jacobian * line_results.cov * jacobian.transpose();
526 
527  // rotate to the original sz system
528  auto tmp = rotMat(0, 0) - line_results.par(0) * rotMat(0, 1);
529  jacobian(1, 1) = 1. / tmp;
530  jacobian(0, 0) = jacobian(1, 1) * jacobian(1, 1);
531  jacobian(0, 1) = 0;
532  jacobian(1, 0) = line_results.par(1) * rotMat(0, 1) * jacobian(0, 0);
533  line_results.par(1) = line_results.par(1) * jacobian(1, 1);
534  line_results.par(0) = (rotMat(0, 1) + line_results.par(0) * rotMat(0, 0)) * jacobian(1, 1);
535  line_results.cov = jacobian * line_results.cov * jacobian.transpose();
536 
537  // compute chi2
538  line_results.chi2 = 0;
539  for (u_int i = 0; i < n; i++) {
540  line_results.chi2 += weights(i) * riemannFit::sqr(zInSZplane(i) - uVec(i));
541  if (i > 0 && i < n - 1)
542  line_results.chi2 += riemannFit::sqr(uVec(i - 1) / (sTotal(i) - sTotal(i - 1)) -
543  uVec(i) * (sTotal(i + 1) - sTotal(i - 1)) /
544  ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))) +
545  uVec(i + 1) / (sTotal(i + 1) - sTotal(i))) /
546  varBeta(i);
547  }
548  }
Eigen::Matrix3d Matrix3d
Definition: FitResult.h:15
T w() const
Eigen::Matrix< double, 2, 3 > Matrix2x3d
Definition: FitUtils.h:49
static const double slope[3]
__host__ __device__ double multScatt(const double &length, const double bField, const double radius, int layer, double slope)
Computes the Coulomb multiple scattering variance of the planar angle.
Definition: BrokenLine.h:54
Eigen::Matrix< double, N, 1 > VectorNd
Definition: FitUtils.h:37
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double bField
Definition: BrokenLine.h:158
Eigen::Matrix2d Matrix2d
Definition: FitResult.h:14
Eigen::Matrix< double, N, N > MatrixNd
Definition: FitUtils.h:19
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 & fast_fit
Definition: BrokenLine.h:158
__host__ __device__ riemannFit::Matrix2d rotationMatrix(double slope)
Computes the 2D rotation matrix that transforms the line y=slope*x into the line y=0.
Definition: BrokenLine.h:78
__host__ __device__ riemannFit::MatrixNd< n > matrixC_u(const riemannFit::VectorNd< n > &weights, const riemannFit::VectorNd< n > &sTotal, const riemannFit::VectorNd< n > &varBeta)
Computes the n-by-n band matrix obtained minimizing the Broken Line&#39;s cost function w...
Definition: BrokenLine.h:216
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
Vector2d par
(cotan(theta),Zip)
Definition: FitResult.h:36
tmp
align.sh
Definition: createJobs.py:716

◆ matrixC_u()

template<int n>
__host__ __device__ riemannFit::MatrixNd<n> brokenline::matrixC_u ( const riemannFit::VectorNd< n > &  weights,
const riemannFit::VectorNd< n > &  sTotal,
const riemannFit::VectorNd< n > &  varBeta 
)
inline

Computes the n-by-n band matrix obtained minimizing the Broken Line's cost function w.r.t u. This is the whole matrix in the case of the line fit and the main n-by-n block in the case of the circle fit.

Parameters
weightsweights of the first part of the cost function, the one with the measurements and not the angles ({i=1}^n w*(y_i-u_i)^2).
sTotaltotal distance traveled by the particle from the pre-fitted closest approach.
varBetakink angles' variance.
Returns
the n-by-n matrix of the linear system

Definition at line 216 of file BrokenLine.h.

References mps_fire::i, create_idmaps::n, riemannFit::sqr(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::sTotal, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::varBeta(), and hltDeepSecondaryVertexTagInfosPFPuppi_cfi::weights.

Referenced by circleFit(), and lineFit().

218  {
220  for (u_int i = 0; i < n; i++) {
221  c_uMat(i, i) = weights(i);
222  if (i > 1)
223  c_uMat(i, i) += 1. / (varBeta(i - 1) * riemannFit::sqr(sTotal(i) - sTotal(i - 1)));
224  if (i > 0 && i < n - 1)
225  c_uMat(i, i) +=
226  (1. / varBeta(i)) * riemannFit::sqr((sTotal(i + 1) - sTotal(i - 1)) /
227  ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))));
228  if (i < n - 2)
229  c_uMat(i, i) += 1. / (varBeta(i + 1) * riemannFit::sqr(sTotal(i + 1) - sTotal(i)));
230 
231  if (i > 0 && i < n - 1)
232  c_uMat(i, i + 1) =
233  1. / (varBeta(i) * (sTotal(i + 1) - sTotal(i))) *
234  (-(sTotal(i + 1) - sTotal(i - 1)) / ((sTotal(i + 1) - sTotal(i)) * (sTotal(i) - sTotal(i - 1))));
235  if (i < n - 2)
236  c_uMat(i, i + 1) +=
237  1. / (varBeta(i + 1) * (sTotal(i + 1) - sTotal(i))) *
238  (-(sTotal(i + 2) - sTotal(i)) / ((sTotal(i + 2) - sTotal(i + 1)) * (sTotal(i + 1) - sTotal(i))));
239 
240  if (i < n - 2)
241  c_uMat(i, i + 2) = 1. / (varBeta(i + 1) * (sTotal(i + 2) - sTotal(i + 1)) * (sTotal(i + 1) - sTotal(i)));
242 
243  c_uMat(i, i) *= 0.5;
244  }
245  return c_uMat + c_uMat.transpose();
246  }
Eigen::Matrix< double, N, N > MatrixNd
Definition: FitUtils.h:19
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67

◆ multScatt()

__host__ __device__ double brokenline::multScatt ( const double &  length,
const double  bField,
const double  radius,
int  layer,
double  slope 
)
inline

Computes the Coulomb multiple scattering variance of the planar angle.

Parameters
lengthlength of the track in the material.
bFieldmagnetic field in Gev/cm/c.
radiusradius of curvature (needed to evaluate p).
layerdenotes which of the four layers of the detector is the endpoint of the multiple scattered track. For example, if Layer=3, then the particle has just gone through the material between the second and the third layer.
Warning
the formula used here assumes beta=1, and so neglects the dependence of theta_0 on the mass of the particle at fixed momentum.
Returns
the variance of the planar angle ((theta_0)^2 /3).

< inverse of radiation length of the material in cm

number between 1/3 (uniform material) and 1 (thin scatterer) to be manually tuned

Definition at line 54 of file BrokenLine.h.

References funct::abs(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::bField, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), fact, CrabHelper::log, SiStripPI::min, HLT_2024v14_cff::pt2, CosmicsPD_Skims::radius, slope, and riemannFit::sqr().

Referenced by circleFit(), lineFit(), and prepareBrokenLineData().

55  {
56  // limit R to 20GeV...
57  auto pt2 = std::min(20., bField * radius);
58  pt2 *= pt2;
59  constexpr double inv_X0 = 0.06 / 16.;
60  //if(Layer==1) XXI_0=0.06/16.;
61  // else XXI_0=0.06/16.;
62  //XX_0*=1;
63 
65  constexpr double geometry_factor = 0.7;
66  constexpr double fact = geometry_factor * riemannFit::sqr(13.6 / 1000.);
67  return fact / (pt2 * (1. + riemannFit::sqr(slope))) * (std::abs(length) * inv_X0) *
68  riemannFit::sqr(1. + 0.038 * log(std::abs(length) * inv_X0));
69  }
static const double slope[3]
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double bField
Definition: BrokenLine.h:158
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const double fact

◆ prepareBrokenLineData()

template<typename M3xN , typename V4 , int n>
__host__ __device__ void brokenline::prepareBrokenLineData ( const M3xN &  hits,
const V4 &  fast_fit,
const double  bField,
PreparedBrokenLineData< n > &  results 
)
inline

Computes the data needed for the Broken Line fit procedure that are mainly common for the circle and the line fit.

Parameters
hitshits coordinates.
fast_fitpre-fit result in the form (X0,Y0,R,tan(theta)).
bFieldmagnetic field in Gev/cm/c.
resultsPreparedBrokenLineData to be filled (see description of PreparedBrokenLineData).

Definition at line 151 of file BrokenLine.h.

References Matriplex::atan2(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::bField, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), riemannFit::cross2D(), d1, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::dVec, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::eVec, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::fast_fit, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::hits, mps_fire::i, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::mId, multScatt(), create_idmaps::n, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::pointsSZ, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::results, rotationMatrix(), ALPAKA_ACCELERATOR_NAMESPACE::brokenline::rotMat, slope, and ALPAKA_ACCELERATOR_NAMESPACE::brokenline::zVec.

Referenced by helixFit(), ALPAKA_ACCELERATOR_NAMESPACE::Kernel_BLFit< N, TrackerTraits >::operator()(), and ALPAKA_ACCELERATOR_NAMESPACE::brokenline::helixFit< n >::operator()().

154  {
157 
158  int mId = 1;
159 
160  if constexpr (n > 3) {
161  riemannFit::Vector2d middle = 0.5 * (hits.block(0, n - 1, 2, 1) + hits.block(0, 0, 2, 1));
162  auto d1 = (hits.block(0, n / 2, 2, 1) - middle).squaredNorm();
163  auto d2 = (hits.block(0, n / 2 - 1, 2, 1) - middle).squaredNorm();
164  mId = d1 < d2 ? n / 2 : n / 2 - 1;
165  }
166 
167  dVec = hits.block(0, mId, 2, 1) - hits.block(0, 0, 2, 1);
168  eVec = hits.block(0, n - 1, 2, 1) - hits.block(0, mId, 2, 1);
169  results.qCharge = riemannFit::cross2D(dVec, eVec) > 0 ? -1 : 1;
170 
171  const double slope = -results.qCharge / fast_fit(3);
172 
174 
175  // calculate radii and s
176  results.radii = hits.block(0, 0, 2, n) - fast_fit.head(2) * riemannFit::MatrixXd::Constant(1, n, 1);
177  eVec = -fast_fit(2) * fast_fit.head(2) / fast_fit.head(2).norm();
178  for (u_int i = 0; i < n; i++) {
179  dVec = results.radii.block(0, i, 2, 1);
180  results.sTransverse(i) = results.qCharge * fast_fit(2) *
181  atan2(riemannFit::cross2D(dVec, eVec), dVec.dot(eVec)); // calculates the arc length
182  }
183  riemannFit::VectorNd<n> zVec = hits.block(2, 0, 1, n).transpose();
184 
185  //calculate sTotal and zVec
187  for (u_int i = 0; i < n; i++) {
188  pointsSZ(0, i) = results.sTransverse(i);
189  pointsSZ(1, i) = zVec(i);
190  pointsSZ.block(0, i, 2, 1) = rotMat * pointsSZ.block(0, i, 2, 1);
191  }
192  results.sTotal = pointsSZ.block(0, 0, 1, n).transpose();
193  results.zInSZplane = pointsSZ.block(1, 0, 1, n).transpose();
194 
195  //calculate varBeta
196  results.varBeta(0) = results.varBeta(n - 1) = 0;
197  for (u_int i = 1; i < n - 1; i++) {
198  results.varBeta(i) = multScatt(results.sTotal(i + 1) - results.sTotal(i), bField, fast_fit(2), i + 2, slope) +
199  multScatt(results.sTotal(i) - results.sTotal(i - 1), bField, fast_fit(2), i + 1, slope);
200  }
201  }
riemannFit::VectorNd< n > zVec
Definition: BrokenLine.h:188
Eigen::Matrix< double, 2, N > Matrix2xNd
Definition: FitUtils.h:29
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN & hits
Definition: BrokenLine.h:158
static const double slope[3]
__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
__host__ __device__ double multScatt(const double &length, const double bField, const double radius, int layer, double slope)
Computes the Coulomb multiple scattering variance of the planar angle.
Definition: BrokenLine.h:54
Eigen::Matrix< double, N, 1 > VectorNd
Definition: FitUtils.h:37
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double bField
Definition: BrokenLine.h:158
Eigen::Matrix2d Matrix2d
Definition: FitResult.h:14
ALPAKA_FN_ACC ALPAKA_FN_INLINE void const M3xN const V4 const double PreparedBrokenLineData< n > & results
Definition: BrokenLine.h:158
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__ riemannFit::Matrix2d rotationMatrix(double slope)
Computes the 2D rotation matrix that transforms the line y=slope*x into the line y=0.
Definition: BrokenLine.h:78
riemannFit::Matrix2xNd< n > pointsSZ
Definition: BrokenLine.h:191
Eigen::Vector2d Vector2d
Definition: FitResult.h:10
static constexpr float d1
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648

◆ rotationMatrix()

__host__ __device__ riemannFit::Matrix2d brokenline::rotationMatrix ( double  slope)
inline

Computes the 2D rotation matrix that transforms the line y=slope*x into the line y=0.

Parameters
slopetangent of the angle of rotation.
Returns
2D rotation matrix.

Definition at line 78 of file BrokenLine.h.

References makeMuonMisalignmentScenario::rot, slope, riemannFit::sqr(), and mathSSE::sqrt().

Referenced by circleFit(), lineFit(), and prepareBrokenLineData().

78  {
80  rot(0, 0) = 1. / sqrt(1. + riemannFit::sqr(slope));
81  rot(0, 1) = slope * rot(0, 0);
82  rot(1, 0) = -rot(0, 1);
83  rot(1, 1) = rot(0, 0);
84  return rot;
85  }
static const double slope[3]
T sqrt(T t)
Definition: SSEVec.h:23
Eigen::Matrix2d Matrix2d
Definition: FitResult.h:14
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67

◆ translateKarimaki()

__host__ __device__ void brokenline::translateKarimaki ( karimaki_circle_fit circle,
double  x0,
double  y0,
riemannFit::Matrix3d jacobian 
)
inline

Changes the Karimäki parameters (and consequently their covariance matrix) under a translation of the coordinate system, such that the old origin has coordinates (x0,y0) in the new coordinate system. The formulas are taken from Karimäki V., 1990, Effective circle fitting for particle trajectories, Nucl. Instr. and Meth. A305 (1991) 187.

Parameters
circlecircle fit in the old coordinate system. circle.par(0) is phi, circle.par(1) is d and circle.par(2) is rho.
x0x coordinate of the translation vector.
y0y coordinate of the translation vector.
jacobianpassed by reference in order to save stack.

Definition at line 98 of file BrokenLine.h.

References Matriplex::atan2(), funct::cos(), l1tPhase1JetProducer_cfi::cosPhi, riemannFit::CircleFit::cov, amptDefaultParameters_cff::mu, riemannFit::CircleFit::par, funct::sin(), l1tPhase1JetProducer_cfi::sinPhi, riemannFit::sqr(), mathSSE::sqrt(), and protons_cff::xi.

Referenced by circleFit().

101  {
102  // Avoid multiple access to the circle.par vector.
103  using scalar = std::remove_reference<decltype(circle.par(0))>::type;
104  scalar phi = circle.par(0);
105  scalar dee = circle.par(1);
106  scalar rho = circle.par(2);
107 
108  // Avoid repeated trig. computations
109  scalar sinPhi = sin(phi);
110  scalar cosPhi = cos(phi);
111 
112  // Intermediate computations for the circle parameters
113  scalar deltaPara = x0 * cosPhi + y0 * sinPhi;
114  scalar deltaOrth = x0 * sinPhi - y0 * cosPhi + dee;
115  scalar tempSmallU = 1 + rho * dee;
116  scalar tempC = -rho * y0 + tempSmallU * cosPhi;
117  scalar tempB = rho * x0 + tempSmallU * sinPhi;
118  scalar tempA = 2. * deltaOrth + rho * (riemannFit::sqr(deltaOrth) + riemannFit::sqr(deltaPara));
119  scalar tempU = sqrt(1. + rho * tempA);
120 
121  // Intermediate computations for the error matrix transform
122  scalar xi = 1. / (riemannFit::sqr(tempB) + riemannFit::sqr(tempC));
123  scalar tempV = 1. + rho * deltaOrth;
124  scalar lambda = (0.5 * tempA) / (riemannFit::sqr(1. + tempU) * tempU);
125  scalar mu = 1. / (tempU * (1. + tempU)) + rho * lambda;
126  scalar zeta = riemannFit::sqr(deltaOrth) + riemannFit::sqr(deltaPara);
127  jacobian << xi * tempSmallU * tempV, -xi * riemannFit::sqr(rho) * deltaOrth, xi * deltaPara,
128  2. * mu * tempSmallU * deltaPara, 2. * mu * tempV, mu * zeta - lambda * tempA, 0, 0, 1.;
129 
130  // translated circle parameters
131  // phi
132  circle.par(0) = atan2(tempB, tempC);
133  // d
134  circle.par(1) = tempA / (1 + tempU);
135  // rho after translation. It is invariant, so noop
136  // circle.par(2)= rho;
137 
138  // translated error matrix
139  circle.cov = jacobian * circle.cov * jacobian.transpose();
140  }
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T sqrt(T t)
Definition: SSEVec.h:23
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
constexpr T sqr(const T a)
raise to square.
Definition: FitUtils.h:67
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Definition: matutil.cc:166
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648