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