CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HelixBarrelPlaneCrossingByCircle.cc
Go to the documentation of this file.
6 
7 #include <algorithm>
8 #include <cfloat>
9 
11  const DirectionType& dir,
12  double rho,
13  PropagationDirection propDir)
14  : theStartingPos(pos), theStartingDir(dir), theRho(rho), thePropDir(propDir) {
15  init();
16 }
17 
19  const GlobalVector& dir,
20  double rho,
21  PropagationDirection propDir)
22  : theStartingPos(pos.basicVector()), theStartingDir(dir.basicVector()), theRho(rho), thePropDir(propDir) {
23  init();
24 }
25 
27  double pabsI = 1. / theStartingDir.mag();
28  double pt = theStartingDir.perp();
29  theCosTheta = theStartingDir.z() * pabsI;
30  theSinTheta = pt * pabsI;
31 
32  // protect for zero curvature case
33  const double sraightLineCutoff = 1.e-7;
34  if (fabs(theRho) < sraightLineCutoff && fabs(theRho) * theStartingPos.perp() < sraightLineCutoff) {
35  useStraightLine = true;
36  } else {
37  // circle parameters
38  // position of center of curvature is on a line perpendicular
39  // to startingDir and at a distance 1/curvature.
40  double o = 1. / (pt * theRho);
43  useStraightLine = false;
44  }
45 }
46 
47 std::pair<bool, double> HelixBarrelPlaneCrossingByCircle::pathLength(const Plane& plane) {
48  typedef std::pair<bool, double> ResultType;
49 
50  if (useStraightLine) {
51  // switch to straight line case
53  return slc.pathLength(plane);
54  }
55 
56  // plane parameters
57  GlobalVector n = plane.normalVector();
58  double distToPlane = -plane.localZ(GlobalPoint(theStartingPos));
59  // double distToPlane = (plane.position().x()-theStartingPos.x()) * n.x() +
60  // (plane.position().y()-theStartingPos.y()) * n.y();
61  double nx = n.x(); // convert to double
62  double ny = n.y(); // convert to double
63  double distCx = theStartingPos.x() - theXCenter;
64  double distCy = theStartingPos.y() - theYCenter;
65 
66  double nfac, dfac;
67  double A, B, C;
68  bool solveForX;
69  if (fabs(nx) > fabs(ny)) {
70  solveForX = false;
71  nfac = ny / nx;
72  dfac = distToPlane / nx;
73  B = distCy - nfac * distCx; // only part of B, may have large cancelation
74  C = (2. * distCx + dfac) * dfac;
75  } else {
76  solveForX = true;
77  nfac = nx / ny;
78  dfac = distToPlane / ny;
79  B = distCx - nfac * distCy; // only part of B, may have large cancelation
80  C = (2. * distCy + dfac) * dfac;
81  }
82  B -= nfac * dfac;
83  B *= 2; // the rest of B (normally small)
84  A = 1. + nfac * nfac;
85 
86  double dx1, dx2, dy1, dy2;
87  RealQuadEquation equation(A, B, C);
88  if (!equation.hasSolution)
89  return ResultType(false, theS = 0.);
90  else {
91  if (solveForX) {
92  dx1 = equation.first;
93  dx2 = equation.second;
94  dy1 = dfac - nfac * dx1;
95  dy2 = dfac - nfac * dx2;
96  } else {
97  dy1 = equation.first;
98  dy2 = equation.second;
99  dx1 = dfac - nfac * dy1;
100  dx2 = dfac - nfac * dy2;
101  }
102  }
103  bool solved = chooseSolution(Vector2D(dx1, dy1), Vector2D(dx2, dy2));
104  if (solved) {
105  theDmag = theD.mag();
106  // protect asin
107  double sinAlpha = 0.5 * theDmag * theRho;
108  if (std::abs(sinAlpha) > 1.)
109  sinAlpha = std::copysign(1., sinAlpha);
110  theS = theActualDir * 2. / (theRho * theSinTheta) * asin(sinAlpha);
111  return ResultType(true, theS);
112  } else
113  return ResultType(false, theS = 0.);
114 }
115 
117  bool solved;
118  double momProj1 = theStartingDir.x() * d1.x() + theStartingDir.y() * d1.y();
119  double momProj2 = theStartingDir.x() * d2.x() + theStartingDir.y() * d2.y();
120 
121  if (thePropDir == anyDirection) {
122  solved = true;
123  if (d1.mag2() < d2.mag2()) {
124  theD = d1;
125  theActualDir = (momProj1 > 0) ? 1. : -1.;
126  } else {
127  theD = d2;
128  theActualDir = (momProj2 > 0) ? 1. : -1.;
129  }
130 
131  } else {
132  double propSign = thePropDir == alongMomentum ? 1 : -1;
133  if (!mathSSE::samesign(momProj1, momProj2)) {
134  // if different signs return the positive one
135  solved = true;
136  theD = mathSSE::samesign(momProj1, propSign) ? d1 : d2;
137  theActualDir = propSign;
138  } else if (mathSSE::samesign(momProj1, propSign)) {
139  // if both positive, return the shortest
140  solved = true;
141  theD = (d1.mag2() < d2.mag2()) ? d1 : d2;
142  theActualDir = propSign;
143  } else
144  solved = false;
145  }
146  return solved;
147 }
148 
150  if (useStraightLine) {
152  } else {
153  if (s == theS) {
154  return PositionType(
156  } else {
157  double phi = s * theSinTheta * theRho;
158  double x1Shift = theStartingPos.x() - theXCenter;
159  double y1Shift = theStartingPos.y() - theYCenter;
160 
161  return PositionType(x1Shift * cos(phi) - y1Shift * sin(phi) + theXCenter,
162  x1Shift * sin(phi) + y1Shift * cos(phi) + theYCenter,
163  theStartingPos.z() + s * theCosTheta);
164  }
165  }
166 }
167 
169  if (useStraightLine) {
170  return theStartingDir;
171  } else {
172  double sinPhi, cosPhi;
173  if (s == theS) {
174  double tmp = 0.5 * theDmag * theRho;
175  if (s < 0)
176  tmp = -tmp;
177  // protect sqrt
178  sinPhi = 1. - (tmp * tmp);
179  if (sinPhi < 0)
180  sinPhi = 0.;
181  sinPhi = 2. * tmp * sqrt(sinPhi);
182  cosPhi = 1. - 2. * (tmp * tmp);
183  } else {
184  double phi = s * theSinTheta * theRho;
185  sinPhi = sin(phi);
186  cosPhi = cos(phi);
187  }
188  return DirectionType(theStartingDir.x() * cosPhi - theStartingDir.y() * sinPhi,
189  theStartingDir.x() * sinPhi + theStartingDir.y() * cosPhi,
190  theStartingDir.z());
191  }
192 }
T y() const
Cartesian y coordinate.
T x() const
Cartesian x coordinate.
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
GlobalVector normalVector() const
Definition: Plane.h:41
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Basic3DVector unit() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:60
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
PropagationDirection
Definition: Plane.h:16
bool chooseSolution(const Vector2D &d1, const Vector2D &d2)
T z() const
Cartesian z coordinate.
T sqrt(T t)
Definition: SSEVec.h:19
DirectionType direction(double s) const override
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const std::string B
T perp() const
Magnitude of transverse component.
Basic3DVector< float > PositionType
the helix is passed to the constructor and does not appear in the interface
Basic3DVector< float > DirectionType
T y() const
Cartesian y coordinate.
std::pair< bool, double > pathLength(const Plane &plane) const
std::pair< bool, double > pathLength(const Plane &) override
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
bool samesign(T rh, T lh)
HelixBarrelPlaneCrossingByCircle(const PositionType &pos, const DirectionType &dir, double rho, PropagationDirection propDir=alongMomentum)
static constexpr float d1
tmp
align.sh
Definition: createJobs.py:716
T x() const
Definition: PV3DBase.h:59
PositionType position(double s) const override
T x() const
Cartesian x coordinate.