CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HelixExtrapolatorToLine2Order.cc
Go to the documentation of this file.
4 
5 #include <cfloat>
6 
8  const DirectionType& direction,
9  const float curvature,
10  const PropagationDirection propDir) :
11  thePosition(point),
12  theRho(curvature),
13  thePropDir(propDir)
14 {
15  //
16  // Components of direction vector (with correct normalisation)
17  //
18  double px = direction.x();
19  double py = direction.y();
20  double pz = direction.z();
21  double pt = px*px+py*py;
22  double p = sqrt(pt+pz*pz);
23  pt = sqrt(pt);
24  theDirection = DirectionTypeDouble(px/pt,py/pt,pz/pt);
25  theSinTheta = pt/p;
26 }
27 
28 //
29 // Propagation status and path length to closest approach with point
30 //
31 std::pair<bool,double>
33  //
36  0.5*theRho*theDirection.x(),
37  0.);
38  DirectionTypeDouble deltaPos(thePosition-position);
39  //
40  // coefficients of 3rd order equation
41  //
42  double ceq[4];
43  ceq[3] = 2*helix2.mag2();
44  // ceq[2] = 3*theDirection.dot(helix2) = 0 since they are orthogonal
45  ceq[2] = 0.;
46  ceq[1] = theDirection.mag2()+2*deltaPos.dot(helix2);
47  ceq[0] = deltaPos.dot(theDirection);
48  //
49  return pathLengthFromCoefficients(ceq);
50 }
51 
52 //
53 // Propagation status and path length to closest approach with line
54 //
55 std::pair<bool,double>
57  //
58  // Auxiliary vectors. Assumes that line.direction().mag()=1 !
59  //
60  PositionTypeDouble linePosition(line.position());
61  DirectionTypeDouble lineDirection(line.direction());
63  0.5*theRho*theDirection.x(),
64  0.);
65  DirectionTypeDouble deltaPos(thePosition-linePosition);
66  DirectionTypeDouble helix1p(theDirection-lineDirection*theDirection.dot(lineDirection));
67  DirectionTypeDouble helix2p(helix2-lineDirection*helix2.dot(lineDirection));
68  //
69  // coefficients of 3rd order equation
70  //
71  double ceq[4];
72  ceq[3] = 2*helix2.dot(helix2p);
73  // ceq[2] = 3*helix1.dot(helix1p);
74  // since theDirection.dot(helix2)==0 equivalent to
75  ceq[2] = 3*theDirection.dot(lineDirection)*helix2.dot(lineDirection);
76  ceq[1] = theDirection.dot(helix1p)+2*deltaPos.dot(helix2p);
77  ceq[0] = deltaPos.dot(helix1p);
78  //
79  return pathLengthFromCoefficients(ceq);
80 }
81 
82 //
83 // Propagation status and path length to intersection
84 //
85 std::pair<bool,double>
87 {
88  //
89  // Solution of 3rd order equation
90  //
91  double solutions[3];
92  unsigned int nRaw = solve3rdOrder(ceq,solutions);
93  //
94  // check compatibility with propagation direction
95  //
96  unsigned int nDir(0);
97  for ( unsigned int i=0; i<nRaw; i++ ) {
98  if ( thePropDir==anyDirection ||
99  (solutions[i]>=0&&thePropDir==alongMomentum) ||
100  (solutions[i]<=0&&thePropDir==oppositeToMomentum) )
101  solutions[nDir++] = solutions[i];
102  }
103  if ( nDir==0 ) return std::make_pair(false,0.);
104  //
105  // check 2nd derivative
106  //
107  unsigned int nMin(0);
108  for ( unsigned int i=0; i<nDir; i++ ) {
109  double st = solutions[i];
110  double deri2 = (3*ceq[3]*st+2*ceq[2])*st+ceq[1];
111  if ( deri2>0. ) solutions[nMin++] = st;
112  }
113  if ( nMin==0 ) return std::make_pair(false,0.);
114  //
115  // choose smallest path length
116  //
117  double dSt = solutions[0];
118  for ( unsigned int i=1; i<nMin; i++ ) {
119  if ( fabs(solutions[i])<fabs(dSt) ) dSt = solutions[i];
120  }
121 
122  return std::make_pair(true,dSt/theSinTheta);
123 }
124 
125 int
127  double solutions[]) const
128 {
129  //
130  // Real 3rd order equation? Follow numerical recipes ..
131  //
132  if ( fabs(ceq[3])>FLT_MIN ) {
133  int result(0);
134  double q = (ceq[2]*ceq[2]-3*ceq[3]*ceq[1]) / (ceq[3]*ceq[3]) / 9.;
135  double r = (2*ceq[2]*ceq[2]*ceq[2]-9*ceq[3]*ceq[2]*ceq[1]+27*ceq[3]*ceq[3]*ceq[0])
136  / (ceq[3]*ceq[3]*ceq[3]) / 54.;
137  double q3 = q*q*q;
138  if ( r*r<q3 ) {
139  double phi = acos(r/sqrt(q3))/3.;
140  double rootq = sqrt(q);
141  for ( int i=0; i<3; i++ ) {
142  solutions[i] = -2*rootq*cos(phi) - ceq[2]/ceq[3]/3.;
143  phi += 2./3.*M_PI;
144  }
145  result = 3;
146  }
147  else {
148  double a = pow(fabs(r)+sqrt(r*r-q3),1./3.);
149  if ( r>0. ) a *= -1;
150  double b = fabs(a)>FLT_MIN ? q/a : 0.;
151  solutions[0] = a + b - ceq[2]/ceq[3]/3.;
152  result = 1;
153  }
154  return result;
155  }
156  //
157  // Second order equation
158  //
159  else if ( fabs(ceq[2])>FLT_MIN ) {
160  return solve2ndOrder(ceq,solutions);
161  }
162  else {
163  //
164  // Special case: linear equation
165  //
166  solutions[0] = -ceq[0]/ceq[1];
167  return 1;
168  }
169 }
170 
171 int
173  double solutions[]) const
174 {
175  //
176  double deq1 = coeff[1]*coeff[1];
177  double deq2 = coeff[2]*coeff[0];
178  if ( fabs(deq1)<FLT_MIN || fabs(deq2/deq1)>1.e-6 ) {
179  //
180  // Standard solution for quadratic equations
181  //
182  double deq = deq1+2*deq2;
183  if ( deq<0. ) return 0;
184  double ceq = -0.5*(coeff[1]+(coeff[1]>0?1:-1)*sqrt(deq));
185  solutions[0] = -2*ceq/coeff[2];
186  solutions[1] = coeff[0]/ceq;
187  return 2;
188  }
189  else {
190  //
191  // Solution by expansion of sqrt(1+deq)
192  //
193  double ceq = coeff[1]/coeff[2];
194  double deq = deq2/deq1;
195  deq *= (1-deq/2);
196  solutions[0] = -ceq*deq;
197  solutions[1] = ceq*(2+deq);
198  return 2;
199  }
200 }
201 //
202 // Position after a step of path length s (2nd order)
203 //
206  // use double precision result
207 // PositionTypeDouble pos = positionInDouble(s);
208 // return PositionType(pos.x(),pos.y(),pos.z());
209  return PositionType(positionInDouble(s));
210 }
211 //
212 // Position after a step of path length s (2nd order) (in double precision)
213 //
216  // based on path length in the transverse plane
217  double st = s*theSinTheta;
219  thePosition.y()+(theDirection.y()+st*0.5*theRho*theDirection.x())*st,
220  thePosition.z()+st*theDirection.z());
221 }
222 //
223 // Direction after a step of path length 2 (2nd order) (in double precision)
224 //
227  // use double precision result
228 // DirectionTypeDouble dir = directionInDouble(s);
229 // return DirectionType(dir.x(),dir.y(),dir.z());
230  return DirectionType(directionInDouble(s));
231 }
232 //
233 // Direction after a step of path length 2 (2nd order)
234 //
237  // based on delta phi
238  double dph = s*theRho*theSinTheta;
239  return DirectionTypeDouble(theDirection.x()-(theDirection.y()+0.5*theDirection.x()*dph)*dph,
240  theDirection.y()+(theDirection.x()-0.5*theDirection.y()*dph)*dph,
241  theDirection.z());
242 }
HelixExtrapolatorToLine2Order(const PositionType &point, const DirectionType &direction, const float curvature, const PropagationDirection propDir=alongMomentum)
Constructor using point, direction and (transverse!) curvature.
int i
Definition: DBlmapReader.cc:9
DirectionType direction() const
Definition: Line.h:27
PositionTypeDouble positionInDouble(double s) const
Position at pathlength s from the starting point in double precision.
virtual DirectionType direction(double s) const
Direction at pathlength s from the starting point.
T y() const
Cartesian y coordinate.
T x() const
Cartesian x coordinate.
Definition: Line.h:10
Basic3DVector< double > PositionTypeDouble
int solve3rdOrder(const double ceq[], double sol[]) const
Solutions of 3rd order equation.
PropagationDirection
Basic3DVector< double > DirectionTypeDouble
tuple result
Definition: mps_fire.py:84
PositionType position() const
Definition: Line.h:26
Basic3DVector< float > DirectionType
T curvature(T InversePt, const edm::EventSetup &iSetup)
Basic3DVector< float > PositionType
T z() const
Cartesian z coordinate.
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
int solve2ndOrder(const double ceq[], double sol[]) const
Solutions of 2nd order equation.
virtual PositionType position(double s) const
Position at pathlength s from the starting point.
virtual std::pair< bool, double > pathLengthFromCoefficients(const double ceq[4]) const
common part for propagation to point and line
#define M_PI
double b
Definition: hdecay.h:120
DirectionTypeDouble directionInDouble(double s) const
Direction at pathlength s from the starting point in double precision.
double a
Definition: hdecay.h:121
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
*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
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
T dot(const Basic3DVector &rh) const
Scalar product, or &quot;dot&quot; product, with a vector of same type.
virtual std::pair< bool, double > pathLength(const GlobalPoint &point) const