CMS 3D CMS Logo

List of all members | Public Member Functions | Private Attributes
fastsim::HelixTrajectory Class Reference

Mathematical representation of a helix. More...

#include <HelixTrajectory.h>

Inheritance diagram for fastsim::HelixTrajectory:
fastsim::Trajectory

Public Member Functions

bool crosses (const BarrelSimplifiedGeometry &layer) const override
 Check if an intersection of the trajectory with a barrel layer exists. More...
 
double getRadParticle (double phi) const
 Return distance of particle from center of the detector if it was at given angle phi of the helix. More...
 
 HelixTrajectory (const Particle &particle, double magneticFieldZ)
 Constructor. More...
 
void move (double deltaTimeC) override
 Move the particle along the helix trajectory for a given time. More...
 
double nextCrossingTimeC (const BarrelSimplifiedGeometry &layer, bool onLayer=false) const override
 Return delta time (t*c) of the next intersection of trajectory and barrel layer. More...
 
- Public Member Functions inherited from fastsim::Trajectory
const math::XYZTLorentzVectorgetMomentum ()
 Simple getter: return momentum of the particle that was used to create trajectory. More...
 
const math::XYZTLorentzVectorgetPosition ()
 Simple getter: return position of the particle that was used to create trajectory. More...
 
double nextCrossingTimeC (const ForwardSimplifiedGeometry &layer, bool onLayer=false) const
 Return delta time (t*c) of the next intersection of trajectory and forward layer. More...
 
double nextCrossingTimeC (const SimplifiedGeometry &layer, bool onLayer=false) const
 Return delta time (t*c) of the next intersection of trajectory and generic layer. More...
 
virtual ~Trajectory ()
 

Private Attributes

const double centerR_
 Distance of the center of the helix from the center of the tracker. More...
 
const double centerX_
 X-coordinate of the center of the helix. More...
 
const double centerY_
 Y-coordinate of the center of the helix. More...
 
const double maxR_
 The maximum distance of the helix from the center of the tracker. More...
 
const double minR_
 The minimal distance of the helix from the center of the tracker. More...
 
const double phi_
 Ranges from 0 to 2PI: 0 corresponds to the positive X direction, phi increases counterclockwise. More...
 
const double phiSpeed_
 The angular speed of the particle on the helix trajectory. More...
 
const double radius_
 The radius of the helix. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from fastsim::Trajectory
static std::unique_ptr< TrajectorycreateTrajectory (const fastsim::Particle &particle, const double magneticFieldZ)
 Calls constructor of derived classes. More...
 
- Protected Member Functions inherited from fastsim::Trajectory
 Trajectory (const fastsim::Particle &particle)
 Constructor of base class. More...
 
- Protected Attributes inherited from fastsim::Trajectory
math::XYZTLorentzVector momentum_
 momentum of the particle that was used to create trajectory More...
 
math::XYZTLorentzVector position_
 position of the particle that was used to create trajectory More...
 

Detailed Description

Mathematical representation of a helix.

Reflects trajectory of a charged particle in a magnetic field. The trajectory is defined by cylindrical coordinates (see definition of variables for more information).

Definition at line 18 of file HelixTrajectory.h.

Constructor & Destructor Documentation

◆ HelixTrajectory()

fastsim::HelixTrajectory::HelixTrajectory ( const Particle particle,
double  magneticFieldZ 
)

Constructor.

The magnetic field is (to good approximation) constant between two tracker layers (and only in Z-direction).

Parameters
particleA (usually charged) particle.
magneticFieldZThe magnetic field.

Definition at line 15 of file HelixTrajectory.cc.

