Belle II Software development
Helix.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <tracking/trackFindingCDC/geometry/Helix.h>
9
10#include <tracking/trackFindingCDC/geometry/HelixParameters.h>
11#include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
12#include <tracking/trackFindingCDC/geometry/PerigeeParameters.h>
13#include <tracking/trackFindingCDC/geometry/SZLine.h>
14#include <tracking/trackFindingCDC/geometry/SZParameters.h>
15
16#include <tracking/trackFindingCDC/geometry/Vector3D.h>
17
18#include <boost/math/tools/minima.hpp>
19
20#include <utility>
21#include <algorithm>
22#include <limits>
23#include <ostream>
24#include <cstdint>
25
26using namespace Belle2;
27using namespace TrackFindingCDC;
28
29double Helix::arcLength2DToClosest(const Vector3D& point, bool firstPeriod) const
30{
31 // The point may happen to lie in the center of the helix.
32 double d0 = circleXY().distance(point.xy());
33 double denominator = 1 + curvatureXY() * d0;
34 if (denominator == 0) {
35 // When this happens we can optimise the z distance for the closest point
36 double arcLength2D = (point.z() - z0()) / tanLambda();
37 if (not std::isfinite(arcLength2D)) {
38 return 0.0;
39 } else {
40 return arcLength2D;
41 }
42 }
43
44 // First approximation optimising the xy distance.
45 double arcLength2D = circleXY().arcLengthTo(point.xy());
46 // In case the helix is a flat circle with no extend into z this is the actual solution
47 if (tanLambda() == 0) {
48 return arcLength2D;
49 }
50
51 double deltaZ = point.z() - szLine().map(arcLength2D);
52 if (not firstPeriod) {
53 if (fabs(deltaZ) > zPeriod() / 2) {
54 double newDeltaZ = std::remainder(deltaZ, zPeriod());
55 double nPeriodShift = (deltaZ - newDeltaZ) / zPeriod();
56 arcLength2D += nPeriodShift * perimeterXY();
57 deltaZ = newDeltaZ;
58 }
59 }
60
61 using boost::math::tools::brent_find_minima;
62
63 auto distance3D = [this, &point](const double & s) -> double {
64 Vector3D pos = atArcLength2D(s);
65 return pos.distance(point);
66 };
67
68 double searchWidth = std::fmin(perimeterXY(), 2 * deltaZ / tanLambda());
69
70 double lowerS = arcLength2D - searchWidth;
71 double upperS = arcLength2D + searchWidth;
72
73 int bits = std::numeric_limits<double>::digits;
74 boost::uintmax_t nMaxIter = 100;
75
76 std::pair<double, double> sBounds = brent_find_minima(distance3D, lowerS, upperS, bits, nMaxIter);
77
78 // Stopped before iterations were exhausted?
79 // bool converged = nMaxIter > 0;
80
81 double firstDistance = distance3D(sBounds.first);
82 double secondDistance = distance3D(sBounds.second);
83 if (firstDistance < secondDistance) {
84 return sBounds.first;
85 } else {
86 return sBounds.second;
87 }
88}
89
91{
92 // Fills the upper left 3x3 corner.
93 PerigeeJacobian perigeeJacobian = circleXY().passiveMoveByJacobian(by.xy());
94 SZJacobian szJacobian = SZUtil::identity();
95 HelixJacobian jacobian = HelixUtil::stackBlocks(perigeeJacobian, szJacobian);
96
97 double curv = curvatureXY();
98 double tanL = tanLambda();
99 double sArc = circleXY().arcLengthTo(by.xy());
100
101 using namespace NHelixParameterIndices;
102 jacobian(c_Z0, c_Curv) = tanL * (jacobian(c_Phi0, c_Curv) - sArc) / curv;
103 jacobian(c_Z0, c_Phi0) = tanL * (jacobian(c_Phi0, c_Phi0) - 1.) / curv;
104 jacobian(c_Z0, c_I) = tanL * jacobian(c_Phi0, c_I) / curv;
105 jacobian(c_Z0, c_TanL) = sArc;
106
107 return jacobian;
108}
109
110std::ostream& TrackFindingCDC::operator<<(std::ostream& output, const Helix& helix)
111{
112 return output << "Helix("
113 << "curv=" << helix.curvatureXY() << ","
114 << "phi0=" << helix.phi0() << ","
115 << "impact=" << helix.impactXY() << ","
116 << "tanL=" << helix.tanLambda() << ","
117 << "z0=" << helix.z0() << ")";
118}
double curv(void) const
Return curvature of helix.
Definition: Helix.h:420
Extension of the generalized circle also caching the perigee coordinates.
Definition: Helix.h:28
double z0() const
Getter for z coordinate at the perigee point of the helix.
Definition: Helix.h:252
double phi0() const
Getter for the azimuth angle of the direction of flight at the perigee.
Definition: Helix.h:301
double impactXY() const
Getter for the signed distance to the z axes at the perigee point.
Definition: Helix.h:210
double tanLambda() const
Getter for the proportinality factor from arc length in xy space to z.
Definition: Helix.h:240
double curvatureXY() const
Getter for the signed curvature in the xy projection.
Definition: Helix.h:204
double arcLength2DToClosest(const Vector3D &point, bool firstPeriod=true) const
Calculates the perpendicular travel distance at which the helix has the closest approach to the given...
Definition: Helix.cc:29
HelixJacobian passiveMoveByJacobian(const Vector3D &by) const
Computes the Jacobi matrix for a move of the coordinate system by the given vector.
Definition: Helix.cc:90
A matrix implementation to be used as an interface typ through out the track finder.
Definition: PlainMatrix.h:40
A three dimensional vector.
Definition: Vector3D.h:33
const Vector2D & xy() const
Getter for the xy projected vector ( reference ! )
Definition: Vector3D.h:508
double z() const
Getter for the z coordinate.
Definition: Vector3D.h:496
Abstract base class for different kinds of events.
static HelixUtil::CovarianceMatrix stackBlocks(const PerigeeUtil::CovarianceMatrix &perigeeCov, const SZUtil::CovarianceMatrix &szCov)
Combine covariance matrices from the xy space and the sz space in their respective blocks.