StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StHelix.cc
1 /***************************************************************************
2  *
3  * $Id: StHelix.cc,v 1.31 2015/07/20 17:30:51 jeromel Exp $
4  *
5  * Author: Thomas Ullrich, Sep 1997
6  ***************************************************************************
7  *
8  * Description: Parametrization of a helix
9  *
10  ***************************************************************************
11  *
12  * $Log: StHelix.cc,v $
13  * Revision 1.31 2015/07/20 17:30:51 jeromel
14  * Use std::isnan to satisfy C++11
15  *
16  * Revision 1.30 2015/04/22 18:02:01 ullrich
17  * Added two default argument to dca of two helices for HFT.
18  *
19  * Revision 1.29 2009/09/22 16:21:05 fine
20  * Silence the compilation warning
21  *
22  * Revision 1.28 2008/09/11 20:34:31 ullrich
23  * Fixed sign problem in seed calculation for helix-helix DCA.
24  *
25  * Revision 1.27 2007/08/20 23:25:39 perev
26  * BugFix #1016
27  *
28  * Revision 1.26 2005/10/13 23:15:13 genevb
29  * Save a few calculations
30  *
31  * Revision 1.25 2005/10/13 22:25:35 genevb
32  * pathLength to plane now finds nearest approach to intersection regardless of # of loops
33  *
34  * Revision 1.24 2005/07/06 18:49:56 fisyak
35  * Replace StHelixD, StLorentzVectorD,StLorentzVectorF,StMatrixD,StMatrixF,StPhysicalHelixD,StThreeVectorD,StThreeVectorF by templated version
36  *
37  * Revision 1.23 2004/12/02 02:51:16 ullrich
38  * Added option to pathLenghth() and distance() to search for
39  * DCA only within one period. Default stays as it was.
40  *
41  * Revision 1.22 2004/05/03 23:35:31 perev
42  * Possible non init WarnOff
43  *
44  * Revision 1.21 2004/01/27 02:49:48 perev
45  * Big value appropriate for float
46  *
47  * Revision 1.20 2003/12/22 18:59:36 perev
48  * remove test for only +ve pathLeng added before
49  *
50  * Revision 1.19 2003/12/18 17:27:02 perev
51  * Small bug fix in number of iters. i++ ==> i--
52  *
53  * Revision 1.18 2003/10/30 20:06:46 perev
54  * Check of quality added
55  *
56  * Revision 1.17 2003/10/19 20:17:00 perev
57  * Protection agains overfloat added into pathLength(StThreeVector,StThreeVector)
58  *
59  * Revision 1.16 2003/10/06 23:39:21 perev
60  * sqrt(-ve) == no solution. infinity returns
61  *
62  * Revision 1.15 2003/09/02 17:59:34 perev
63  * gcc 3.2 updates + WarnOff
64  *
65  * Revision 1.14 2003/06/26 17:15:56 ullrich
66  * Changed local variable name in pathLenght.
67  *
68  * Revision 1.13 2002/06/21 17:49:25 genevb
69  * Some minor speed improvements
70  *
71  * Revision 1.12 2002/04/24 02:40:25 ullrich
72  * Restored old format and lost CVS statements.
73  *
74  * Revision 1.11 2002/02/12 19:37:51 jeromel
75  * fix for Linux 7.2 (float.h). Took oportunity to doxygenize.
76  *
77  * Revision 1.10 2000/07/17 21:44:19 ullrich
78  * Fixed problem in pathLength(cyl_rad).
79  *
80  * Revision 1.9 2000/05/22 21:38:28 ullrich
81  * Add parenthesis to make Linux compiler happy.
82  *
83  * Revision 1.8 2000/05/22 21:11:21 ullrich
84  * In pathLength(StThreeVector&): Increased number of max iteration
85  * in Newton method from 10 to 100. Improved initial guess in case
86  * it is off by n period.
87  *
88  * Revision 1.7 2000/03/06 20:24:25 ullrich
89  * Parameter h for case B=0 correctly handled now.
90  *
91  * Revision 1.6 1999/12/22 15:14:39 ullrich
92  * Added analytical solution for dca between two helices
93  * in the case for B=0.
94  *
95  * Revision 1.5 1999/12/21 15:14:08 ullrich
96  * Modified to cope with new compiler version on Sun (CC5.0).
97  *
98  * Revision 1.4 1999/11/29 21:45:38 fisyak
99  * fix abs for HP
100  *
101  * Revision 1.3 1999/03/07 14:55:41 wenaus
102  * fix scope problem
103  *
104  * Revision 1.2 1999/03/02 19:47:35 ullrich
105  * Added method to find dca between two helices
106  *
107  * Revision 1.1 1999/01/30 03:59:02 fisyak
108  * Root Version of StarClassLibrary
109  *
110  * Revision 1.1 1999/01/23 00:29:15 ullrich
111  * Initial Revision
112  *
113  **************************************************************************/
114 #if !defined(ST_NO_NUMERIC_LIMITS)
115 # include <limits>
116 # if !defined(ST_NO_NAMESPACES)
117  using std::numeric_limits;
118 # endif
119 #endif
120 #define FOR_HELIX
121 #include <float.h>
122 #include "StHelix.hh"
123 #include "PhysicalConstants.h"
124 #ifdef __ROOT__
125 ClassImpT(StHelix,double);
126 #endif
127 const double StHelix::NoSolution = 3.e+33;
128 
129 StHelix::StHelix(){ /*noop*/ }
130 
131 StHelix::StHelix(double c, double d, double phase,
132  const StThreeVector<double>& o, int h)
133 {
134  setParameters(c, d, phase, o, h);
135 }
136 
137 StHelix::~StHelix() { /* noop */ };
138 
139 void StHelix::setParameters(double c, double dip, double phase,
140  const StThreeVector<double>& o, int h)
141 {
142  //
143  // The order in which the parameters are set is important
144  // since setCurvature might have to adjust the others.
145  //
146  mH = (h>=0) ? 1 : -1; // Default is: positive particle
147  // positive field
148  mOrigin = o;
149  setDipAngle(dip);
150  setPhase(phase);
151 
152  //
153  // Check for singularity and correct for negative curvature.
154  // May change mH and mPhase. Must therefore be set last.
155  //
156  setCurvature(c);
157 
158  //
159  // For the case B=0, h is ill defined. In the following we
160  // always assume h = +1. Since phase = psi - h * pi/2
161  // we have to correct the phase in case h = -1.
162  // This assumes that the user uses the same h for phase
163  // as the one he passed to the constructor.
164  //
165  if (mSingularity && mH == -1) {
166  mH = +1;
167  setPhase(mPhase-M_PI);
168  }
169 }
170 
171 void StHelix::setCurvature(double val)
172 {
173  if (val < 0) {
174  mCurvature = -val;
175  mH = -mH;
176  setPhase(mPhase+M_PI);
177  }
178  else
179  mCurvature = val;
180 
181 #ifndef ST_NO_NUMERIC_LIMITS
182  if (fabs(mCurvature) <= numeric_limits<double>::epsilon())
183 #else
184  if (fabs(mCurvature) <= static_cast<double>(0))
185 #endif
186  mSingularity = true; // straight line
187  else
188  mSingularity = false; // curved
189 }
190 
191 void StHelix::setPhase(double val)
192 {
193  mPhase = val;
194  mCosPhase = cos(mPhase);
195  mSinPhase = sin(mPhase);
196  if (fabs(mPhase) > M_PI)
197  mPhase = atan2(mSinPhase, mCosPhase); // force range [-pi,pi]
198 }
199 
200 void StHelix::setDipAngle(double val)
201 {
202  mDipAngle = val;
203  mCosDipAngle = cos(mDipAngle);
204  mSinDipAngle = sin(mDipAngle);
205 }
206 
207 double StHelix::xcenter() const
208 {
209  if (mSingularity)
210  return 0;
211  else
212  return mOrigin.x()-mCosPhase/mCurvature;
213 }
214 
215 double StHelix::ycenter() const
216 {
217  if (mSingularity)
218  return 0;
219  else
220  return mOrigin.y()-mSinPhase/mCurvature;
221 }
222 
224 {
225  double s;
226  double dx = p.x()-mOrigin.x();
227  double dy = p.y()-mOrigin.y();
228 
229  if (mSingularity) {
230  s = (dy*mCosPhase - dx*mSinPhase)/mCosDipAngle;
231  }
232  else {
233  s = atan2(dy*mCosPhase - dx*mSinPhase,
234  1/mCurvature + dx*mCosPhase+dy*mSinPhase)/
235  (mH*mCurvature*mCosDipAngle);
236  }
237  return s;
238 }
239 
240 double StHelix::distance(const StThreeVector<double>& p, bool scanPeriods) const
241 {
242  return abs(this->at(pathLength(p,scanPeriods))-p);
243 }
244 
245 double StHelix::pathLength(const StThreeVector<double>& p, bool scanPeriods) const
246 {
247  //
248  // Returns the path length at the distance of closest
249  // approach between the helix and point p.
250  // For the case of B=0 (straight line) the path length
251  // can be calculated analytically. For B>0 there is
252  // unfortunately no easy solution to the problem.
253  // Here we use the Newton method to find the root of the
254  // referring equation. The 'fudgePathLength' serves
255  // as a starting value.
256  //
257  double s;
258  double dx = p.x()-mOrigin.x();
259  double dy = p.y()-mOrigin.y();
260  double dz = p.z()-mOrigin.z();
261 
262  if (mSingularity) {
263  s = mCosDipAngle*(mCosPhase*dy-mSinPhase*dx) +
264  mSinDipAngle*dz;
265  }
266  else { //
267 #ifndef ST_NO_NAMESPACES
268  {
269  using namespace units;
270 #endif
271  const double MaxPrecisionNeeded = micrometer;
272  const int MaxIterations = 100;
273 
274  //
275  // The math is taken from Maple with C(expr,optimized) and
276  // some hand-editing. It is not very nice but efficient.
277  //
278  double t34 = mCurvature*mCosDipAngle*mCosDipAngle;
279  double t41 = mSinDipAngle*mSinDipAngle;
280  double t6, t7, t11, t12, t19;
281 
282  //
283  // Get a first guess by using the dca in 2D. Since
284  // in some extreme cases we might be off by n periods
285  // we add (subtract) periods in case we get any closer.
286  //
287  s = fudgePathLength(p);
288 
289  if (scanPeriods) {
290  double ds = period();
291  int j, jmin = 0;
292  double d, dmin = abs(at(s) - p);
293  for(j=1; j<MaxIterations; j++) {
294  if ((d = abs(at(s+j*ds) - p)) < dmin) {
295  dmin = d;
296  jmin = j;
297  }
298  else
299  break;
300  }
301  for(j=-1; -j<MaxIterations; j--) {
302  if ((d = abs(at(s+j*ds) - p)) < dmin) {
303  dmin = d;
304  jmin = j;
305  }
306  else
307  break;
308  }
309  if (jmin) s += jmin*ds;
310  }
311 
312  //
313  // Newtons method:
314  // Stops after MaxIterations iterations or if the required
315  // precision is obtained. Whatever comes first.
316  //
317  double sOld = s;
318  for (int i=0; i<MaxIterations; i++) {
319  t6 = mPhase+s*mH*mCurvature*mCosDipAngle;
320  t7 = cos(t6);
321  t11 = dx-(1/mCurvature)*(t7-mCosPhase);
322  t12 = sin(t6);
323  t19 = dy-(1/mCurvature)*(t12-mSinPhase);
324  s -= (t11*t12*mH*mCosDipAngle-t19*t7*mH*mCosDipAngle -
325  (dz-s*mSinDipAngle)*mSinDipAngle)/
326  (t12*t12*mCosDipAngle*mCosDipAngle+t11*t7*t34 +
327  t7*t7*mCosDipAngle*mCosDipAngle +
328  t19*t12*t34+t41);
329  if (fabs(sOld-s) < MaxPrecisionNeeded) break;
330  sOld = s;
331  }
332 #ifndef ST_NO_NAMESPACES
333  }
334 #endif
335  }
336  return s;
337 }
338 
339 double StHelix::period() const
340 {
341  if (mSingularity)
342 #ifndef ST_NO_NUMERIC_LIMITS
343  return numeric_limits<double>::max();
344 #else
345  return DBL_MAX;
346 #endif
347  else
348  return fabs(2*M_PI/(mH*mCurvature*mCosDipAngle));
349 }
350 
351 pair<double, double> StHelix::pathLength(double r) const
352 {
353  pair<double,double> value;
354  pair<double,double> VALUE(999999999.,999999999.);
355  //
356  // The math is taken from Maple with C(expr,optimized) and
357  // some hand-editing. It is not very nice but efficient.
358  // 'first' is the smallest of the two solutions (may be negative)
359  // 'second' is the other.
360  //
361  if (mSingularity) {
362  double t1 = mCosDipAngle*(mOrigin.x()*mSinPhase-mOrigin.y()*mCosPhase);
363  double t12 = mOrigin.y()*mOrigin.y();
364  double t13 = mCosPhase*mCosPhase;
365  double t15 = r*r;
366  double t16 = mOrigin.x()*mOrigin.x();
367  double t20 = -mCosDipAngle*mCosDipAngle*(2.0*mOrigin.x()*mSinPhase*mOrigin.y()*mCosPhase +
368  t12-t12*t13-t15+t13*t16);
369  if (t20<0.) return VALUE;
370  t20 = ::sqrt(t20);
371  value.first = (t1-t20)/(mCosDipAngle*mCosDipAngle);
372  value.second = (t1+t20)/(mCosDipAngle*mCosDipAngle);
373  }
374  else {
375  double t1 = mOrigin.y()*mCurvature;
376  double t2 = mSinPhase;
377  double t3 = mCurvature*mCurvature;
378  double t4 = mOrigin.y()*t2;
379  double t5 = mCosPhase;
380  double t6 = mOrigin.x()*t5;
381  double t8 = mOrigin.x()*mOrigin.x();
382  double t11 = mOrigin.y()*mOrigin.y();
383  double t14 = r*r;
384  double t15 = t14*mCurvature;
385  double t17 = t8*t8;
386  double t19 = t11*t11;
387  double t21 = t11*t3;
388  double t23 = t5*t5;
389  double t32 = t14*t14;
390  double t35 = t14*t3;
391  double t38 = 8.0*t4*t6 - 4.0*t1*t2*t8 - 4.0*t11*mCurvature*t6 +
392  4.0*t15*t6 + t17*t3 + t19*t3 + 2.0*t21*t8 + 4.0*t8*t23 -
393  4.0*t8*mOrigin.x()*mCurvature*t5 - 4.0*t11*t23 -
394  4.0*t11*mOrigin.y()*mCurvature*t2 + 4.0*t11 - 4.0*t14 +
395  t32*t3 + 4.0*t15*t4 - 2.0*t35*t11 - 2.0*t35*t8;
396  double t40 = (-t3*t38);
397  if (t40<0.) return VALUE;
398  t40 = ::sqrt(t40);
399 
400  double t43 = mOrigin.x()*mCurvature;
401  double t45 = 2.0*t5 - t35 + t21 + 2.0 - 2.0*t1*t2 -2.0*t43 - 2.0*t43*t5 + t8*t3;
402  double t46 = mH*mCosDipAngle*mCurvature;
403 
404  value.first = (-mPhase + 2.0*atan((-2.0*t1 + 2.0*t2 + t40)/t45))/t46;
405  value.second = -(mPhase + 2.0*atan((2.0*t1 - 2.0*t2 + t40)/t45))/t46;
406 
407  //
408  // Solution can be off by +/- one period, select smallest
409  //
410  double p = period();
411  if (! std::isnan(value.first)) {
412  if (fabs(value.first-p) < fabs(value.first)) value.first = value.first-p;
413  else if (fabs(value.first+p) < fabs(value.first)) value.first = value.first+p;
414  }
415  if (! std::isnan(value.second)) {
416  if (fabs(value.second-p) < fabs(value.second)) value.second = value.second-p;
417  else if (fabs(value.second+p) < fabs(value.second)) value.second = value.second+p;
418  }
419  }
420  if (value.first > value.second)
421  swap(value.first,value.second);
422  return(value);
423 }
424 
425 pair<double, double> StHelix::pathLength(double r, double x, double y)
426 {
427  double x0 = mOrigin.x();
428  double y0 = mOrigin.y();
429  mOrigin.setX(x0-x);
430  mOrigin.setY(y0-y);
431  pair<double, double> result = this->pathLength(r);
432  mOrigin.setX(x0);
433  mOrigin.setY(y0);
434  return result;
435 }
436 
438  const StThreeVector<double>& n) const
439 {
440  //
441  // Vector 'r' defines the position of the center and
442  // vector 'n' the normal vector of the plane.
443  // For a straight line there is a simple analytical
444  // solution. For curvatures > 0 the root is determined
445  // by Newton method. In case no valid s can be found
446  // the max. largest value for s is returned.
447  //
448  double s;
449 
450  if (mSingularity) {
451  double t = n.z()*mSinDipAngle +
452  n.y()*mCosDipAngle*mCosPhase -
453  n.x()*mCosDipAngle*mSinPhase;
454  if (t == 0)
455  s = NoSolution;
456  else
457  s = ((r - mOrigin)*n)/t;
458  }
459  else {
460  const double MaxPrecisionNeeded = micrometer;
461  const int MaxIterations = 20;
462 
463  double A = mCurvature*((mOrigin - r)*n) -
464  n.x()*mCosPhase -
465  n.y()*mSinPhase;
466  double t = mH*mCurvature*mCosDipAngle;
467  double u = n.z()*mCurvature*mSinDipAngle;
468 
469  double a, f, fp;
470  double sOld = s = 0;
471  double shiftOld = 0;
472  double shift;
473 // (cos(angMax)-1)/angMax = 0.1
474  const double angMax = 0.21;
475  double deltas = fabs(angMax/(mCurvature*mCosDipAngle));
476 // dampingFactor = exp(-0.5);
477 // double dampingFactor = 0.60653;
478  int i;
479 
480  for (i=0; i<MaxIterations; i++) {
481  a = t*s+mPhase;
482  double sina = sin(a);
483  double cosa = cos(a);
484  f = A +
485  n.x()*cosa +
486  n.y()*sina +
487  u*s;
488  fp = -n.x()*sina*t +
489  n.y()*cosa*t +
490  u;
491  if ( fabs(fp)*deltas <= fabs(f) ) { //too big step
492  int sgn = 1;
493  if (fp<0.) sgn = -sgn;
494  if (f <0.) sgn = -sgn;
495  shift = sgn*deltas;
496  if (shift<0) shift*=0.9; // don't get stuck shifting +/-deltas
497  } else {
498  shift = f/fp;
499  }
500  s -= shift;
501  shiftOld = shift;
502  if (fabs(sOld-s) < MaxPrecisionNeeded) break;
503  sOld = s;
504  }
505  if (i == MaxIterations) return NoSolution;
506  }
507  return s;
508 }
509 
510 pair<double, double>
511 StHelix::pathLengths(const StHelix& h, double minStepSize, double minRange) const
512 {
513  //
514  // Cannot handle case where one is a helix
515  // and the other one is a straight line.
516  //
517  if (mSingularity != h.mSingularity)
518  return pair<double, double>(NoSolution, NoSolution);
519 
520  double s1, s2;
521 
522  if (mSingularity) {
523  //
524  // Analytic solution
525  //
526  StThreeVector<double> dv = h.mOrigin - mOrigin;
527  StThreeVector<double> a(-mCosDipAngle*mSinPhase,
528  mCosDipAngle*mCosPhase,
529  mSinDipAngle);
530  StThreeVector<double> b(-h.mCosDipAngle*h.mSinPhase,
531  h.mCosDipAngle*h.mCosPhase,
532  h.mSinDipAngle);
533  double ab = a*b;
534  double g = dv*a;
535  double k = dv*b;
536  s2 = (k-ab*g)/(ab*ab-1.);
537  s1 = g+s2*ab;
538  return pair<double, double>(s1, s2);
539  }
540  else {
541  //
542  // First step: get dca in the xy-plane as start value
543  //
544  double dx = h.xcenter() - xcenter();
545  double dy = h.ycenter() - ycenter();
546  double dd = ::sqrt(dx*dx + dy*dy);
547  double r1 = 1/curvature();
548  double r2 = 1/h.curvature();
549 
550  double cosAlpha = (r1*r1 + dd*dd - r2*r2)/(2*r1*dd);
551 
552  double s;
553  double x, y;
554  if (fabs(cosAlpha) < 1) { // two solutions
555  double sinAlpha = sin(acos(cosAlpha));
556  x = xcenter() + r1*(cosAlpha*dx - sinAlpha*dy)/dd;
557  y = ycenter() + r1*(sinAlpha*dx + cosAlpha*dy)/dd;
558  s = pathLength(x, y);
559  x = xcenter() + r1*(cosAlpha*dx + sinAlpha*dy)/dd;
560  y = ycenter() + r1*(cosAlpha*dy - sinAlpha*dx)/dd;
561  double a = pathLength(x, y);
562  if (h.distance(at(a)) < h.distance(at(s))) s = a;
563  }
564  else { // no intersection (or exactly one)
565  int rsign = ((r2-r1) > dd ? -1 : 1); // set -1 when *this* helix is
566  // completely contained in the other
567  x = xcenter() + rsign*r1*dx/dd;
568  y = ycenter() + rsign*r1*dy/dd;
569  s = pathLength(x, y);
570  }
571 
572  //
573  // Second step: scan in decreasing intervals around seed 's'
574  // minRange and minStepSize are passed as arguments to the method.
575  // They have default values defined in the header file.
576  //
577  double dmin = h.distance(at(s));
578  double range = max(2*dmin, minRange);
579  double ds = range/10;
580  double slast=-999999, ss, d;
581  s1 = s - range/2.;
582  s2 = s + range/2.;
583 
584  while (ds > minStepSize) {
585  for (ss=s1; ss<s2+ds; ss+=ds) {
586  d = h.distance(at(ss));
587  if (d < dmin) {
588  dmin = d;
589  s = ss;
590  }
591  slast = ss;
592  }
593  //
594  // In the rare cases where the minimum is at the
595  // the border of the current range we shift the range
596  // and start all over, i.e we do not decrease 'ds'.
597  // Else we decrease the search intervall around the
598  // current minimum and redo the scan in smaller steps.
599  //
600  if (s == s1) {
601  d = 0.8*(s2-s1);
602  s1 -= d;
603  s2 -= d;
604  }
605  else if (s == slast) {
606  d = 0.8*(s2-s1);
607  s1 += d;
608  s2 += d;
609  }
610  else {
611  s1 = s-ds;
612  s2 = s+ds;
613  ds /= 10;
614  }
615  }
616  return pair<double, double>(s, h.pathLength(at(s)));
617  }
618 }
619 
620 
621 void StHelix::moveOrigin(double s)
622 {
623  if (mSingularity)
624  mOrigin = at(s);
625  else {
626  StThreeVector<double> newOrigin = at(s);
627  double newPhase = atan2(newOrigin.y() - ycenter(),
628  newOrigin.x() - xcenter());
629  mOrigin = newOrigin;
630  setPhase(newPhase);
631  }
632 }
633 
634 int operator== (const StHelix& a, const StHelix& b)
635 {
636  //
637  // Checks for numerical identity only !
638  //
639  return (a.origin() == b.origin() &&
640  a.dipAngle() == b.dipAngle() &&
641  a.curvature() == b.curvature() &&
642  a.phase() == b.phase() &&
643  a.h() == b.h());
644 }
645 
646 int operator!= (const StHelix& a, const StHelix& b) {return !(a == b);}
647 
648 ostream& operator<<(ostream& os, const StHelix& h)
649 {
650  return os << '('
651  << "curvature = " << h.curvature() << ", "
652  << "dip angle = " << h.dipAngle() << ", "
653  << "phase = " << h.phase() << ", "
654  << "h = " << h.h() << ", "
655  << "origin = " << h.origin() << ')';
656 }
657 
658 
659 
660 
void setParameters(double c, double dip, double phase, const StThreeVector< double > &o, int h)
starting point
Definition: StHelix.cc:139
int h() const
y-center of circle in xy-plane
Definition: StHelix.hh:174
pair< double, double > pathLengths(const StHelix &, double minStepSize=10 *micrometer, double minRange=10 *centimeter) const
path lengths at dca between two helices
Definition: StHelix.cc:511
double x(double s) const
coordinates of helix at point s
Definition: StHelix.hh:182
double distance(const StThreeVector< double > &p, bool scanPeriods=true) const
minimal distance between point and helix
Definition: StHelix.cc:240
double fudgePathLength(const StThreeVector< double > &) const
value of S where distance in x-y plane is minimal
Definition: StHelix.cc:223
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
double ycenter() const
x-center of circle in xy-plane
Definition: StHelix.cc:215
const StThreeVector< double > & origin() const
-sign(q*B);
Definition: StHelix.hh:224
void setPhase(double)
performs also various checks
Definition: StHelix.cc:191
StHelix(double c, double dip, double phase, const StThreeVector< double > &o, int h=-1)
curvature, dip angle, phase, origin, h
Definition: StHelix.cc:131
virtual void moveOrigin(double s)
move the origin along the helix to s which becomes then s=0
Definition: StHelix.cc:621
double period() const
returns period length of helix
Definition: StHelix.cc:339
double xcenter() const
aziumth in xy-plane measured from ring center
Definition: StHelix.cc:207
double phase() const
1/R in xy-plane
Definition: StHelix.hh:180