16  : Trajectory(particle)
17  // exact: r = gamma*beta*m_0*c / (q*e*B) = p_T / (q * e * B)
18  // momentum in units of GeV/c: r = p_T * 10^9 / (c * q * B)
19  // in cmssw units: r = p_T / (c * 10^-4 * q * B)
20  ,
21  radius_(
22  std::abs(momentum_.Pt() / (fastsim::Constants::speedOfLight * 1e-4 * particle.charge() * magneticFieldZ))),
23  phi_(std::atan(momentum_.Py() / momentum_.Px()) +
24  (momentum_.Px() * particle.charge() < 0 ? 3. * M_PI / 2. : M_PI / 2.))
25  // maybe consider (for -pi/2<x<pi/2)
26  // cos(atan(x)) = 1 / sqrt(x^2+1)
27  // -> cos(atan(x) + pi/2) = - x / sqrt(x^2+1)
28  // -> cos(atan(x) +3*pi/2) = + x / sqrt(x^2+1)
29  // sin(atan(x)) = x / sqrt(x^2+1)
30  // -> sin(atan(x) + pi/2) = + 1 / sqrt(x^2+1)
31  // -> sin(atan(x) +3*pi/2) = - 1 / sqrt(x^2+1)
32  ,
33  centerX_(position_.X() -
34  radius_ * (momentum_.Py() / momentum_.Px()) /
35  std::sqrt((momentum_.Py() / momentum_.Px()) * (momentum_.Py() / momentum_.Px()) + 1) *
36  (momentum_.Px() * particle.charge() < 0 ? 1. : -1.)),
37  centerY_(position_.Y() -
38  radius_ * 1 / std::sqrt((momentum_.Py() / momentum_.Px()) * (momentum_.Py() / momentum_.Px()) + 1) *
39  (momentum_.Px() * particle.charge() < 0 ? -1. : 1.))
40  //, centerX_(position_.X() - radius_*std::cos(phi_))
41  //, centerY_(position_.Y() - radius_*std::sin(phi_))
42  ,
46  // omega = q * e * B / (gamma * m) = q * e *B / (E / c^2) = q * e * B * c^2 / E
47  // omega: negative for negative q -> seems to be what we want.
48  // energy in units of GeV: omega = q * B * c^2 / (E * 10^9)
49  // in cmssw units: omega[1/ns] = q * B * c^2 * 10^-4 / E
50  ,
53  ;
54 }

Member Function Documentation

◆ crosses()

bool fastsim::HelixTrajectory::crosses ( const BarrelSimplifiedGeometry layer) const
overridevirtual

Check if an intersection of the trajectory with a barrel layer exists.

Parameters
layerA barrel layer.

Implements fastsim::Trajectory.

Definition at line 56 of file HelixTrajectory.cc.

56  {
57  return (minR_ < layer.getRadius() && maxR_ > layer.getRadius());
58 }

References phase1PixelTopology::layer.

◆ getRadParticle()

double fastsim::HelixTrajectory::getRadParticle ( double  phi) const

Return distance of particle from center of the detector if it was at given angle phi of the helix.

Parameters
phiangle of the helix

Definition at line 209 of file HelixTrajectory.cc.

209  {
210  return sqrt((centerX_ + radius_ * std::cos(phi)) * (centerX_ + radius_ * std::cos(phi)) +
211  (centerY_ + radius_ * std::sin(phi)) * (centerY_ + radius_ * std::sin(phi)));
212 }

References funct::cos(), funct::sin(), and mathSSE::sqrt().

◆ move()

void fastsim::HelixTrajectory::move ( double  deltaTimeC)
overridevirtual

Move the particle along the helix trajectory for a given time.

Parameters
deltaTimeCTime in units of t*c..

Implements fastsim::Trajectory.

Definition at line 193 of file HelixTrajectory.cc.

193  {
194  double deltaT = deltaTimeC / fastsim::Constants::speedOfLight;
195  double deltaPhi = phiSpeed_ * deltaT;
198  position_.Z() + momentum_.Z() / momentum_.E() * deltaTimeC,
199  position_.T() + deltaT);
200  // Rotation defined by
201  // x' = x cos θ - y sin θ
202  // y' = x sin θ + y cos θ
205  momentum_.Z(),
206  momentum_.E());
207 }

References funct::cos(), SiPixelRawToDigiRegional_cfi::deltaPhi, funct::sin(), and fastsim::Constants::speedOfLight.

◆ nextCrossingTimeC()

