CMS 3D CMS Logo

HelixArbitraryPlaneCrossing2Order.cc
Go to the documentation of this file.
2 
5 
6 #include <cmath>
7 #include <cfloat>
10 
12  const DirectionType& direction,
13  const float curvature,
14  const PropagationDirection propDir)
15  : theX0(point.x()), theY0(point.y()), theZ0(point.z()), theRho(curvature), thePropDir(propDir) {
16  //
17  // Components of direction vector (with correct normalisation)
18  //
19  double px = direction.x();
20  double py = direction.y();
21  double pz = direction.z();
22  double pt2 = px * px + py * py;
23  double p2 = pt2 + pz * pz;
24  double pI = 1. / sqrt(p2);
25  double ptI = 1. / sqrt(pt2);
26  theCosPhi0 = px * ptI;
27  theSinPhi0 = py * ptI;
28  theCosTheta = pz * pI;
29  theSinThetaI = p2 * pI * ptI; // (1/(pt/p)) = p/pt = p*ptI and p = p2/p = p2*pI
30 }
31 
32 //
33 // Propagation status and path length to intersection
34 //
35 std::pair<bool, double> HelixArbitraryPlaneCrossing2Order::pathLength(const Plane& plane) {
36  //
37  // get local z-vector in global co-ordinates and
38  // distance to starting point
39  //
40  GlobalVector normalToPlane = plane.normalVector();
41  double nPx = normalToPlane.x();
42  double nPy = normalToPlane.y();
43  double nPz = normalToPlane.z();
44  double cP = plane.localZ(GlobalPoint(theX0, theY0, theZ0));
45  //
46  // coefficients of 2nd order equation to obtain intersection point
47  // in approximation (without curvature-related factors).
48  //
49  double ceq1 = theRho * (nPx * theSinPhi0 - nPy * theCosPhi0);
50  double ceq2 = nPx * theCosPhi0 + nPy * theSinPhi0 + nPz * theCosTheta * theSinThetaI;
51  double ceq3 = cP;
52  //
53  // Check for degeneration to linear equation (zero
54  // curvature, forward plane or direction perp. to plane)
55  //
56  double dS1, dS2;
57  if LIKELY (std::abs(ceq1) > FLT_MIN) {
58  double deq1 = ceq2 * ceq2;
59  double deq2 = ceq1 * ceq3;
60  if (std::abs(deq1) < FLT_MIN || std::abs(deq2 / deq1) > 1.e-6) {
61  //
62  // Standard solution for quadratic equations
63  //
64  double deq = deq1 + 2 * deq2;
65  if UNLIKELY (deq < 0.)
66  return std::pair<bool, double>(false, 0);
67  double ceq = ceq2 + std::copysign(std::sqrt(deq), ceq2);
68  dS1 = (ceq / ceq1) * theSinThetaI;
69  dS2 = -2. * (ceq3 / ceq) * theSinThetaI;
70  } else {
71  //
72  // Solution by expansion of sqrt(1+deq)
73  //
74  double ceq = (ceq2 / ceq1) * theSinThetaI;
75  double deq = deq2 / deq1;
76  deq *= (1 - 0.5 * deq);
77  dS1 = -ceq * deq;
78  dS2 = ceq * (2 + deq);
79  }
80  } else {
81  //
82  // Special case: linear equation
83  //
84  dS1 = dS2 = -(ceq3 / ceq2) * theSinThetaI;
85  }
86  //
87  // Choose and return solution
88  //
89  return solutionByDirection(dS1, dS2);
90 }
91 
92 //
93 // Position after a step of path length s (2nd order)
94 //
96  // use double precision result
98  return PositionType(pos.x(), pos.y(), pos.z());
99 }
100 //
101 // Position after a step of path length s (2nd order) (in double precision)
102 //
104  double s) const {
105  // based on path length in the transverse plane
106  double st = s / theSinThetaI;
107  return PositionTypeDouble(theX0 + (theCosPhi0 - (st * 0.5 * theRho) * theSinPhi0) * st,
108  theY0 + (theSinPhi0 + (st * 0.5 * theRho) * theCosPhi0) * st,
109  theZ0 + st * theCosTheta * theSinThetaI);
110 }
111 //
112 // Direction after a step of path length 2 (2nd order) (in double precision)
113 //
115  // use double precision result
117  return DirectionType(dir.x(), dir.y(), dir.z());
118 }
119 //
120 // Direction after a step of path length 2 (2nd order)
121 //
123  double s) const {
124  // based on delta phi
125  double dph = s * theRho / theSinThetaI;
126  return DirectionTypeDouble(theCosPhi0 - (theSinPhi0 + 0.5 * dph * theCosPhi0) * dph,
127  theSinPhi0 + (theCosPhi0 - 0.5 * dph * theSinPhi0) * dph,
129 }
130 //
131 // Choice of solution according to propagation direction
132 //
133 std::pair<bool, double> HelixArbitraryPlaneCrossing2Order::solutionByDirection(const double dS1,
134  const double dS2) const {
135  bool valid = false;
136  double path = 0;
137  if (thePropDir == anyDirection) {
138  valid = true;
139  path = smallestPathLength(dS1, dS2);
140  } else {
141  // use same logic for both directions (invert if necessary)
142  double propSign = thePropDir == alongMomentum ? 1 : -1;
143  double s1(propSign * dS1);
144  double s2(propSign * dS2);
145  // sort
146  if (s1 > s2)
147  std::swap(s1, s2);
148  // choose solution (if any with positive sign)
149  if ((s1 < 0) & (s2 >= 0)) {
150  // First solution in backward direction: choose second one.
151  valid = true;
152  path = propSign * s2;
153  } else if (s1 >= 0) {
154  // First solution in forward direction: choose it (s2 is further away!).
155  valid = true;
156  path = propSign * s1;
157  }
158  }
159  if (edm::isNotFinite(path))
160  valid = false;
161  return std::pair<bool, double>(valid, path);
162 }
HelixArbitraryPlaneCrossing2Order(const PositionType &point, const DirectionType &direction, const float curvature, const PropagationDirection propDir=alongMomentum)
T x() const
Cartesian x coordinate.
T z() const
Definition: PV3DBase.h:61
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
PositionTypeDouble positionInDouble(double s) const
DirectionTypeDouble directionInDouble(double s) const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
#define LIKELY(x)
Definition: Likely.h:20
PropagationDirection
DirectionType direction(double s) const override
T y() const
Cartesian y coordinate.
Definition: Plane.h:16
float float float z
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
T curvature(T InversePt, const MagneticField &field)
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
double smallestPathLength(const double firstPathLength, const double secondPathLength) const
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Basic3DVector< float > PositionType
the helix is passed to the constructor and does not appear in the interface
Basic3DVector< float > DirectionType
PositionType position(double s) const override
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
T z() const
Cartesian z coordinate.
std::pair< bool, double > pathLength(const Plane &) override
float x
GlobalVector normalVector() const
Definition: Plane.h:41
std::pair< bool, double > solutionByDirection(const double dS1, const double dS2) const
#define UNLIKELY(x)
Definition: Likely.h:21
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5