Skip to content

Commit 9cef6de

Browse files
mcoquet642Maurice Coquet
andauthored
Computation of DCAxyz for forward tracks (#14460)
* Computation of 3D DCA for forward tracks * clang format --------- Co-authored-by: Maurice Coquet <mcoquet@lxplus955.cern.ch>
1 parent 8b07c99 commit 9cef6de

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackFwd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class TrackParCovFwd : public TrackParFwd
161161
void propagateToZquadratic(double zEnd, double zField);
162162
void propagateToZhelix(double zEnd, double zField);
163163
void propagateToZ(double zEnd, double zField); // Parameters: helix; errors: quadratic
164+
void propagateToDCAhelix(double zField, const std::array<double, 3>& p, std::array<double, 3>& dca);
164165

165166
// Add Multiple Coulomb Scattering effects
166167
void addMCSEffect(double x2X0);

DataFormats/Reconstruction/src/TrackFwd.cxx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "ReconstructionDataFormats/TrackFwd.h"
1313
#include "Math/MatrixFunctions.h"
14+
#include <GPUCommonLogger.h>
1415

1516
namespace o2
1617
{
@@ -503,5 +504,73 @@ bool TrackParCovFwd::getCovXYZPxPyPzGlo(std::array<float, 21>& cv) const
503504
return true;
504505
}
505506

507+
//________________________________________________________________
508+
509+
void TrackParCovFwd::propagateToDCAhelix(double zField, const std::array<double, 3>& p, std::array<double, 3>& dca)
510+
{
511+
// Computing DCA of fwd track w.r.t vertex in helix track model, using Newton-Raphson minimization
512+
513+
auto x0 = mParameters(0);
514+
auto y0 = mParameters(1);
515+
auto z0 = mZ;
516+
auto phi0 = mParameters(2);
517+
auto tanl = mParameters(3);
518+
auto qOverPt = mParameters(4);
519+
auto k = TMath::Abs(o2::constants::math::B2C * zField);
520+
auto qpt = 1.0 / qOverPt;
521+
auto qR = qpt / std::fabs(k);
522+
auto invtanl = 1.0 / tanl;
523+
auto Hz = std::copysign(1, zField);
524+
525+
auto xPV = p[0];
526+
auto yPV = p[1];
527+
auto zPV = p[2];
528+
529+
auto qRtanl = qR * tanl;
530+
auto invqRtanl = 1.0 / qRtanl;
531+
auto [sinp, cosp] = o2::math_utils::sincosd(phi0);
532+
533+
auto z = zPV;
534+
double tol = 1e-4;
535+
int max_iter = 10;
536+
int iter = 0;
537+
538+
while (iter++ < max_iter) {
539+
double theta = (z0 - z) * invqRtanl;
540+
double phi_theta = phi0 + Hz * theta;
541+
double sin_phi_theta = sin(phi_theta);
542+
double cos_phi_theta = cos(phi_theta);
543+
544+
double DX = x0 - Hz * qR * (sin_phi_theta - sinp) - xPV;
545+
double DY = y0 + Hz * qR * (cos_phi_theta - cosp) - yPV;
546+
double DZ = z - zPV;
547+
548+
double dD2_dZ =
549+
2 * DX * cos_phi_theta * invtanl +
550+
2 * DY * sin_phi_theta * invtanl +
551+
2 * DZ;
552+
553+
double d2D2_dZ2 =
554+
2 * invtanl * invtanl +
555+
2 * invtanl * (DX * Hz * sin_phi_theta - DY * Hz * cos_phi_theta) * invqRtanl +
556+
2;
557+
558+
double z_new = z - dD2_dZ / d2D2_dZ2;
559+
560+
if (std::abs(z_new - z) < tol) {
561+
z = z_new;
562+
this->propagateToZhelix(z, zField);
563+
dca[0] = this->getX() - xPV;
564+
dca[1] = this->getY() - yPV;
565+
dca[2] = this->getZ() - zPV;
566+
LOG(debug) << "Converged after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
567+
return;
568+
}
569+
z = z_new;
570+
}
571+
LOG(debug) << "Failed to converge after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
572+
return;
573+
}
574+
506575
} // namespace track
507576
} // namespace o2

0 commit comments

Comments
 (0)