double fastsim::HelixTrajectory::nextCrossingTimeC ( const BarrelSimplifiedGeometry layer,
bool  onLayer = false 
) const
overridevirtual

Return delta time (t*c) of the next intersection of trajectory and barrel layer.

This function solves the quadratic equation (basically intersection of two circles with a given radius) in order to calculate the moment in time when the particle's trajectory intersects with a given barrel layer.

Parameters
layerA barrel layer.
onLayerSpecify if the particle already is on the layer (in that case the second solution has to be picked).
Returns
t*c [ns * cm/ns] of next intersection (-1 if there is none).

Implements fastsim::Trajectory.

Definition at line 60 of file HelixTrajectory.cc.

60  {
61  if (!crosses(layer))
62  return -1;
63 
64  // solve the following equation for sin(phi)
65  // (x^2 + y^2 = R_L^2) (1) the layer
66  // x = x_c + R_H*cos(phi) (2) the helix in the xy plane
67  // y = y_c + R_H*sin(phi) (3) the helix in the xy plane
68  // with
69  // R_L: the radius of the layer
70  // x_c,y_c the center of the helix in xy plane
71  // R_H, the radius of the helix
72  // phi, the phase of the helix
73  //
74  // substitute (2) and (3) in (1)
75  // =>
76  // x_c^2 + 2*x_c*R_H*cos(phi) + R_H^2*cos^2(phi)
77  // + y_c^2 + 2*y_c*R_H*sin(phi) + R_H^2*sin^2(phi)
78  // = R_L^2
79  // =>
80  // (x_c^2 + y_c^2 + R_H^2 - R_L^2) + (2*y_c*R_H)*sin(phi) = -(2*x_c*R_H)*cos(phi)
81  //
82  // rewrite
83  // E + F *sin(phi) = G *cos(phi)
84  // =>
85  // E^2 + 2*E*F*sin(phi) + F^2*sin^2(phi) = G^2*(1-sin^2(phi))
86  // rearrange
87  // sin^2(phi)*(F^2 + G^2) + sin(phi)*(2*E*F) + (E^2 - G^2) = 0
88  //
89  // rewrite
90  // sin^2(phi)* a + sin(phi)* b + c = 0
91  // => sin(phi) = (-b +/- sqrt(b^2 - 4*ac)) / (2*a)
92  // with
93  // a = F^2 + G^2
94  // b = 2*E*F
95  // c = E^2 - G^2
96 
97  double E = centerX_ * centerX_ + centerY_ * centerY_ + radius_ * radius_ - layer.getRadius() * layer.getRadius();
98  double F = 2 * centerY_ * radius_;
99  double G = 2 * centerX_ * radius_;
100 
101  double a = F * F + G * G;
102  double b = 2 * E * F;
103  double c = E * E - G * G;
104 
105  double delta = b * b - 4 * a * c;
106 
107  // case of no solution
108  if (delta < 0) {
109  // Should not be reached: Full Propagation does always have a solution "if(crosses(layer)) == -1"
110  // Even if particle is outside all layers -> can turn around in magnetic field
111  return -1;
112  }
113 
114  // Uses a numerically more stable procedure:
115  // https://people.csail.mit.edu/bkph/articles/Quadratics.pdf
116  double sqrtDelta = sqrt(delta);
117  double phi1 = 0, phi2 = 0;
118  if (b < 0) {
119  phi1 = std::asin((2. * c) / (-b + sqrtDelta));
120  phi2 = std::asin((-b + sqrtDelta) / (2. * a));
121  } else {
122  phi1 = std::asin((-b - sqrtDelta) / (2. * a));
123  phi2 = std::asin((2. * c) / (-b - sqrtDelta));
124  }
125 
126  // asin is ambiguous, make sure to have the right solution
127  if (std::abs(layer.getRadius() - getRadParticle(phi1)) > 1.0e-2) {
128  phi1 = -phi1 + M_PI;
129  }
130  if (std::abs(layer.getRadius() - getRadParticle(phi2)) > 1.0e-2) {
131  phi2 = -phi2 + M_PI;
132  }
133 
134  // another ambiguity
135  if (phi1 < 0) {
136  phi1 += 2. * M_PI;
137  }
138  if (phi2 < 0) {
139  phi2 += 2. * M_PI;
140  }
141 
142  // find the corresponding times when the intersection occurs
143  // make sure they are positive
144  double t1 = (phi1 - phi_) / phiSpeed_;
145  while (t1 < 0) {
146  t1 += 2 * M_PI / std::abs(phiSpeed_);
147  }
148  double t2 = (phi2 - phi_) / phiSpeed_;
149  while (t2 < 0) {
150  t2 += 2 * M_PI / std::abs(phiSpeed_);
151  }
152 
153  // Check if propagation successful (numerical reasons): both solutions (phi1, phi2) have to be on the layer (same radius)
154  // Can happen due to numerical instabilities of geometrical function (if momentum is almost parallel to x/y axis)
155  // Get crossingTimeC from StraightTrajectory as good approximation
156  if (std::abs(layer.getRadius() - getRadParticle(phi1)) > 1.0e-2 ||
157  std::abs(layer.getRadius() - getRadParticle(phi2)) > 1.0e-2) {
158  StraightTrajectory traj(*this);
159  return traj.nextCrossingTimeC(layer, onLayer);
160  }
161 
162  // if the particle is already on the layer, we need to make sure the 2nd solution is picked.
163  // happens if particle turns around in the magnetic field instead of hitting the next layer
164  if (onLayer) {
165  bool particleMovesInwards = momentum_.X() * position_.X() + momentum_.Y() * position_.Y() < 0;
166 
167  double posX1 = centerX_ + radius_ * std::cos(phi1);
168  double posY1 = centerY_ + radius_ * std::sin(phi1);
169  double momX1 = momentum_.X() * std::cos(phi1 - phi_) - momentum_.Y() * std::sin(phi1 - phi_);
170  double momY1 = momentum_.X() * std::sin(phi1 - phi_) + momentum_.Y() * std::cos(phi1 - phi_);
171  bool particleMovesInwards1 = momX1 * posX1 + momY1 * posY1 < 0;
172 
173  double posX2 = centerX_ + radius_ * std::cos(phi2);
174  double posY2 = centerY_ + radius_ * std::sin(phi2);
175  double momX2 = momentum_.X() * std::cos(phi2 - phi_) - momentum_.Y() * std::sin(phi2 - phi_);
176  double momY2 = momentum_.X() * std::sin(phi2 - phi_) + momentum_.Y() * std::cos(phi2 - phi_);
177  bool particleMovesInwards2 = momX2 * posX2 + momY2 * posY2 < 0;
178 
179  if (particleMovesInwards1 != particleMovesInwards) {
181  } else if (particleMovesInwards2 != particleMovesInwards) {
183  }
184  // try to catch numerical issues again..
185  else {
186  return -1;
187  }
188  }
189 
191 }

