CMS 3D CMS Logo

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