CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HelixBarrelCylinderCrossing.cc
Go to the documentation of this file.
4 
6 
7 #include <iostream>
8 #include <cmath>
9 
10 #include <tuple>
11 
12 template <typename T>
13 inline T sqr(const T& t) {
14  return t * t;
15 }
16 
18  const GlobalVector& startingDir,
19  double rho,
20  PropagationDirection propDir,
21  const Cylinder& cyl,
22  Solution sol) {
23  // assumes the cylinder is centered at 0,0
24  double R = cyl.radius();
25 
26  // protect for zero curvature case
27  const double sraightLineCutoff = 1.e-7;
28  if (fabs(rho) * R < sraightLineCutoff && fabs(rho) * startingPos.perp() < sraightLineCutoff) {
29  // switch to straight line case
30  StraightLineCylinderCrossing slc(cyl.toLocal(startingPos), cyl.toLocal(startingDir), propDir);
31  std::pair<bool, double> pl = slc.pathLength(cyl);
32  if (pl.first) {
33  theSolExists = true;
34  theS = pl.second;
35  thePos = cyl.toGlobal(slc.position(theS));
36  theDir = startingDir;
37  } else
38  theSolExists = false;
39  return; // all needed data members have been set
40  }
41 
42  double R2cyl = R * R;
43  double pt = startingDir.perp();
44  Point center(startingPos.x() - startingDir.y() / (pt * rho), startingPos.y() + startingDir.x() / (pt * rho));
45  double p2 = startingPos.perp2();
46  bool solveForX;
47  double B, C, E, F;
48  if (fabs(center.x()) > fabs(center.y())) {
49  solveForX = false;
50  E = (R2cyl - p2) / (2. * center.x());
51  F = center.y() / center.x();
52  B = 2. * (startingPos.y() - F * startingPos.x() - E * F);
53  C = 2. * E * startingPos.x() + E * E + p2 - R2cyl;
54  } else {
55  solveForX = true;
56  E = (R2cyl - p2) / (2. * center.y());
57  F = center.x() / center.y();
58  B = 2. * (startingPos.x() - F * startingPos.y() - E * F);
59  C = 2. * E * startingPos.y() + E * E + p2 - R2cyl;
60  }
61 
62  RealQuadEquation eq(1 + F * F, B, C);
63  if (!eq.hasSolution) {
64  theSolExists = false;
65  return;
66  }
67 
68  Vector d1, d2;
69  ;
70  if (solveForX) {
71  d1 = Point(eq.first, E - F * eq.first);
72  d2 = Point(eq.second, E - F * eq.second);
73  } else {
74  d1 = Point(E - F * eq.first, eq.first);
75  d2 = Point(E - F * eq.second, eq.second);
76  }
77 
78  Vector theD;
79  int theActualDir;
80 
81  std::tie(theD, theActualDir) = chooseSolution(d1, d2, startingPos, startingDir, propDir);
82  if (!theSolExists)
83  return;
84 
85  float ipabs = 1.f / startingDir.mag();
86  float sinTheta = float(pt) * ipabs;
87  float cosTheta = startingDir.z() * ipabs;
88 
89  // -------
90 
91  auto dMag = theD.mag();
92  float tmp = 0.5f * float(dMag * rho);
93  if (std::abs(tmp) > 1.f)
94  tmp = std::copysign(1.f, tmp);
95  theS = theActualDir * 2.f * std::asin(tmp) / (float(rho) * sinTheta);
96  thePos = GlobalPoint(startingPos.x() + theD.x(), startingPos.y() + theD.y(), startingPos.z() + theS * cosTheta);
97 
98  if (sol == onlyPos)
99  return;
100 
101  if (theS < 0)
102  tmp = -tmp;
103  auto sinPhi = 2.f * tmp * sqrt(1.f - tmp * tmp);
104  auto cosPhi = 1.f - 2.f * tmp * tmp;
105  theDir = DirectionType(startingDir.x() * cosPhi - startingDir.y() * sinPhi,
106  startingDir.x() * sinPhi + startingDir.y() * cosPhi,
107  startingDir.z());
108 
109  if (sol != bothSol)
110  return;
111 
112  //----- BM
113  //double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
114  //double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
115 
116  int theActualDir1 = propDir == alongMomentum ? 1 : -1;
117  int theActualDir2 = propDir == alongMomentum ? 1 : -1;
118 
119  auto dMag1 = d1.mag();
120  auto tmp1 = 0.5f * dMag1 * float(rho);
121  if (std::abs(tmp1) > 1.f)
122  tmp1 = std::copysign(1.f, tmp1);
123  auto theS1 = theActualDir1 * 2.f * std::asin(tmp1) / (rho * sinTheta);
124  thePos1 = GlobalPoint(startingPos.x() + d1.x(), startingPos.y() + d1.y(), startingPos.z() + theS1 * cosTheta);
125 
126  auto dMag2 = d2.mag();
127  auto tmp2 = 0.5f * dMag2 * float(rho);
128  if (std::abs(tmp2) > 1.f)
129  tmp2 = std::copysign(1.f, tmp2);
130  auto theS2 = theActualDir2 * 2.f * std::asin(tmp2) / (float(rho) * sinTheta);
131  thePos2 = GlobalPoint(startingPos.x() + d2.x(), startingPos.y() + d2.y(), startingPos.z() + theS2 * cosTheta);
132 }
133 
134 std::pair<HelixBarrelCylinderCrossing::Vector, int> HelixBarrelCylinderCrossing::chooseSolution(
135  const Vector& d1,
136  const Vector& d2,
137  const PositionType& startingPos,
138  const DirectionType& startingDir,
139  PropagationDirection propDir) {
140  Vector theD;
141  int theActualDir;
142 
143  auto momProj1 = startingDir.x() * d1.x() + startingDir.y() * d1.y();
144  auto momProj2 = startingDir.x() * d2.x() + startingDir.y() * d2.y();
145 
146  if (propDir == anyDirection) {
147  theSolExists = true;
148  if (d1.mag2() < d2.mag2()) {
149  theD = d1;
150  theActualDir = (momProj1 > 0) ? 1 : -1;
151  } else {
152  theD = d2;
153  theActualDir = (momProj2 > 0) ? 1 : -1;
154  }
155  } else {
156  int propSign = propDir == alongMomentum ? 1 : -1;
157  if (momProj1 * momProj2 < 0) {
158  // if different signs return the positive one
159  theSolExists = true;
160  theD = (momProj1 * propSign > 0) ? d1 : d2;
161  theActualDir = propSign;
162  } else if (momProj1 * propSign > 0) {
163  // if both positive, return the shortest
164  theSolExists = true;
165  theD = (d1.mag2() < d2.mag2()) ? d1 : d2;
166  theActualDir = propSign;
167  } else
168  theSolExists = false;
169  }
170 
171  return std::pair<Vector, int>(theD, theActualDir);
172 }
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
HelixBarrelCylinderCrossing(const GlobalPoint &startingPos, const GlobalVector &startingDir, double rho, PropagationDirection propDir, const Cylinder &cyl, Solution sol=bothSol)
T perp() const
Definition: PV3DBase.h:69
const TString p2
Definition: fwPaths.cc:13
std::pair< bool, double > pathLength(const Cylinder &cyl) const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:60
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
T perp2() const
Definition: PV3DBase.h:68
PropagationDirection
int sqr(const T &t)
std::pair< Vector, int > chooseSolution(const Point &p1, const Point &p2, const PositionType &startingPos, const DirectionType &startingDir, PropagationDirection propDir)
T mag() const
Definition: PV3DBase.h:64
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:64
T sqrt(T t)
Definition: SSEVec.h:19
LocalPoint toLocal(const GlobalPoint &gp) const
T z() const
Definition: PV3DBase.h:61
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const std::string B
T y() const
Cartesian y coordinate.
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
static constexpr float d1
tmp
align.sh
Definition: createJobs.py:716
long double T
T x() const
Definition: PV3DBase.h:59
T x() const
Cartesian x coordinate.