CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HelixArbitraryPlaneCrossing.cc
Go to the documentation of this file.
4 
5 #include <cmath>
6 #include <vdt/vdtMath.h>
7 #include <iostream>
9 
10 HelixArbitraryPlaneCrossing::HelixArbitraryPlaneCrossing(const PositionType& point,
11  const DirectionType& direction,
12  const float curvature,
13  const PropagationDirection propDir) :
14  theQuadraticCrossingFromStart(point,direction,curvature,propDir),
15  theX0(point.x()),
16  theY0(point.y()),
17  theZ0(point.z()),
18  theRho(curvature),
19  thePropDir(propDir),
20  theCachedS(0),
21  theCachedDPhi(0.),
22  theCachedSDPhi(0.),
23  theCachedCDPhi(1.)
24 {
25  //
26  // Components of direction vector (with correct normalisation)
27  //
28  double px = direction.x();
29  double py = direction.y();
30  double pz = direction.z();
31  double pt2 = px*px+py*py;
32  double p2 = pt2+pz*pz;
33  double pI = 1./sqrt(p2);
34  double ptI = 1./sqrt(pt2);
35  theCosPhi0 = px*ptI;
36  theSinPhi0 = py*ptI;
37  theCosTheta = pz*pI;
38  theSinTheta = pt2*ptI*pI;
39 }
40 //
41 // Propagation status and path length to intersection
42 //
43 std::pair<bool,double>
44 HelixArbitraryPlaneCrossing::pathLength(const Plane& plane) {
45  //
46  // Constants used for control of convergence
47  //
48  const int maxIterations(100);
49  //
50  // maximum distance to plane (taking into account numerical precision)
51  //
52  float maxNumDz = theNumericalPrecision*plane.position().mag();
53  float safeMaxDist = (theMaxDistToPlane>maxNumDz?theMaxDistToPlane:maxNumDz);
54  //
55  // Prepare internal value of the propagation direction and position / direction vectors for iteration
56  //
57  PropagationDirection propDir = thePropDir;
58  PositionTypeDouble xnew(theX0,theY0,theZ0);
59  DirectionTypeDouble pnew(theCosPhi0,theSinPhi0,theCosTheta/theSinTheta);
60  //
61  // Prepare iterations: count and total pathlength
62  //
63  unsigned int iteration(maxIterations+1);
64  double dSTotal(0.);
65  //
66  bool first = true;
67  while ( notAtSurface(plane,xnew,safeMaxDist) ) {
68  //
69  // return empty solution vector if no convergence after maxIterations iterations
70  //
71  if unlikely( --iteration == 0 ) {
72  edm::LogInfo("HelixArbitraryPlaneCrossing") << "pathLength : no convergence";
73  return std::pair<bool,double>(false,0);
74  }
75 
76  //
77  // Use existing 2nd order object at first pass, create temporary object
78  // for subsequent passes.
79  //
80  std::pair<bool,double> deltaS2;
81  if unlikely( first ) {
82  first = false;
83  deltaS2 = theQuadraticCrossingFromStart.pathLength(plane);
84  }
85  else {
86  HelixArbitraryPlaneCrossing2Order quadraticCrossing(xnew.x(),xnew.y(),xnew.z(),
87  pnew.x(),pnew.y(),
88  theCosTheta,theSinTheta,
89  theRho,
90  anyDirection);
91 
92  deltaS2 = quadraticCrossing.pathLength(plane);
93  }
94 
95  if unlikely( !deltaS2.first ) return deltaS2;
96  //
97  // Calculate and sort total pathlength (max. 2 solutions)
98  //
99  dSTotal += deltaS2.second;
100  PropagationDirection newDir = dSTotal>=0 ? alongMomentum : oppositeToMomentum;
101  if ( propDir == anyDirection ) {
102  propDir = newDir;
103  }
104  else {
105  if unlikely( newDir!=propDir ) return std::pair<bool,double>(false,0);
106  }
107  //
108  // Step forward by dSTotal.
109  //
110  xnew = positionInDouble(dSTotal);
111  pnew = directionInDouble(dSTotal);
112  }
113  //
114  // Return result
115  //
116  return std::pair<bool,double>(true,dSTotal);
117 }
118 //
119 // Position on helix after a step of path length s.
120 //
122 HelixArbitraryPlaneCrossing::position (double s) const {
123  // use result in double precision
124  PositionTypeDouble pos = positionInDouble(s);
125  return PositionType(pos.x(),pos.y(),pos.z());
126 }
127 //
128 // Position on helix after a step of path length s in double precision.
129 //
130 HelixArbitraryPlaneCrossing::PositionTypeDouble
131 HelixArbitraryPlaneCrossing::positionInDouble (double s) const {
132  //
133  // Calculate delta phi (if not already available)
134  //
135  if unlikely( s!=theCachedS ) {
136  theCachedS = s;
137  theCachedDPhi = theCachedS*theRho*theSinTheta;
138  vdt::fast_sincos(theCachedDPhi,theCachedSDPhi,theCachedCDPhi);
139  }
140  //
141  // Calculate with appropriate formulation of full helix formula or with
142  // 2nd order approximation.
143  //
144 // if ( fabs(theCachedDPhi)>1.e-1 ) {
145  if ( std::abs(theCachedDPhi)>1.e-4 ) {
146  // "standard" helix formula
147  double o = 1./theRho;
148  return PositionTypeDouble(theX0+(-theSinPhi0*(1.-theCachedCDPhi)+theCosPhi0*theCachedSDPhi)*o,
149  theY0+( theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)*o,
150  theZ0+theCachedS*theCosTheta);
151  }
152 // else if ( fabs(theCachedDPhi)>theNumericalPrecision ) {
153 // // full helix formula, but avoiding (1-cos(deltaPhi)) for small angles
154 // return PositionTypeDouble(theX0+(-theSinPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
155 // theCosPhi0*theCachedSDPhi)/theRho,
156 // theY0+(theCosPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
157 // theSinPhi0*theCachedSDPhi)/theRho,
158 // theZ0+theCachedS*theCosTheta);
159 // }
160  else {
161  // Use 2nd order.
162  return theQuadraticCrossingFromStart.positionInDouble(theCachedS);
163  }
164 }
165 //
166 // Direction vector on helix after a step of path length s.
167 //
169 HelixArbitraryPlaneCrossing::direction (double s) const {
170  // use result in double precision
171  DirectionTypeDouble dir = directionInDouble(s);
172  return DirectionType(dir.x(),dir.y(),dir.z());
173 }
174 //
175 // Direction vector on helix after a step of path length s in double precision.
176 //
177 HelixArbitraryPlaneCrossing::DirectionTypeDouble
178 HelixArbitraryPlaneCrossing::directionInDouble (double s) const {
179  //
180  // Calculate delta phi (if not already available)
181  //
182  if unlikely( s!=theCachedS ) {
183  theCachedS = s;
184  theCachedDPhi = theCachedS*theRho*theSinTheta;
185  theCachedSDPhi = sin(theCachedDPhi);
186  theCachedCDPhi = cos(theCachedDPhi);
187  }
188 
189  if ( std::abs(theCachedDPhi)>1.e-4 ) {
190  // full helix formula
191  return DirectionTypeDouble(theCosPhi0*theCachedCDPhi-theSinPhi0*theCachedSDPhi,
192  theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
193  theCosTheta/theSinTheta);
194  }
195  else {
196  // 2nd order
197  return theQuadraticCrossingFromStart.directionInDouble(theCachedS);
198  }
199 }
200 // Iteration control: continue if distance to plane > theMaxDistToPlane. Includes
201 // protection for numerical precision (Surfaces work with single precision).
202 bool HelixArbitraryPlaneCrossing::notAtSurface (const Plane& plane,
203  const PositionTypeDouble& point,
204  const float maxDist) const {
205  float dz = plane.localZ(Surface::GlobalPoint(point.x(),point.y(),point.z()));
206  return std::abs(dz)>maxDist;
207 }
208 
209 const float HelixArbitraryPlaneCrossing::theNumericalPrecision = 5.e-7f;
210 const float HelixArbitraryPlaneCrossing::theMaxDistToPlane = 1.e-4f;
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:49
PropagationDirection
Definition: Plane.h:17
float float float z
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
Point3DBase< Scalar, GlobalTag > PositionType
Definition: Definitions.h:30
U second(std::pair< T, U > const &p)
#define unlikely(x)
Definition: Likely.h:21
T mag() const
Definition: PV3DBase.h:67
T curvature(T InversePt, const edm::EventSetup &iSetup)
tuple iteration
Definition: align_cfg.py:5
T sqrt(T t)
Definition: SSEVec.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
bool first
Definition: L1TdeRCT.cc:79
double p2[4]
Definition: TauolaWrapper.h:90
return(e1-e2)*(e1-e2)+dp *dp
if(dp >Float(M_PI)) dp-
dbl *** dir
Definition: mlp_gen.cc:35
volatile std::atomic< bool > shutdown_flag false
Definition: DDAxes.h:10
const PositionType & position() const
*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