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 template <typename T>
11 inline T sqr(const T& t) {return t*t;}
12 
15  const GlobalVector& startingDir,
16  double rho, PropagationDirection propDir,
17  const Cylinder& cyl)
18 {
19  // assumes the cylinder is centered at 0,0
20  double R = cyl.radius();
21 
22  // protect for zero curvature case
23  const double sraightLineCutoff = 1.e-7;
24  if (fabs(rho)*R < sraightLineCutoff &&
25  fabs(rho)*startingPos.perp() < sraightLineCutoff) {
26  // switch to straight line case
27  StraightLineCylinderCrossing slc( cyl.toLocal(startingPos),
28  cyl.toLocal(startingDir), propDir);
29  std::pair<bool,double> pl = slc.pathLength( cyl);
30  if (pl.first) {
31  theSolExists = true;
32  theS = pl.second;
33  thePos = cyl.toGlobal(slc.position(theS));
34  theDir = startingDir;
35  }
36  else theSolExists = false;
37  return; // all needed data members have been set
38  }
39 
40  double R2cyl = R*R;
41  double pt = startingDir.perp();
42  Point center( startingPos.x()-startingDir.y()/(pt*rho),
43  startingPos.y()+startingDir.x()/(pt*rho));
44  double p2 = startingPos.perp2();
45  bool solveForX;
46  double B, C, E, F;
47  if (fabs(center.x()) > fabs(center.y())) {
48  solveForX = false;
49  E = (R2cyl - p2) / (2.*center.x());
50  F = center.y()/center.x();
51  B = 2.*( startingPos.y() - F*startingPos.x() - E*F);
52  C = 2.*E*startingPos.x() + E*E + p2 - R2cyl;
53  }
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  if (solveForX) {
70  d1 = Point(eq.first, E-F*eq.first);
71  d2 = Point(eq.second, E-F*eq.second);
72  }
73  else {
74  d1 = Point( E-F*eq.first, eq.first);
75  d2 = Point( E-F*eq.second, eq.second);
76  }
77 
78  chooseSolution(d1, d2, startingPos, startingDir, propDir);
79  if (!theSolExists) return;
80 
81  double ipabs = 1./startingDir.mag();
82  double sinTheta = pt * ipabs;
83  double cosTheta = startingDir.z() * ipabs;
84 
85 
86  //----- BM
87  //double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
88  //double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
89 
90 
91  int theActualDir1 = propDir==alongMomentum ? 1 : -1;
92  int theActualDir2 = propDir==alongMomentum ? 1 : -1;
93 
94 
95  double dMag1 = d1.mag();
96  double tmp1 = 0.5 * dMag1 * rho;
97  if (std::abs(tmp1)>1.) tmp1 = ::copysign(1.,tmp1);
98  double theS1 = theActualDir1 * 2.* asin( tmp1 ) / (rho*sinTheta);
99  thePos1 = GlobalPoint( startingPos.x() + d1.x(),
100  startingPos.y() + d1.y(),
101  startingPos.z() + theS1*cosTheta);
102 
103 
104  double dMag2 = d2.mag();
105  double tmp2 = 0.5 * dMag2 * rho;
106  if (std::abs(tmp2)>1.) tmp2 = ::copysign(1.,tmp2);
107  double theS2 = theActualDir2 * 2.* asin( tmp2 ) / (rho*sinTheta);
108  thePos2 = GlobalPoint( startingPos.x() + d2.x(),
109  startingPos.y() + d2.y(),
110  startingPos.z() + theS2*cosTheta);
111  // -------
112 
113  double dMag = theD.mag();
114  double tmp = 0.5 * dMag * rho;
115  if (std::abs(tmp)>1.) tmp = ::copysign(1.,tmp);
116  theS = theActualDir * 2.* asin( tmp ) / (rho*sinTheta);
117  thePos = GlobalPoint( startingPos.x() + theD.x(),
118  startingPos.y() + theD.y(),
119  startingPos.z() + theS*cosTheta);
120 
121  if (theS < 0) tmp = -tmp;
122  double sinPhi = 2.*tmp*sqrt(1.-tmp*tmp);
123  double cosPhi = 1.-2.*tmp*tmp;
124  theDir = DirectionType(startingDir.x()*cosPhi-startingDir.y()*sinPhi,
125  startingDir.x()*sinPhi+startingDir.y()*cosPhi,
126  startingDir.z());
127 }
128 
130  const PositionType& startingPos,
131  const DirectionType& startingDir,
132  PropagationDirection propDir)
133 {
134  double momProj1 = startingDir.x()*d1.x() + startingDir.y()*d1.y();
135  double momProj2 = startingDir.x()*d2.x() + startingDir.y()*d2.y();
136 
137  if ( propDir == anyDirection ) {
138  theSolExists = true;
139  if (d1.mag2()<d2.mag2()) {
140  theD = d1;
141  theActualDir = (momProj1 > 0) ? 1 : -1;
142  }
143  else {
144  theD = d2;
145  theActualDir = (momProj2 > 0) ? 1 : -1;
146  }
147  }
148  else {
149  int propSign = propDir==alongMomentum ? 1 : -1;
150  if (momProj1*momProj2 < 0) {
151  // if different signs return the positive one
152  theSolExists = true;
153  theD = (momProj1*propSign > 0) ? d1 : d2;
154  theActualDir = propSign;
155  }
156  else if (momProj1*propSign > 0) {
157  // if both positive, return the shortest
158  theSolExists = true;
159  theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
160  theActualDir = propSign;
161  }
162  else theSolExists = false;
163  }
164 }
165 
void chooseSolution(const Point &p1, const Point &p2, const PositionType &startingPos, const DirectionType &startingDir, PropagationDirection propDir) dso_internal
T perp() const
Definition: PV3DBase.h:72
double_binary B
Definition: DDStreamer.cc:234
Definition: DDAxes.h:10
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
T mag() const
Definition: PV3DBase.h:67
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
HelixBarrelCylinderCrossing(const GlobalPoint &startingPos, const GlobalVector &startingDir, double rho, PropagationDirection propDir, const Cylinder &cyl)
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.