CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HelixBarrelPlaneCrossingByCircle.cc
Go to the documentation of this file.
6 
7 #include <algorithm>
8 #include <cfloat>
9 
10 HelixBarrelPlaneCrossingByCircle::
11 HelixBarrelPlaneCrossingByCircle( const PositionType& pos,
12  const DirectionType& dir,
13  double rho, PropagationDirection propDir) :
14  theStartingPos( pos), theStartingDir(dir),
15  theRho(rho), thePropDir(propDir) { init();}
16 
17 HelixBarrelPlaneCrossingByCircle::
18 HelixBarrelPlaneCrossingByCircle( const GlobalPoint& pos,
19  const GlobalVector& dir,
20  double rho, PropagationDirection propDir) :
21  theStartingPos( pos.basicVector()), theStartingDir(dir.basicVector()),
22  theRho(rho), thePropDir(propDir) { init();}
23 
25 {
26  double pabsI = 1./theStartingDir.mag();
27  double pt = theStartingDir.perp();
28  theCosTheta = theStartingDir.z()*pabsI;
29  theSinTheta = pt*pabsI;
30 
31  // protect for zero curvature case
32  const double sraightLineCutoff = 1.e-7;
33  if (fabs(theRho) < sraightLineCutoff &&
34  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);
41  theXCenter = theStartingPos.x() - theStartingDir.y()*o;
42  theYCenter = theStartingPos.y() + theStartingDir.x()*o;
43  useStraightLine = false;
44  }
45 }
46 
47 std::pair<bool,double>
48 HelixBarrelPlaneCrossingByCircle::pathLength( const Plane& plane)
49 {
50  typedef std::pair<bool,double> ResultType;
51 
52  if(useStraightLine){
53  // switch to straight line case
54  StraightLinePlaneCrossing slc( theStartingPos,
55  theStartingDir, thePropDir);
56  return slc.pathLength( plane);
57  }
58 
59 
60  // plane parameters
61  GlobalVector n = plane.normalVector();
62  double distToPlane = -plane.localZ( GlobalPoint( theStartingPos));
63  // double distToPlane = (plane.position().x()-theStartingPos.x()) * n.x() +
64  // (plane.position().y()-theStartingPos.y()) * n.y();
65  double nx = n.x(); // convert to double
66  double ny = n.y(); // convert to double
67  double distCx = theStartingPos.x() - theXCenter;
68  double distCy = theStartingPos.y() - theYCenter;
69 
70  double nfac, dfac;
71  double A, B, C;
72  bool solveForX;
73  if (fabs(nx) > fabs(ny)) {
74  solveForX = false;
75  nfac = ny/nx;
76  dfac = distToPlane/nx;
77  B = distCy - nfac*distCx; // only part of B, may have large cancelation
78  C = (2.*distCx + dfac)*dfac;
79  }
80  else {
81  solveForX = true;
82  nfac = nx/ny;
83  dfac = distToPlane/ny;
84  B = distCx - nfac*distCy; // only part of B, may have large cancelation
85  C = (2.*distCy + dfac)*dfac;
86  }
87  B -= nfac*dfac; B *= 2; // the rest of B (normally small)
88  A = 1.+ nfac*nfac;
89 
90  double dx1, dx2, dy1, dy2;
91  RealQuadEquation equation(A,B,C);
92  if (!equation.hasSolution) return ResultType( false, 0.);
93  else {
94  if (solveForX) {
95  dx1 = equation.first;
96  dx2 = equation.second;
97  dy1 = dfac - nfac*dx1;
98  dy2 = dfac - nfac*dx2;
99  }
100  else {
101  dy1 = equation.first;
102  dy2 = equation.second;
103  dx1 = dfac - nfac*dy1;
104  dx2 = dfac - nfac*dy2;
105  }
106  }
107  bool solved = chooseSolution( Vector2D(dx1, dy1), Vector2D(dx2, dy2));
108  if (solved) {
109  theDmag = theD.mag();
110  // protect asin (taking some safety margin)
111  double sinAlpha = 0.5*theDmag*theRho;
112  if ( sinAlpha>(1.-10*DBL_EPSILON) ) sinAlpha = 1.-10*DBL_EPSILON;
113  else if ( sinAlpha<-(1.-10*DBL_EPSILON) ) sinAlpha = -(1.-10*DBL_EPSILON);
114  theS = theActualDir*2./(theRho*theSinTheta) * asin( sinAlpha);
115  return ResultType( true, theS);
116  }
117  else return ResultType( false, 0.);
118 }
119 
120 bool
121 HelixBarrelPlaneCrossingByCircle::chooseSolution( const Vector2D& d1,
122  const Vector2D& d2)
123 {
124  bool solved;
125  double momProj1 = theStartingDir.x()*d1.x() + theStartingDir.y()*d1.y();
126  double momProj2 = theStartingDir.x()*d2.x() + theStartingDir.y()*d2.y();
127 
128  if ( thePropDir == anyDirection ) {
129  solved = true;
130  if (d1.mag2()<d2.mag2()) {
131  theD = d1;
132  theActualDir = (momProj1 > 0) ? 1. : -1.;
133  }
134  else {
135  theD = d2;
136  theActualDir = (momProj2 > 0) ? 1. : -1.;
137  }
138 
139  }
140  else {
141  double propSign = thePropDir==alongMomentum ? 1 : -1;
142  if (!mathSSE::samesign(momProj1,momProj2)) {
143  // if different signs return the positive one
144  solved = true;
145  theD = mathSSE::samesign(momProj1,propSign) ? d1 : d2;
146  theActualDir = propSign;
147  }
148  else if (mathSSE::samesign(momProj1,propSign)) {
149  // if both positive, return the shortest
150  solved = true;
151  theD = (d1.mag2()<d2.mag2()) ? d1 : d2;
152  theActualDir = propSign;
153  }
154  else solved = false;
155  }
156  return solved;
157 }
158 
161 {
162  if(useStraightLine){
163  return PositionType(theStartingPos+s*theStartingDir.unit());
164  }else{
165  if ( s==theS) {
166  return PositionType( theStartingPos.x() + theD.x(),
167  theStartingPos.y() + theD.y(),
168  theStartingPos.z() + s*theCosTheta);
169  }
170  else {
171  double phi = s*theSinTheta*theRho;
172  double x1Shift = theStartingPos.x() - theXCenter;
173  double y1Shift = theStartingPos.y() - theYCenter;
174 
175  return PositionType(x1Shift*cos(phi)-y1Shift*sin(phi) + theXCenter,
176  x1Shift*sin(phi)+y1Shift*cos(phi) + theYCenter,
177  theStartingPos.z() + s*theCosTheta);
178  }
179  }
180 }
181 
183 HelixBarrelPlaneCrossingByCircle::direction( double s) const
184 {
185  if(useStraightLine){return theStartingDir;}
186  else{
187  double sinPhi, cosPhi;
188  if ( s==theS) {
189  double tmp = 0.5*theDmag*theRho;
190  if (s < 0) tmp = -tmp;
191  // protect sqrt
192  sinPhi = 1.-(tmp*tmp);
193  if ( sinPhi<0 ) sinPhi = 0.;
194  sinPhi = 2.*tmp*sqrt(sinPhi);
195  cosPhi = 1.-2.*(tmp*tmp);
196  }
197  else {
198  double phi = s*theSinTheta*theRho;
199  sinPhi = sin(phi);
200  cosPhi = cos(phi);
201  }
202  return DirectionType(theStartingDir.x()*cosPhi-theStartingDir.y()*sinPhi,
203  theStartingDir.x()*sinPhi+theStartingDir.y()*cosPhi,
204  theStartingDir.z());
205  }
206 }
double_binary B
Definition: DDStreamer.cc:234
GlobalVector normalVector() const
Definition: Plane.h:45
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Definition: DDAxes.h:10
int init
Definition: HydjetWrapper.h:62
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:49
PropagationDirection
Definition: Plane.h:17
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
Point3DBase< Scalar, GlobalTag > PositionType
Definition: Definitions.h:30
T sqrt(T t)
Definition: SSEVec.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
bool samesign(T rh, T lh)
dbl *** dir
Definition: mlp_gen.cc:35
T x() const
Definition: PV3DBase.h:62
Definition: DDAxes.h:10