References a, funct::abs(), b, c, funct::cos(), dumpMFGeometry_cfg::delta, MillePedeFileConverter_cfg::e, F(), cmssw_cycle_finder::G, phase1PixelTopology::layer, M_PI, min(), fastsim::StraightTrajectory::nextCrossingTimeC(), funct::sin(), fastsim::Constants::speedOfLight, mathSSE::sqrt(), RandomServiceHelper::t1, and RandomServiceHelper::t2.

Member Data Documentation

◆ centerR_

const double fastsim::HelixTrajectory::centerR_
private

Distance of the center of the helix from the center of the tracker.

Definition at line 62 of file HelixTrajectory.h.

◆ centerX_

const double fastsim::HelixTrajectory::centerX_
private

X-coordinate of the center of the helix.

Definition at line 60 of file HelixTrajectory.h.

◆ centerY_

const double fastsim::HelixTrajectory::centerY_
private

Y-coordinate of the center of the helix.

Definition at line 61 of file HelixTrajectory.h.

◆ maxR_

const double fastsim::HelixTrajectory::maxR_
private

The maximum distance of the helix from the center of the tracker.

Definition at line 64 of file HelixTrajectory.h.

◆ minR_

const double fastsim::HelixTrajectory::minR_
private

The minimal distance of the helix from the center of the tracker.

