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