Belle II Software  release-08-01-10
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 
26 using namespace Belle2;
27 using namespace TrackFindingCDC;
28 
29 double 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 
110 std::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 }
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 perimeterXY() const
Getter for the perimeter of the circle in the xy projection.
Definition: Helix.h:271
double impactXY() const
Getter for the signed distance to the z axes at the perigee point.
Definition: Helix.h:210
const SZLine & szLine() const
Getter for the projection into xy space.
Definition: Helix.h:326
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 zPeriod() const
Getter for the distance in z at which the two points on the helix coincide in the xy projection.
Definition: Helix.h:259
double d0() const
Getter for the signed distance to the z axes at the perigee point.
Definition: Helix.h:222
Vector3D atArcLength2D(double s) const
Calculates the point, which lies at the give perpendicular travel distance (counted from the perigee)
Definition: Helix.h:174
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
const PerigeeCircle & circleXY() const
Getter for the projection into xy space.
Definition: Helix.h:320
double distance(const Vector2D &point) const
Getter for the proper signed distance of the point to the circle.
PerigeeJacobian passiveMoveByJacobian(const Vector2D &by) const
Computes the Jacobi matrix for a move of the coordinate system by the given vector.
double arcLengthTo(const Vector2D &point) const
Calculates the arc length between the perigee and the given point.
A matrix implementation to be used as an interface typ through out the track finder.
Definition: PlainMatrix.h:40
double map(double s) const
Maps the two dimensional arc length s to z.
Definition: SZLine.h:116
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
std::ostream & operator<<(std::ostream &output, const Helix &helix)
Output operator for debugging and the generation of unittest error messages.
Definition: Helix.cc:631
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.