Definition at line 63 of file HelixTrajectory.h.

◆ phi_

const double fastsim::HelixTrajectory::phi_
private

Ranges from 0 to 2PI: 0 corresponds to the positive X direction, phi increases counterclockwise.

The angle of the particle alone the helix.

Definition at line 58 of file HelixTrajectory.h.

◆ phiSpeed_

const double fastsim::HelixTrajectory::phiSpeed_
private

The angular speed of the particle on the helix trajectory.

Definition at line 65 of file HelixTrajectory.h.

◆ radius_

const double fastsim::HelixTrajectory::radius_
private

The radius of the helix.

Definition at line 57 of file HelixTrajectory.h.

fastsim::Trajectory::position_
math::XYZTLorentzVector position_
position of the particle that was used to create trajectory
Definition: Trajectory.h:91
RandomServiceHelper.t2
t2
Definition: RandomServiceHelper.py:257
fastsim::HelixTrajectory::crosses
bool crosses(const BarrelSimplifiedGeometry &layer) const override
Check if an intersection of the trajectory with a barrel layer exists.
Definition: HelixTrajectory.cc:56
fastsim::Constants::speedOfLight
static constexpr double speedOfLight
Speed of light [cm / ns].
Definition: Constants.h:12
fastsim::HelixTrajectory::radius_
const double radius_
The radius of the helix.
Definition: HelixTrajectory.h:57
min
T min(T a, T b)
Definition: MathUtil.h:58
fastsim::Trajectory::momentum_
math::XYZTLorentzVector momentum_
momentum of the particle that was used to create trajectory
Definition: Trajectory.h:92
fastsim::HelixTrajectory::phi_
const double phi_
Ranges from 0 to 2PI: 0 corresponds to the positive X direction, phi increases counterclockwise.
Definition: HelixTrajectory.h:58
fastsim::Trajectory::Trajectory
Trajectory(const fastsim::Particle &particle)
Constructor of base class.
Definition: Trajectory.cc:12
fastsim::HelixTrajectory::maxR_
const double maxR_
The maximum distance of the helix from the center of the tracker.
Definition: HelixTrajectory.h:64
F
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
funct::sin
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
RandomServiceHelper.t1
t1
Definition: RandomServiceHelper.py:256
funct::cos
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
SiPixelRawToDigiRegional_cfi.deltaPhi
deltaPhi
Definition: SiPixelRawToDigiRegional_cfi.py:9
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
b
double b
Definition: hdecay.h:118
phase1PixelTopology::layer
constexpr std::array< uint8_t, layerIndexSize > layer
Definition: phase1PixelTopology.h:99
fastsim::HelixTrajectory::centerY_
const double centerY_
Y-coordinate of the center of the helix.
Definition: HelixTrajectory.h:61
a
double a
Definition: hdecay.h:119
fastsim::HelixTrajectory::phiSpeed_
const double phiSpeed_
The angular speed of the particle on the helix trajectory.
Definition: HelixTrajectory.h:65
dumpMFGeometry_cfg.delta
delta
Definition: dumpMFGeometry_cfg.py:25
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:49
fastsim::HelixTrajectory::centerR_
const double centerR_
Distance of the center of the helix from the center of the tracker.
Definition: HelixTrajectory.h:62
CaloMaterial_cfi.magneticFieldZ
magneticFieldZ
Definition: CaloMaterial_cfi.py:112
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
fastsim::HelixTrajectory::minR_
const double minR_
The minimal distance of the helix from the center of the tracker.
Definition: HelixTrajectory.h:63
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:56
cmssw_cycle_finder.G
G
Definition: cmssw_cycle_finder.py:154
fastsim::HelixTrajectory::getRadParticle
double getRadParticle(double phi) const
Return distance of particle from center of the detector if it was at given angle phi of the helix.
Definition: HelixTrajectory.cc:209
fastsim::HelixTrajectory::centerX_
const double centerX_
X-coordinate of the center of the helix.
Definition: HelixTrajectory.h:60
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37