CMS 3D CMS Logo

HelixArbitraryPlaneCrossing.cc
Go to the documentation of this file.
4 
5 #include <cmath>
6 #include <vdt/vdtMath.h>
7 #include <iostream>
9 
10 #ifdef VI_DEBUG
11 #include <atomic>
12 struct MaxIter {
13  MaxIter(){}
14  ~MaxIter() { std::cout << "maxiter " << v << std::endl; }
15  void operator()(int i) const {
16  int old = v;
17  int t = std::min(old,i);
18  while(not v.compare_exchange_weak(old,t)) {
19  t = std::min(old,i);
20  }
21  }
22  mutable std::atomic<int> v {100};
23 };
24 #else
25 struct MaxIter {
26  MaxIter(){}
27  void operator()(int)const{}
28 };
29 #endif
30 static const MaxIter maxiter;
31 
32 
34  const DirectionType& direction,
35  const float curvature,
36  const PropagationDirection propDir) :
37  theQuadraticCrossingFromStart(point,direction,curvature,propDir),
38  theX0(point.x()),
39  theY0(point.y()),
40  theZ0(point.z()),
41  theRho(curvature),
42  thePropDir(propDir),
43  theCachedS(0),
44  theCachedDPhi(0.),
45  theCachedSDPhi(0.),
46  theCachedCDPhi(1.)
47 {
48  //
49  // Components of direction vector (with correct normalisation)
50  //
51  double px = direction.x();
52  double py = direction.y();
53  double pz = direction.z();
54  double pt2 = px*px+py*py;
55  double p2 = pt2+pz*pz;
56  double pI = 1./sqrt(p2);
57  double ptI = 1./sqrt(pt2);
58  theCosPhi0 = px*ptI;
59  theSinPhi0 = py*ptI;
60  theCosTheta = pz*pI;
61  theSinTheta = pt2*ptI*pI;
62 }
63 //
64 // Propagation status and path length to intersection
65 //
66 std::pair<bool,double>
68  //
69  // Constants used for control of convergence
70  //
71  constexpr int maxIterations = 20;
72  //
73  // maximum distance to plane (taking into account numerical precision)
74  //
75  float maxNumDz = theNumericalPrecision*plane.position().mag();
76  float safeMaxDist = (theMaxDistToPlane>maxNumDz?theMaxDistToPlane:maxNumDz);
77  //
78  // Prepare internal value of the propagation direction and position / direction vectors for iteration
79  //
80 
82  if (std::abs(dz)<safeMaxDist) return std::make_pair(true,0.);
83 
84  bool notFail;
85  double dSTotal;
86  // Use existing 2nd order object at first pass
87  std::tie(notFail,dSTotal) = theQuadraticCrossingFromStart.pathLength(plane);
88  if unlikely(!notFail) return std::make_pair(notFail,dSTotal);
89  auto xnew = positionInDouble(dSTotal);
90 
91  auto propDir = thePropDir;
92  auto newDir = dSTotal>=0 ? alongMomentum : oppositeToMomentum;
93  if ( propDir == anyDirection ) {
94  propDir = newDir;
95  } else {
96  if unlikely( newDir!=propDir ) return std::pair<bool,double>(false,0);
97  }
98 
99 
100  //
101  // Prepare iterations: count and total pathlength
102  //
103  auto iteration = maxIterations;
104  while ( notAtSurface(plane,xnew,safeMaxDist) ) {
105  //
106  // return empty solution vector if no convergence after maxIterations iterations
107  //
108  if unlikely( --iteration == 0 ) {
109  LogDebug("HelixArbitraryPlaneCrossing") << "pathLength : no convergence";
110  return std::pair<bool,double>(false,0);
111  }
112 
113  //
114  // create temporary object for subsequent passes.
115  auto pnew = directionInDouble(dSTotal);
116  HelixArbitraryPlaneCrossing2Order quadraticCrossing(xnew.x(),xnew.y(),xnew.z(),
117  pnew.x(),pnew.y(),
119  theRho,
120  anyDirection);
121 
122  auto deltaS2 = quadraticCrossing.pathLength(plane);
123 
124 
125  if unlikely( !deltaS2.first ) return deltaS2;
126  //
127  // Calculate and sort total pathlength (max. 2 solutions)
128  //
129  dSTotal += deltaS2.second;
130  auto newDir = dSTotal>=0 ? alongMomentum : oppositeToMomentum;
131  if ( propDir == anyDirection ) {
132  propDir = newDir;
133  }
134  else {
135  if unlikely( newDir!=propDir ) return std::pair<bool,double>(false,0);
136  }
137  //
138  // Step forward by dSTotal.
139  //
140  xnew = positionInDouble(dSTotal);
141  }
142  //
143  // Return result
144  //
145  maxiter(iteration);
146 
147  return std::make_pair(true,dSTotal);
148 }
149 //
150 // Position on helix after a step of path length s.
151 //
154  // use result in double precision
156  return PositionType(pos.x(),pos.y(),pos.z());
157 }
158 //
159 // Position on helix after a step of path length s in double precision.
160 //
163  //
164  // Calculate delta phi (if not already available)
165  //
166  if unlikely( s!=theCachedS ) {
167  theCachedS = s;
169  vdt::fast_sincos(theCachedDPhi,theCachedSDPhi,theCachedCDPhi);
170  }
171  //
172  // Calculate with appropriate formulation of full helix formula or with
173  // 2nd order approximation.
174  //
175 // if ( fabs(theCachedDPhi)>1.e-1 ) {
176  if ( std::abs(theCachedDPhi)>1.e-4 ) {
177  // "standard" helix formula
178  double o = 1./theRho;
180  theY0+( theCosPhi0*(1.-theCachedCDPhi)+theSinPhi0*theCachedSDPhi)*o,
182  }
183 // else if ( fabs(theCachedDPhi)>theNumericalPrecision ) {
184 // // full helix formula, but avoiding (1-cos(deltaPhi)) for small angles
185 // return PositionTypeDouble(theX0+(-theSinPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
186 // theCosPhi0*theCachedSDPhi)/theRho,
187 // theY0+(theCosPhi0*theCachedSDPhi*theCachedSDPhi/(1.+theCachedCDPhi)+
188 // theSinPhi0*theCachedSDPhi)/theRho,
189 // theZ0+theCachedS*theCosTheta);
190 // }
191  else {
192  // Use 2nd order.
194  }
195 }
196 //
197 // Direction vector on helix after a step of path length s.
198 //
201  // use result in double precision
203  return DirectionType(dir.x(),dir.y(),dir.z());
204 }
205 //
206 // Direction vector on helix after a step of path length s in double precision.
207 //
210  //
211  // Calculate delta phi (if not already available)
212  //
213  if unlikely( s!=theCachedS ) { // very very unlikely!
214  theCachedS = s;
216  vdt::fast_sincos(theCachedDPhi,theCachedSDPhi,theCachedCDPhi);
217  }
218 
219  if ( std::abs(theCachedDPhi)>1.e-4 ) {
220  // full helix formula
222  theSinPhi0*theCachedCDPhi+theCosPhi0*theCachedSDPhi,
224  }
225  else {
226  // 2nd order
228  }
229 }
230 // Iteration control: continue if distance to plane > theMaxDistToPlane. Includes
231 // protection for numerical precision (Surfaces work with single precision).
233  const PositionTypeDouble& point,
234  const float maxDist) const {
235  float dz = plane.localZ(Surface::GlobalPoint(point.x(),point.y(),point.z()));
236  return std::abs(dz)>maxDist;
237 }
238 
#define LogDebug(id)
DirectionTypeDouble directionInDouble(double s) const
std::pair< bool, double > pathLength(const Plane &plane) override
HelixArbitraryPlaneCrossing2Order theQuadraticCrossingFromStart
T y() const
Cartesian y coordinate.
T x() const
Cartesian x coordinate.
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
DirectionTypeDouble directionInDouble(double s) const
Basic3DVector< double > PositionTypeDouble
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
const PropagationDirection thePropDir
PropagationDirection
Definition: Plane.h:17
#define constexpr
#define unlikely(x)
T curvature(T InversePt, const edm::EventSetup &iSetup)
T z() const
Cartesian z coordinate.
T sqrt(T t)
Definition: SSEVec.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
PositionTypeDouble positionInDouble(double s) const
PositionType position(double s) const override
double f[11][100]
static const MaxIter maxiter
T min(T a, T b)
Definition: MathUtil.h:58
PositionTypeDouble positionInDouble(double s) 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
DirectionType direction(double s) const override
std::pair< bool, double > pathLength(const Plane &) override
Basic3DVector< double > DirectionTypeDouble
void operator()(int) const
dbl *** dir
Definition: mlp_gen.cc:35
bool notAtSurface(const Plane &, const PositionTypeDouble &, const float) const
HelixArbitraryPlaneCrossing(const PositionType &point, const DirectionType &direction, const float curvature, const PropagationDirection propDir=alongMomentum)
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