Belle II Software development
HelixSwimmer.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
9#include <top/reconstruction_cpp/HelixSwimmer.h>
10#include <framework/gearbox/Const.h>
11#include <framework/gearbox/Unit.h>
12#include <framework/logging/Logger.h>
13#include <limits>
14#include <cmath>
15
16using namespace std;
17using namespace ROOT::Math;
18
19namespace Belle2 {
24 namespace TOP {
25
26 void HelixSwimmer::set(const XYZPoint& position, const XYZVector& momentum, double charge, double Bz)
27 {
28 double p = momentum.R();
29 double pT = momentum.Rho();
30 double b = -Bz * charge * Const::speedOfLight;
31 if (std::abs(b / Unit::T) > pT) { // helix for R < 100 m
32 m_R = pT / std::abs(b);
33 m_omega = b / p;
34 m_kz = momentum.Z() / p;
35 m_phi0 = momentum.Phi() - copysign(M_PI / 2, m_omega);
36 m_xc = position.X() - m_R * cos(m_phi0);
37 m_yc = position.Y() - m_R * sin(m_phi0);
38 m_z0 = position.Z();
39 m_T0 = 2 * M_PI / std::abs(m_omega);
40 } else { // straight line
41 m_omega = 0; // distinguisher between straight line and helix
42 x0 = position.X();
43 y0 = position.Y();
44 z0 = position.Z();
45 kx = momentum.X() / p;
46 ky = momentum.Y() / p;
47 kz = momentum.Z() / p;
48 }
49 }
50
52 {
53 if (m_omega != 0) {
54 m_phi0 += m_omega * length;
55 m_z0 += m_kz * length;
56 } else {
57 x0 += kx * length;
58 y0 += ky * length;
59 z0 += kz * length;
60 }
61 }
62
63 XYZPoint HelixSwimmer::getPosition(double length) const
64 {
65 if (m_omega != 0) {
66 double phi = m_phi0 + m_omega * length;
67 XYZPoint vec(m_xc + m_R * cos(phi), m_yc + m_R * sin(phi), m_z0 + m_kz * length);
68 return m_transformInv * vec;
69 } else {
70 XYZPoint vec(x0 + kx * length, y0 + ky * length, z0 + kz * length);
71 return m_transformInv * vec;
72 }
73 }
74
75 XYZVector HelixSwimmer::getDirection(double length) const
76 {
77 if (m_omega != 0) {
78 double phi = m_phi0 + m_omega * length;
79 double k_T = m_omega * m_R;
80 XYZVector vec(-k_T * sin(phi), k_T * cos(phi), m_kz);
81 return m_transformInv * vec;
82 } else {
83 XYZVector vec(kx, ky, kz);
84 return m_transformInv * vec;
85 }
86 }
87
88 double HelixSwimmer::getDistanceToPlane(const XYZPoint& point, const XYZVector& normal) const
89 {
90 if (m_omega != 0) {
91 auto r = point - XYZPoint(m_xc, m_yc, m_z0);
92 double phi = normal.Phi();
93 double s = r.Dot(normal);
94 if (std::abs(s) > m_R) return std::numeric_limits<double>::quiet_NaN(); // no solution
95
96 double t = shortestDistance(s / m_R, phi);
97 double v = m_kz * normal.Z();
98 if (v == 0) return t;
99
100 double t_prev = t;
101 double dt_prev = 0;
102 for (int i = 0; i < 100; i++) {
103 double cosAlpha = (s - v * t) / m_R;
104 if (std::abs(cosAlpha) > 1) {
105 return std::numeric_limits<double>::quiet_NaN(); // no solution
106 }
107 t = shortestDistance(cosAlpha, phi);
108 double dt = t - t_prev;
109 if (dt == 0 or (dt + dt_prev) == 0) return t;
110 t_prev = t;
111 dt_prev = dt;
112 }
113 if (std::abs(dt_prev) < 1e-6) {
114 B2DEBUG(20, "TOP::HelixSwimmer::getDistanceToPlane: not converged"
115 << LogVar("v", v) << LogVar("dt", dt_prev));
116 return t;
117 } else {
118 B2DEBUG(20, "TOP::HelixSwimmer::getDistanceToPlane: not converged"
119 << LogVar("v", v) << LogVar("dt", dt_prev));
120 return std::numeric_limits<double>::quiet_NaN();
121 }
122 } else {
123 auto r = point - XYZPoint(x0, y0, z0);
124 auto v = XYZVector(kx, ky, kz);
125 return r.Dot(normal) / v.Dot(normal);
126 }
127 }
128
129 } //TOP
131} //Belle2
132
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
double m_phi0
phi of reference position
Definition: HelixSwimmer.h:105
void moveReferencePosition(double length)
Moves reference position along helix by length.
Definition: HelixSwimmer.cc:51
double & kx
direction in x for zero magnetic field
Definition: HelixSwimmer.h:112
ROOT::Math::XYZPoint getPosition(double length) const
Returns particle position at given length.
Definition: HelixSwimmer.cc:63
ROOT::Math::Transform3D m_transformInv
transformation from nominal to local frame
Definition: HelixSwimmer.h:116
double getDistanceToPlane(const ROOT::Math::XYZPoint &point, const ROOT::Math::XYZVector &normal) const
Returns the distance along helix to the nearest intersection with the plane nearly parallel to z axis...
Definition: HelixSwimmer.cc:88
double & ky
direction in y for zero magnetic field
Definition: HelixSwimmer.h:113
double & z0
z of reference position for zero magnetic field
Definition: HelixSwimmer.h:111
double & kz
direction in z for zero magnetic field
Definition: HelixSwimmer.h:114
double & y0
y of reference position for zero magnetic field
Definition: HelixSwimmer.h:110
double shortestDistance(double cosAlpha, double phi) const
Returns shortest distance.
Definition: HelixSwimmer.h:121
double m_R
helix radius
Definition: HelixSwimmer.h:100
ROOT::Math::XYZVector getDirection(double length) const
Returns particle direction at given length.
Definition: HelixSwimmer.cc:75
double m_yc
helix axis position in y
Definition: HelixSwimmer.h:102
double m_omega
angular speed [1/cm]
Definition: HelixSwimmer.h:103
double m_T0
helix length of single turn
Definition: HelixSwimmer.h:107
double m_z0
z of reference position
Definition: HelixSwimmer.h:106
double m_xc
helix axis position in x
Definition: HelixSwimmer.h:101
void set(const ROOT::Math::XYZPoint &position, const ROOT::Math::XYZVector &momentum, double charge, double Bz)
Sets the helix.
Definition: HelixSwimmer.cc:26
double & x0
x of reference position for zero magnetic field
Definition: HelixSwimmer.h:109
double m_kz
slope in z
Definition: HelixSwimmer.h:104
static const double T
[tesla]
Definition: Unit.h:120
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.
STL namespace.