Belle II Software  release-08-01-10
PerigeeCircle.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/PerigeeCircle.h>
9 
10 #include <tracking/trackFindingCDC/geometry/PerigeeParameters.h>
11 
12 #include <tracking/trackFindingCDC/geometry/Circle2D.h>
13 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
14 
15 #include <tracking/trackFindingCDC/numerics/EForwardBackward.h>
16 #include <tracking/trackFindingCDC/numerics/ERotation.h>
17 #include <tracking/trackFindingCDC/numerics/Quadratic.h>
18 #include <tracking/trackFindingCDC/numerics/SpecialFunctions.h>
19 #include <tracking/trackFindingCDC/numerics/Angle.h>
20 
21 #include <ostream>
22 #include <utility>
23 #include <cmath>
24 
25 namespace Belle2 {
30  namespace TrackFindingCDC {
31  class GeneralizedCircle;
32  class Line2D;
33  }
35 }
36 
37 using namespace Belle2;
38 using namespace TrackFindingCDC;
39 
40 
41 
43 {
44  invalidate();
45 }
46 
47 PerigeeCircle::PerigeeCircle(double curvature, const Vector2D& phi0Vec, double impact)
48  : m_curvature(curvature)
49  , m_phi0(phi0Vec.phi())
50  , m_phi0Vec(phi0Vec)
51  , m_impact(impact)
52 {
53 }
54 
55 PerigeeCircle::PerigeeCircle(double curvature, double phi0, double impact)
56  : m_curvature(curvature)
57  , m_phi0(phi0)
58  , m_phi0Vec(Vector2D::Phi(phi0))
59  , m_impact(impact)
60 {
61 }
62 
64  : PerigeeCircle(perigeeParameters(EPerigeeParameter::c_Curv),
65  perigeeParameters(EPerigeeParameter::c_Phi0),
66  perigeeParameters(EPerigeeParameter::c_I))
67 {
68 }
69 
70 PerigeeCircle::PerigeeCircle(double curvature, double phi0, const Vector2D& phi0Vec, double impact)
71  : m_curvature(curvature)
72  , m_phi0(phi0)
73  , m_phi0Vec(phi0Vec)
74  , m_impact(impact)
75 {
77 }
78 
80 {
81  setN(n012);
82 }
83 
85 {
86  setN(n0123);
87 }
88 
90 {
91  setCenterAndRadius(circle.center(), circle.absRadius(), circle.orientation());
92 }
93 
94 PerigeeCircle PerigeeCircle::fromN(double n0, double n1, double n2, double n3)
95 {
96  PerigeeCircle circle;
97  circle.setN(n0, n1, n2, n3);
98  return circle;
99 }
100 
101 PerigeeCircle PerigeeCircle::fromN(double n0, const Vector2D& n12, double n3)
102 {
103  PerigeeCircle circle;
104  circle.setN(n0, n12, n3);
105  return circle;
106 }
107 
109 PerigeeCircle::fromCenterAndRadius(const Vector2D& center, double absRadius, ERotation orientation)
110 {
111  PerigeeCircle circle;
113  return circle;
114 }
115 
116 Vector2D PerigeeCircle::atArcLength(double arcLength) const
117 {
118  double chi = arcLength * curvature();
119  double chiHalf = chi / 2.0;
120 
121  double atX = arcLength * sinc(chi);
122  double atY = arcLength * sinc(chiHalf) * sin(chiHalf) + impact();
123  return Vector2D::compose(phi0Vec(), atX, atY);
124 }
125 
127 {
130  m_phi0Vec.reverse();
131  m_impact = -m_impact;
132 }
133 
135 {
137 }
138 
140 {
141  double denominator = 2 + curvature() * impact();
142  std::swap(m_impact, m_curvature);
143  m_curvature *= denominator;
144  m_impact /= denominator;
145  // Also properly fixing the orientation to the opposite.
146  reverse();
147 }
148 
150 {
151  double denominator = 2 + curvature() * impact();
152  // Properly fixing the orientation to the opposite by the minus signs
153  double newCurvature = -impact() * denominator;
154  double newPhi0 = AngleUtil::reversed(phi0());
155  Vector2D newPhi0Vec = -phi0Vec();
156  double newImpact = -curvature() / denominator;
157  return PerigeeCircle(newCurvature, newPhi0, newPhi0Vec, newImpact);
158 }
159 
161 {
162  m_curvature = 0.0;
163  m_phi0 = NAN;
164  m_phi0Vec = Vector2D(0.0, 0.0);
165  m_impact = 0;
166 }
167 
169 {
170  return (not std::isfinite(phi0()) or not std::isfinite(curvature()) or
171  not std::isfinite(impact()) or phi0Vec().isNull());
172 }
173 
175 {
176  double arcLength = arcLengthTo(by);
177  m_impact = distance(by);
178  m_phi0 = m_phi0 + curvature() * arcLength;
181 }
182 
184 {
186  passiveMoveByJacobian(by, jacobian);
187  return jacobian;
188 }
189 
191 {
192  Vector2D deltaVec = by - perigee();
193  double delta = deltaVec.norm();
194  double deltaParallel = phi0Vec().dot(deltaVec);
195  // double deltaOrthogonal = phi0Vec().cross(deltaVec);
196  // double zeta = deltaVec.normSquared();
197 
198  Vector2D UVec = gradient(by);
199  double U = UVec.norm();
200  double USquared = UVec.normSquared();
201  double UOrthogonal = phi0Vec().cross(UVec);
202  // double UParallel = phi0Vec().dot(UVec);
203 
204  // Vector2D CB = gradient(by).orthogonal();
205  // double U = sqrt(1 + curvature() * A);
206  // double xi = 1.0 / CB.normSquared();
207  // double nu = 1 - curvature() * deltaOrthogonal;
208  // double mu = 1.0 / (U * (U + 1)) + curvature() * lambda;
209  // double mu = 1.0 / U / 2.0;
210  // double nu = -UOrthogonal;
211  // double xi = 1 / USquared;
212 
213  // double halfA = fastDistance(by);
214  // double A = 2 * halfA;
215  // double lambda = halfA / ((1 + U) * (1 + U) * U);
216  double dr = distance(by);
217 
218  // Vector2D uVec = gradient(Vector2D(0.0, 0.0));
219  // double u = uVec.norm();
220  double u = 1 + curvature() * impact(); //= n12().cylindricalR()
221 
222  using namespace NPerigeeParameterIndices;
223  jacobian(c_Curv, c_Curv) = 1;
224  jacobian(c_Curv, c_Phi0) = 0;
225  jacobian(c_Curv, c_I) = 0;
226 
227  jacobian(c_Phi0, c_Curv) = deltaParallel / USquared;
228  jacobian(c_Phi0, c_Phi0) = -u * UOrthogonal / USquared;
229  jacobian(c_Phi0, c_I) = -curvature() * curvature() * deltaParallel / USquared;
230 
231  jacobian(c_I, c_Curv) = (delta - dr) * (delta + dr) / U / 2;
232  jacobian(c_I, c_Phi0) = u * deltaParallel / U;
233  jacobian(c_I, c_I) = -UOrthogonal / U;
234 }
235 
236 double PerigeeCircle::arcLengthTo(const Vector2D& point) const
237 {
238  Vector2D closestToPoint = closest(point);
239  double secantLength = perigee().distance(closestToPoint);
240  double deltaParallel = phi0Vec().dot(point);
241  return copysign(arcLengthAtSecantLength(secantLength), deltaParallel);
242 }
243 
244 double PerigeeCircle::arcLengthBetween(const Vector2D& from, const Vector2D& to) const
245 {
246  EForwardBackward lengthSign = isForwardOrBackwardOf(from, to);
247  if (not NForwardBackward::isValid(lengthSign)) return NAN;
248  // Handling the rare case that from and to correspond to opposing points on the circle
249  if (lengthSign == EForwardBackward::c_Unknown) lengthSign = EForwardBackward::c_Forward;
250  Vector2D closestAtFrom = closest(from);
251  Vector2D closestAtTo = closest(to);
252  double secantLength = closestAtFrom.distance(closestAtTo);
253  return static_cast<double>(lengthSign) * arcLengthAtSecantLength(secantLength);
254 }
255 
256 double PerigeeCircle::arcLengthToCylindricalR(double cylindricalR) const
257 {
258  // Slight trick here
259  // Since the sought point is on the helix we treat it as the perigee
260  // and the origin as the point to extrapolate to.
261  // We know the distance of the origin to the circle, which is just d0
262  // The direct distance from the origin to the imaginary perigee is just the given cylindricalR.
263  return arcLengthAtDeltaLength(cylindricalR, impact());
264 }
265 
266 double PerigeeCircle::arcLengthAtDeltaLength(double delta, double dr) const
267 {
268  const double secantLength = sqrt((delta + dr) * (delta - dr) / (1 + dr * curvature()));
269  const double arcLength = arcLengthAtSecantLength(secantLength);
270  return arcLength;
271 }
272 
273 double PerigeeCircle::arcLengthAtSecantLength(double secantLength) const
274 {
275  double x = secantLength * curvature() / 2.0;
276  double arcLengthFactor = asinc(x);
277  return secantLength * arcLengthFactor;
278 }
279 
280 std::pair<Vector2D, Vector2D> PerigeeCircle::atCylindricalR(const double cylindricalR) const
281 {
282  const double u = (1 + curvature() * impact());
283  const double orthogonal = ((square(impact()) + square(cylindricalR)) * curvature() / 2.0 + impact()) / u;
284  const double parallel = sqrt(square(cylindricalR) - square(orthogonal));
285  Vector2D atCylindricalR1 = Vector2D::compose(phi0Vec(), -parallel, orthogonal);
286  Vector2D atCylindricalR2 = Vector2D::compose(phi0Vec(), parallel, orthogonal);
287  std::pair<Vector2D, Vector2D> result(atCylindricalR1, atCylindricalR2);
288  return result;
289 }
290 
292  const double cylindricalR) const
293 {
294  std::pair<Vector2D, Vector2D> candidatePoints = atCylindricalR(cylindricalR);
295  return chooseNextForwardOf(startPoint, candidatePoints.first, candidatePoints.second);
296 }
297 
299  const Vector2D& end1,
300  const Vector2D& end2) const
301 {
302  double arcLength1 = arcLengthBetween(start, end1);
303  double arcLength2 = arcLengthBetween(start, end2);
304  if (arcLength1 < 0) arcLength1 += arcLengthPeriod();
305  if (arcLength2 < 0) arcLength2 += arcLengthPeriod();
306  if (fmin(arcLength1, arcLength2) == arcLength1) {
307  return end1;
308  } else if (fmin(arcLength1, arcLength2) == arcLength2) {
309  return end2;
310  } else {
311  return Vector2D(NAN, NAN);
312  }
313 }
314 
316 {
317  return point - normal(point) * distance(point);
318 }
319 
321 {
322  double A = 2 * fastDistance;
323  double U = std::sqrt(1 + A * curvature());
324  return A / (1.0 + U);
325 }
326 
327 double PerigeeCircle::fastDistance(const Vector2D& point) const
328 {
329  Vector2D delta = point - perigee();
330  double deltaOrthogonal = phi0Vec().cross(delta);
331  return -deltaOrthogonal + curvature() * delta.normSquared() / 2;
332 }
333 
335  double absRadius,
337 {
338  m_curvature = static_cast<double>(orientation) / std::fabs(absRadius);
341  m_phi0 = m_phi0Vec.phi();
342  m_impact = (center.norm() - std::fabs(absRadius)) * static_cast<double>(orientation);
343 }
344 
345 void PerigeeCircle::setN(double n0, const Vector2D& n12, double n3)
346 {
347  double normalization = sqrt(n12.normSquared() - 4 * n0 * n3);
348  m_curvature = 2 * n3 / normalization;
351  m_phi0 = m_phi0Vec.phi();
352  m_impact = distance(n0 / normalization); // Uses the new curvature
353 }
354 
355 std::ostream& TrackFindingCDC::operator<<(std::ostream& output, const PerigeeCircle& circle)
356 {
357  return output << "PerigeeCircle("
358  << "curvature=" << circle.curvature() << ","
359  << "phi0=" << circle.phi0() << ","
360  << "impact=" << circle.impact() << ")";
361 }
A two dimensional circle in its natural representation using center and radius as parameters.
Definition: Circle2D.h:26
Vector2D center() const
Getter for the central point of the circle.
Definition: Circle2D.h:221
double absRadius() const
Getter for the absolute radius.
Definition: Circle2D.h:209
ERotation orientation() const
Indicates if the circle is to be interpreted counterclockwise or clockwise.
Definition: Circle2D.h:215
A two dimensional normal line.
Definition: Line2D.h:37
Extension of the generalized circle also caching the perigee coordinates.
Definition: PerigeeCircle.h:36
Vector2D atArcLength(double arcLength) const
Calculates the point, which lies at the give perpendicular travel distance (counted from the perigee)
PerigeeCircle reversed() const
Returns a copy of the circle with opposite orientation.
const Vector2D & phi0Vec() const
Getter for the unit vector of the direction of flight at the perigee.
void setCenterAndRadius(const Vector2D &center, double absRadius, ERotation orientation=ERotation::c_CounterClockwise)
Setter for the circle center and radius.
double fastDistance(const Vector2D &point) const
Getter for the linearised distance measure to a point.
double m_phi0
Memory for the azimuth angle of the direction of flight at the perigee.
double n1() const
Getter for the generalised circle parameters n1.
Vector2D perigee() const
Getter for the perigee point.
Vector2D gradient(const Vector2D &point) const
Gradient of the distance field, hence indicates the direction of increasing distance.
Vector2D atCylindricalRForwardOf(const Vector2D &startPoint, double cylindricalR) const
Approach on the circle with the given cylindrical radius that lies in the forward direction of a star...
double phi0() const
Getter for the azimuth angle of the direction of flight at the perigee.
double arcLengthBetween(const Vector2D &from, const Vector2D &to) const
Calculates the arc length between two points of closest approach on the circle.
bool isInvalid() const
Indicates if all circle parameters are zero.
void reverse()
Flips the orientation of the circle in place.
Vector2D normal(const Vector2D &point) const
Unit normal vector from the circle to the given point.
Vector2D chooseNextForwardOf(const Vector2D &start, const Vector2D &end1, const Vector2D &end2) const
Returns the one of two end point which is first reached from the given start if one stricly follows t...
double distance(const Vector2D &point) const
Getter for the proper signed distance of the point to the circle.
void passiveMoveBy(const Vector2D &by)
Moves the coordinates system by the given vector. Updates perigee parameters in place.
EForwardBackward isForwardOrBackwardOf(const Vector2D &from, const Vector2D &to) const
Indicates whether to given point lies in the forward direction from the perigee.
Vector2D n12() const
Getter for the generalised circle parameters n1 and n2.
double impact() const
Getter for the signed distance of the origin to the circle.
Vector2D center() const
Getter for the center of the circle. If it was a line both components will be infinity.
static PerigeeCircle fromCenterAndRadius(const Vector2D &center, double absRadius, ERotation orientation=ERotation::c_CounterClockwise)
Constructor from center, radius and a optional orientation.
double arcLengthAtDeltaLength(double delta, double dr) const
Helper method to calculate the arc length to a point at distance delta to the perigee and dr to circl...
double n3() const
Getter for the generalised circle parameter n3.
void invalidate()
Sets all circle parameters to zero.
void conformalTransform()
Transforms the generalized circle to conformal space inplace.
double m_impact
Memory for the signed impact parameter.
double n2() const
Getter for the generalised circle parameters n2.
PerigeeCircle()
Default constructor for ROOT compatibility.
Vector2D m_phi0Vec
Cached unit direction of flight at the perigee.
double m_curvature
Memory for the signed curvature.
double curvature() const
Getter for the signed curvature.
void setN(double n0, double n1, double n2, double n3=0.0)
Setter for four generalised circle parameters.
double absRadius() const
Gives the signed radius of the circle. If it was a line this will be infinity.
Vector2D closest(const Vector2D &point) const
Calculates the point of closest approach on the circle to the given point.
double arcLengthAtSecantLength(double secantLength) const
Helper method to calculate the arc length between to points on the circle from a given direct secant ...
PerigeeCircle conformalTransformed() const
Returns a copy of the circle in conformal space.
PerigeeJacobian passiveMoveByJacobian(const Vector2D &by) const
Computes the Jacobi matrix for a move of the coordinate system by the given vector.
std::pair< Vector2D, Vector2D > atCylindricalR(double cylindricalR) const
Calculates the two points with the given cylindrical radius on the generalised circle.
double n0() const
Getter for the generalised circle parameter n0.
static PerigeeCircle fromN(double n0, double n1, double n2, double n3=0)
Constructor with the four parameters of the generalized circle.
ERotation orientation() const
Getter for the orientation of the circle.
double arcLengthPeriod() const
Getter for the arc length for a full round of the circle.
double arcLengthTo(const Vector2D &point) const
Calculates the arc length between the perigee and the given point.
double arcLengthToCylindricalR(double cylindricalR) const
Calculates the two dimensional arc length till the cylindrical radius is reached If the radius can no...
A matrix implementation to be used as an interface typ through out the track finder.
Definition: PlainMatrix.h:40
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
double normalize()
Normalizes the vector to unit length.
Definition: Vector2D.h:315
static Vector2D compose(const Vector2D &coordinateVec, const double parallelCoor, const double orthoCoor)
Constructs a vector from a unit coordinate system vector and the coordinates in that system.
Definition: Vector2D.h:83
double dot(const Vector2D &rhs) const
Calculates the two dimensional dot product.
Definition: Vector2D.h:170
double distance(const Vector2D &rhs=Vector2D(0.0, 0.0)) const
Calculates the distance of this point to the rhs.
Definition: Vector2D.h:216
double cross(const Vector2D &rhs) const
Calculated the two dimensional cross product.
Definition: Vector2D.h:175
double phi() const
Gives the azimuth angle being the angle to the x axes ( range -M_PI to M_PI )
Definition: Vector2D.h:581
double normSquared() const
Calculates .
Definition: Vector2D.h:181
Vector2D orthogonal() const
Orthogonal vector to the counterclockwise direction.
Definition: Vector2D.h:301
double first() const
Getter for the first coordinate.
Definition: Vector2D.h:641
Vector2D & reverse()
Reverses the direction of the vector in place.
Definition: Vector2D.h:339
double norm() const
Calculates the length of the vector.
Definition: Vector2D.h:187
static Vector2D Phi(const double phi)
Constucts a unit vector with azimuth angle equal to phi.
Definition: Vector2D.h:71
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.
EForwardBackward
Enumeration to represent the distinct possibilities of the right left passage information.
EPerigeeParameter
Enumeration to address the individual perigee parameters in a vector or matrix.
ERotation
Enumeration to represent the distinct possibilities of the right left passage information.
Definition: ERotation.h:25
ERotation reversed(ERotation eRotation)
Return the reversed rotation. Leaves ERotation::c_Invalid the same.
Definition: ERotation.h:41
Abstract base class for different kinds of events.
static void normalise(double &angle)
Normalise an angle inplace to lie in the range from [-pi, pi].
Definition: Angle.h:41
static double reversed(const double angle)
Get the angle that point in the opposite direction.
Definition: Angle.h:54