ROOT logo
///////////////////////////////////////////////////////////////////////////
//                                                                       //
// AliFmHelix: a helper helix class                                      //
// Includes all the operations and specifications of the helix. Can be   //
// used to determine path lengths, distance of closest approach etc.     //
//                                                                       //
///////////////////////////////////////////////////////////////////////////
#if !defined(ST_NO_NUMERIC_LIMITS)
#    include <limits>
#    if !defined(ST_NO_NAMESPACES)
using std::numeric_limits;
#    endif
#endif
#define FOR_HELIX
#include <float.h>
#include <assert.h>

#include "AliFmHelix.h"
#include "PhysicalConstants.h" 
#include "SystemOfUnits.h"
#ifdef __ROOT__
ClassImpT(AliFmHelix,double);
#endif

#ifdef WIN32
#include "gcc2vs.h"
#endif

#include <iostream>
#include <fstream>
using namespace std;

const double AliFmHelix::fgkNoSolution = 3.e+33;

AliFmHelix::AliFmHelix() :
  fSingularity(0),
  fOrigin(0,0,0),
  fDipAngle(0),
  fCurvature(0),
  fPhase(0),
  fH(0),
  fCosDipAngle(0),
  fSinDipAngle(0),
  fCosPhase(0),
  fSinPhase(0)
{
  //Default constructor
/*noop*/ 
}

AliFmHelix::AliFmHelix(double c, double d, double phase,
		       const AliFmThreeVector<double>& o, int h) :
  fSingularity(0),
  fOrigin(0,0,0),
  fDipAngle(0),
  fCurvature(0),
  fPhase(0),
  fH(0),
  fCosDipAngle(0),
  fSinDipAngle(0),
  fCosPhase(0),
  fSinPhase(0)
{
  // Constructor with helix parameters
  SetParameters(c, d, phase, o, h);
}

AliFmHelix::~AliFmHelix() { 
  // Default destructor
/* noop */ 
}

void AliFmHelix::SetParameters(double c, double dip, double phase,
			       const AliFmThreeVector<double>& o, int h)
{
	//
	//  The order in which the parameters are set is important
	//  since setCurvature might have to adjust the others.
	//
	fH = (h>=0) ? 1 : -1;    // Default is: positive particle
	//             positive field
	fOrigin   = o;
	SetDipAngle(dip);
	SetPhase(phase);

	//
	// Check for singularity and correct for negative curvature.           
	// May change mH and mPhase. Must therefore be set last.
	//
	SetCurvature(c);

	//
	// For the case B=0, h is ill defined. In the following we
	// always assume h = +1. Since phase = psi - h * pi/2
	// we have to correct the phase in case h = -1.
	// This assumes that the user uses the same h for phase
	// as the one he passed to the constructor.
	//
	if (fSingularity && fH == -1) {
		fH = +1;
		SetPhase(fPhase-M_PI);
	}
}

void AliFmHelix::SetCurvature(double val)
{
  // Set helix curvature
	if (val < 0) {
		fCurvature = -val;
		fH = -fH;
		SetPhase(fPhase+M_PI);
	}
	else
		fCurvature = val;

#ifndef ST_NO_NUMERIC_LIMITS
	if (fabs(fCurvature) <= numeric_limits<double>::epsilon())
#else
	if (fabs(fCurvature) <= static_cast<double>(0))
#endif    
		fSingularity = true;			// straight line
	else
		fSingularity = false;            	// curved
}

void AliFmHelix::SetPhase(double val)
{
  // Set helix phase
	fPhase       = val;
	fCosPhase    = cos(fPhase);
	fSinPhase    = sin(fPhase);
	if (fabs(fPhase) > M_PI)
		fPhase = atan2(fSinPhase, fCosPhase);  // force range [-pi,pi]
}

void AliFmHelix::SetDipAngle(double val)
{
  // Set helix dip angle
	fDipAngle    = val;
	fCosDipAngle = cos(fDipAngle);
	fSinDipAngle = sin(fDipAngle);
}

double AliFmHelix::XCenter() const
{
  // Set helix center in X
	if (fSingularity)
		return 0;
	else
		return fOrigin.x()-fCosPhase/fCurvature;
}

double AliFmHelix::YCenter() const
{
  // Set helix center in Y
	if (fSingularity)
		return 0;
	else
		return fOrigin.y()-fSinPhase/fCurvature;
}

double AliFmHelix::FudgePathLength(const AliFmThreeVector<double>& p) const
{
  // Path length
	double s;
	double dx = p.x()-fOrigin.x();
	double dy = p.y()-fOrigin.y();

	if (fSingularity) {
		s = (dy*fCosPhase - dx*fSinPhase)/fCosDipAngle;
	}
	else {
		s = atan2(dy*fCosPhase - dx*fSinPhase,
			1/fCurvature + dx*fCosPhase+dy*fSinPhase)/
			(fH*fCurvature*fCosDipAngle);
	}
	return s;
}

double AliFmHelix::Distance(const AliFmThreeVector<double>& p, bool scanPeriods) const
{
  // calculate distance between origin an p along the helix
	return abs(this->At(PathLength(p,scanPeriods))-p);
}

double AliFmHelix::PathLength(const AliFmThreeVector<double>& p, bool scanPeriods) const 
{
	//
	//  Returns the path length at the distance of closest 
	//  approach between the helix and point p. 
	//  For the case of B=0 (straight line) the path length
	//  can be calculated analytically. For B>0 there is
	//  unfortunately no easy solution to the problem.
	//  Here we use the Newton method to find the root of the
	//  referring equation. The 'fudgePathLength' serves
	//  as a starting value.
	//
	double s;
	double dx = p.x()-fOrigin.x();
	double dy = p.y()-fOrigin.y();
	double dz = p.z()-fOrigin.z();

	if (fSingularity) {
		s = fCosDipAngle*(fCosPhase*dy-fSinPhase*dx) +
			fSinDipAngle*dz;
	}
	else { //
#ifndef ST_NO_NAMESPACES
		{
			using namespace units;
#endif
			const double ktMaxPrecisionNeeded = micrometer;
			const int    ktMaxIterations      = 100;

			//
			// The math is taken from Maple with C(expr,optimized) and
			// some hand-editing. It is not very nice but efficient.
			//
			double t34 = fCurvature*fCosDipAngle*fCosDipAngle;
			double t41 = fSinDipAngle*fSinDipAngle;
			double t6, t7, t11, t12, t19;

			//
			// Get a first guess by using the dca in 2D. Since
			// in some extreme cases we might be off by n periods
			// we add (subtract) periods in case we get any closer.
			// 
			s = FudgePathLength(p);

			if (scanPeriods) {
				double ds = Period();
				int    j, jmin = 0;
				double d, dmin = abs(At(s) - p);
				for(j=1; j<ktMaxIterations; j++) {
					if ((d = abs(At(s+j*ds) - p)) < dmin) {
						dmin = d;
						jmin = j;
					}
					else
						break;
				}
				for(j=-1; -j<ktMaxIterations; j--) {
					if ((d = abs(At(s+j*ds) - p)) < dmin) {
						dmin = d;
						jmin = j;
					}
					else
						break;
				}
				if (jmin) s += jmin*ds;
			}

			//
			// Newtons method:
			// Stops after ktMaxIterations iterations or if the required
			// precision is obtained. Whatever comes first.
			//
			double sOld = s;
			for (int i=0; i<ktMaxIterations; i++) {
				t6  = fPhase+s*fH*fCurvature*fCosDipAngle;
				t7  = cos(t6);
				t11 = dx-(1/fCurvature)*(t7-fCosPhase);
				t12 = sin(t6);
				t19 = dy-(1/fCurvature)*(t12-fSinPhase);
				s  -= (t11*t12*fH*fCosDipAngle-t19*t7*fH*fCosDipAngle -
					(dz-s*fSinDipAngle)*fSinDipAngle)/
					(t12*t12*fCosDipAngle*fCosDipAngle+t11*t7*t34 +
					t7*t7*fCosDipAngle*fCosDipAngle +
					t19*t12*t34+t41);
				if (fabs(sOld-s) < ktMaxPrecisionNeeded) break;
				sOld = s;
			}
#ifndef ST_NO_NAMESPACES
		}
#endif
	}
	return s;
}

double AliFmHelix::Period() const
{
  // period
	if (fSingularity)
#ifndef ST_NO_NUMERIC_LIMITS
		return numeric_limits<double>::max();
#else
		return DBL_MAX;
#endif    
	else	
		return fabs(2*M_PI/(fH*fCurvature*fCosDipAngle)); 
}

pair<double, double> AliFmHelix::PathLength(double r) const
{
	//
	// The math is taken from Maple with C(expr,optimized) and
	// some hand-editing. It is not very nice but efficient.
	// 'first' is the smallest of the two solutions (may be negative)
	// 'second' is the other.
	//
	pair<double,double> tvalue;
	pair<double,double> tVALUE(999999999.,999999999.);
	if (fSingularity) {
		double t1 = fCosDipAngle*(fOrigin.x()*fSinPhase-fOrigin.y()*fCosPhase);
		double t12 = fOrigin.y()*fOrigin.y();
		double t13 = fCosPhase*fCosPhase;
		double t15 = r*r;
		double t16 = fOrigin.x()*fOrigin.x();
		double t20 = -fCosDipAngle*fCosDipAngle*(2.0*fOrigin.x()*fSinPhase*fOrigin.y()*fCosPhase +
			t12-t12*t13-t15+t13*t16);
		if (t20<0.) return tVALUE;
		t20 = ::sqrt(t20);
		tvalue.first  = (t1-t20)/(fCosDipAngle*fCosDipAngle);
		tvalue.second = (t1+t20)/(fCosDipAngle*fCosDipAngle);
	}
	else {
		double t1 = fOrigin.y()*fCurvature;
		double t2 = fSinPhase;
		double t3 = fCurvature*fCurvature;
		double t4 = fOrigin.y()*t2;
		double t5 = fCosPhase;
		double t6 = fOrigin.x()*t5;
		double t8 = fOrigin.x()*fOrigin.x();
		double t11 = fOrigin.y()*fOrigin.y();
		double t14 = r*r;
		double t15 = t14*fCurvature;
		double t17 = t8*t8;
		double t19 = t11*t11;
		double t21 = t11*t3;
		double t23 = t5*t5;
		double t32 = t14*t14;
		double t35 = t14*t3;
		double t38 = 8.0*t4*t6 - 4.0*t1*t2*t8 - 4.0*t11*fCurvature*t6 +
			4.0*t15*t6 + t17*t3 + t19*t3 + 2.0*t21*t8 + 4.0*t8*t23 -
			4.0*t8*fOrigin.x()*fCurvature*t5 - 4.0*t11*t23 -
			4.0*t11*fOrigin.y()*fCurvature*t2 + 4.0*t11 - 4.0*t14 +
			t32*t3 + 4.0*t15*t4 - 2.0*t35*t11 - 2.0*t35*t8;
		double t40 = (-t3*t38);
		if (t40<0.) return tVALUE;
		t40 = ::sqrt(t40);

		double t43 = fOrigin.x()*fCurvature;
		double t45 = 2.0*t5 - t35 + t21 + 2.0 - 2.0*t1*t2 -2.0*t43 - 2.0*t43*t5 + t8*t3;
		double t46 = fH*fCosDipAngle*fCurvature;

		tvalue.first = (-fPhase + 2.0*atan((-2.0*t1 + 2.0*t2 + t40)/t45))/t46;
		tvalue.second = -(fPhase + 2.0*atan((2.0*t1 - 2.0*t2 + t40)/t45))/t46;

		//
		//   Solution can be off by +/- one Period, select smallest
		//
		double p = Period();
		//	malisa deletes "isnan" check 22apr2006	if (!isnan(value.first)) {
		if (fabs(tvalue.first-p) < fabs(tvalue.first)) tvalue.first = tvalue.first-p;
		else if (fabs(tvalue.first+p) < fabs(tvalue.first)) tvalue.first = tvalue.first+p;
		//	malisa	}
		//	malisa deletes "isnan" check 22apr2006		if (!isnan(tvalue.second)) {
		if (fabs(tvalue.second-p) < fabs(tvalue.second)) tvalue.second = tvalue.second-p;
		else if (fabs(tvalue.second+p) < fabs(tvalue.second)) tvalue.second = tvalue.second+p;
		//      malisa }
	}
	if (tvalue.first > tvalue.second)
		swap(tvalue.first,tvalue.second);
	return(tvalue);
}

pair<double, double> AliFmHelix::PathLength(double r, double x, double y, bool /* scanPeriods */)
{
  // path length
	double x0 = fOrigin.x();
	double y0 = fOrigin.y();
	fOrigin.SetX(x0-x);
	fOrigin.SetY(y0-y);
	pair<double, double> result = this->PathLength(r);
	fOrigin.SetX(x0);
	fOrigin.SetY(y0);
	return result;  
}

double AliFmHelix::PathLength(const AliFmThreeVector<double>& r,
						   const AliFmThreeVector<double>& n) const
{
	//
	// Vector 'r' defines the position of the center and
	// vector 'n' the normal vector of the plane.
	// For a straight line there is a simple analytical
	// solution. For curvatures > 0 the root is determined
	// by Newton method. In case no valid s can be found
	// the max. largest value for s is returned.
	//
	double s;

	if (fSingularity) {
		double t = n.z()*fSinDipAngle +
			n.y()*fCosDipAngle*fCosPhase -
			n.x()*fCosDipAngle*fSinPhase;
		if (t == 0)
			s = fgkNoSolution;
		else
			s = ((r - fOrigin)*n)/t;
	}
	else {
		const double ktMaxPrecisionNeeded = micrometer;
		const int    ktMaxIterations      = 20;

		double tA = fCurvature*((fOrigin - r)*n) -
			n.x()*fCosPhase - 
			n.y()*fSinPhase;
		double t = fH*fCurvature*fCosDipAngle;
		double u = n.z()*fCurvature*fSinDipAngle;

		double a, f, fp;
		double sOld = s = 0;  
		double shiftOld = 0;
		double shift;
		//		(cos(kangMax)-1)/kangMax = 0.1
		const double kangMax = 0.21;
		double deltas = fabs(kangMax/(fCurvature*fCosDipAngle));
		//              dampingFactor = exp(-0.5);
		double dampingFactor = 0.60653;
		int i;

		for (i=0; i<ktMaxIterations; i++) {
			a  = t*s+fPhase;
			double sina = sin(a);
			double cosa = cos(a);
			f  = tA +
				n.x()*cosa +
				n.y()*sina +
				u*s;
			fp = -n.x()*sina*t +
				n.y()*cosa*t +
				u;
			if ( fabs(fp)*deltas <= fabs(f) ) { //too big step
				int sgn = 1;
				if (fp<0.) sgn = -sgn;
				if (f <0.) sgn = -sgn;
				shift = sgn*deltas;
				if (shift == -shiftOld) { // don't get stuck shifting +/-deltas
					deltas *= dampingFactor; // dampen magnitude of shift
					shift = sgn*deltas;
					// allow iterations to run out
				} else {
					i--; // don't count against iterations
				}
			} else {
				shift = f/fp;
			}
			s -= shift;
			shiftOld = shift;
			if (fabs(sOld-s) < ktMaxPrecisionNeeded) break;
			sOld = s;
		}
		if (i == ktMaxIterations) return fgkNoSolution;
	}
	return s;
}

pair<double, double>
AliFmHelix::PathLengths(const AliFmHelix& h, bool scanPeriods) const
{
	//
	//	Cannot handle case where one is a helix
	//  and the other one is a straight line.
	//
	if (fSingularity != h.fSingularity) 
		return pair<double, double>(fgkNoSolution, fgkNoSolution);

	double s1, s2;

	if (fSingularity) {
		//
		//  Analytic solution
		//
		AliFmThreeVector<double> dv = h.fOrigin - fOrigin;
		AliFmThreeVector<double> a(-fCosDipAngle*fSinPhase,
			fCosDipAngle*fCosPhase,
			fSinDipAngle);
		AliFmThreeVector<double> b(-h.fCosDipAngle*h.fSinPhase,
			h.fCosDipAngle*h.fCosPhase,
			h.fSinDipAngle);	
		double ab = a*b;
		double g  = dv*a;
		double k  = dv*b;
		s2 = (k-ab*g)/(ab*ab-1.);
		s1 = g+s2*ab;
		return pair<double, double>(s1, s2);
	}
	else {	
		//
		//  First step: get dca in the xy-plane as start value
		//
		double dx = h.XCenter() - XCenter();
		double dy = h.YCenter() - YCenter();
		double dd = ::sqrt(dx*dx + dy*dy);
		double r1 = 1/Curvature();
		double r2 = 1/h.Curvature();

		/* malisa 22apr2006 is commenting out the "isnan" check
		 *		if ( !finite(r1) || isnan(r1) || !finite(r2) || isnan(r2) ) {
		 *		 cerr << __FUNCTION__ << " *** error *** ";
		 *			cerr << "  r1=" << r1;
		 *			cerr << "  r2=" << r2 << endl;
		 *			return pair<double, double>(fgkNoSolution, fgkNoSolution);
		 *		}
		 */

		double cosAlpha = (r1*r1 + dd*dd - r2*r2)/(2*r1*dd);

		double s;
		double x, y;
		if (fabs(cosAlpha) < 1) {           // two solutions
			double sinAlpha = sin(acos(cosAlpha));
			x = XCenter() + r1*(cosAlpha*dx - sinAlpha*dy)/dd;
			y = YCenter() + r1*(sinAlpha*dx + cosAlpha*dy)/dd;
			s = PathLength(x, y);
			x = XCenter() + r1*(cosAlpha*dx + sinAlpha*dy)/dd;
			y = YCenter() + r1*(cosAlpha*dy - sinAlpha*dx)/dd;
			double a = PathLength(x, y);
			if (h.Distance(At(a),scanPeriods) < h.Distance(At(s),scanPeriods)) s = a;
		}
		else {                              // no intersection (or exactly one)
			x = XCenter() + r1*dx/dd;
			y = YCenter() + r1*dy/dd;
			s = PathLength(x, y);
		}

		//
		//   Second step: scan in decreasing intervals around seed 's'
		// 
		const double ktMinStepSize = 10*micrometer;
		const double ktMinRange    = 10*centimeter;    
		double dmin              = h.Distance(At(s),scanPeriods);
		double range             = max(2*dmin, ktMinRange);

		/* malisa comments out the "isnan" check 22apr2006
		 *		if ( !finite(range) || isnan(range)) {
		 *			cerr << __FUNCTION__ << " *** error *** ";
		 *			cerr << "  range=" << range << endl;
		 *			return pair<double, double>(fgkNoSolution, fgkNoSolution);
		 *		}
		 */

		double ds = range/10.;
		double slast=-999999, d;
		s1 = s - range/2.;
		s2 = s + range/2.;

		double tmp1;
		double tmp2;

		while (ds > ktMinStepSize) {
			if ( !(s1<s2) ) {
				cerr << __FUNCTION__ << " *** error *** s1 = ";
				cerr << "    s2 = " << s2;
				cerr << "    range = " << range;
				cerr << "     ds = " << ds << endl;
				return pair<double, double>(fgkNoSolution, fgkNoSolution);
			}	
			tmp1 = (s2-s1);
			tmp2 = tmp1/10.0;
			ds = tmp2;
			if ( ds<0) {
			    cerr << __FUNCTION__ << " *** error *** ds = " << ds << endl;
			    return pair<double, double>(fgkNoSolution, fgkNoSolution);
			}
			int iterations = 0;
			for (double ss=s1; ss<(s2+ds); ss+=ds) {
			    iterations++;
			    if ( iterations > 100 ) {
				cerr << __FUNCTION__ << " *** error *** iterations = " << iterations << endl;
				return pair<double, double>(fgkNoSolution, fgkNoSolution);
			    }
			    d = h.Distance(At(ss),scanPeriods);
			    if (d < dmin) {
				dmin = d;
				s = ss;
			    }
			    slast = ss;
			}
			//
			//  In the rare cases where the minimum is at the
			//  the border of the current range we shift the range
			//  and start all over, i.e we do not decrease 'ds'.
			//  Else we decrease the search intervall around the
			//  current minimum and redo the scan in smaller steps.
			//
			if (s == s1) {
				d = 0.8*(s2-s1);
				s1 -= d;
				s2 -= d;
			}
			else if (s == slast) {
				d = 0.8*(s2-s1);
				s1 += d;
				s2 += d;
			}
			else {           
				s1 = s-ds;
				s2 = s+ds;
			//	ds /= 10;
			}
		}
		return pair<double, double>(s, h.PathLength(At(s),scanPeriods));
	}
}


void AliFmHelix::MoveOrigin(double s)
{
  // Move the helix origin
	if (fSingularity)
		fOrigin	= At(s);
	else {
		AliFmThreeVector<double> newOrigin = At(s);
		double newPhase = atan2(newOrigin.y() - YCenter(),
			newOrigin.x() - XCenter());
		fOrigin = newOrigin;
		SetPhase(newPhase);	        
	}
}

int operator== (const AliFmHelix& a, const AliFmHelix& b)
{
	//
	// Checks for numerical identity only !
	//
	return (a.Origin()    == b.Origin()    &&
		a.DipAngle()  == b.DipAngle()  &&
		a.Curvature() == b.Curvature() &&
		a.Phase()     == b.Phase()     &&
		a.H()         == b.H());
}

int operator!= (const AliFmHelix& a, const AliFmHelix& b) {return !(a == b);}

ostream& operator<<(ostream& os, const AliFmHelix& h)
{
	return os << '('
		<< "curvature = "  << h.Curvature() << ", " 
		<< "dip angle = "  << h.DipAngle()  << ", "
		<< "phase = "      << h.Phase()     << ", "  
		<< "h = "          << h.H()         << ", "    
		<< "origin = "     << h.Origin()    << ')';
}





 AliFmHelix.cxx:1
 AliFmHelix.cxx:2
 AliFmHelix.cxx:3
 AliFmHelix.cxx:4
 AliFmHelix.cxx:5
 AliFmHelix.cxx:6
 AliFmHelix.cxx:7
 AliFmHelix.cxx:8
 AliFmHelix.cxx:9
 AliFmHelix.cxx:10
 AliFmHelix.cxx:11
 AliFmHelix.cxx:12
 AliFmHelix.cxx:13
 AliFmHelix.cxx:14
 AliFmHelix.cxx:15
 AliFmHelix.cxx:16
 AliFmHelix.cxx:17
 AliFmHelix.cxx:18
 AliFmHelix.cxx:19
 AliFmHelix.cxx:20
 AliFmHelix.cxx:21
 AliFmHelix.cxx:22
 AliFmHelix.cxx:23
 AliFmHelix.cxx:24
 AliFmHelix.cxx:25
 AliFmHelix.cxx:26
 AliFmHelix.cxx:27
 AliFmHelix.cxx:28
 AliFmHelix.cxx:29
 AliFmHelix.cxx:30
 AliFmHelix.cxx:31
 AliFmHelix.cxx:32
 AliFmHelix.cxx:33
 AliFmHelix.cxx:34
 AliFmHelix.cxx:35
 AliFmHelix.cxx:36
 AliFmHelix.cxx:37
 AliFmHelix.cxx:38
 AliFmHelix.cxx:39
 AliFmHelix.cxx:40
 AliFmHelix.cxx:41
 AliFmHelix.cxx:42
 AliFmHelix.cxx:43
 AliFmHelix.cxx:44
 AliFmHelix.cxx:45
 AliFmHelix.cxx:46
 AliFmHelix.cxx:47
 AliFmHelix.cxx:48
 AliFmHelix.cxx:49
 AliFmHelix.cxx:50
 AliFmHelix.cxx:51
 AliFmHelix.cxx:52
 AliFmHelix.cxx:53
 AliFmHelix.cxx:54
 AliFmHelix.cxx:55
 AliFmHelix.cxx:56
 AliFmHelix.cxx:57
 AliFmHelix.cxx:58
 AliFmHelix.cxx:59
 AliFmHelix.cxx:60
 AliFmHelix.cxx:61
 AliFmHelix.cxx:62
 AliFmHelix.cxx:63
 AliFmHelix.cxx:64
 AliFmHelix.cxx:65
 AliFmHelix.cxx:66
 AliFmHelix.cxx:67
 AliFmHelix.cxx:68
 AliFmHelix.cxx:69
 AliFmHelix.cxx:70
 AliFmHelix.cxx:71
 AliFmHelix.cxx:72
 AliFmHelix.cxx:73
 AliFmHelix.cxx:74
 AliFmHelix.cxx:75
 AliFmHelix.cxx:76
 AliFmHelix.cxx:77
 AliFmHelix.cxx:78
 AliFmHelix.cxx:79
 AliFmHelix.cxx:80
 AliFmHelix.cxx:81
 AliFmHelix.cxx:82
 AliFmHelix.cxx:83
 AliFmHelix.cxx:84
 AliFmHelix.cxx:85
 AliFmHelix.cxx:86
 AliFmHelix.cxx:87
 AliFmHelix.cxx:88
 AliFmHelix.cxx:89
 AliFmHelix.cxx:90
 AliFmHelix.cxx:91
 AliFmHelix.cxx:92
 AliFmHelix.cxx:93
 AliFmHelix.cxx:94
 AliFmHelix.cxx:95
 AliFmHelix.cxx:96
 AliFmHelix.cxx:97
 AliFmHelix.cxx:98
 AliFmHelix.cxx:99
 AliFmHelix.cxx:100
 AliFmHelix.cxx:101
 AliFmHelix.cxx:102
 AliFmHelix.cxx:103
 AliFmHelix.cxx:104
 AliFmHelix.cxx:105
 AliFmHelix.cxx:106
 AliFmHelix.cxx:107
 AliFmHelix.cxx:108
 AliFmHelix.cxx:109
 AliFmHelix.cxx:110
 AliFmHelix.cxx:111
 AliFmHelix.cxx:112
 AliFmHelix.cxx:113
 AliFmHelix.cxx:114
 AliFmHelix.cxx:115
 AliFmHelix.cxx:116
 AliFmHelix.cxx:117
 AliFmHelix.cxx:118
 AliFmHelix.cxx:119
 AliFmHelix.cxx:120
 AliFmHelix.cxx:121
 AliFmHelix.cxx:122
 AliFmHelix.cxx:123
 AliFmHelix.cxx:124
 AliFmHelix.cxx:125
 AliFmHelix.cxx:126
 AliFmHelix.cxx:127
 AliFmHelix.cxx:128
 AliFmHelix.cxx:129
 AliFmHelix.cxx:130
 AliFmHelix.cxx:131
 AliFmHelix.cxx:132
 AliFmHelix.cxx:133
 AliFmHelix.cxx:134
 AliFmHelix.cxx:135
 AliFmHelix.cxx:136
 AliFmHelix.cxx:137
 AliFmHelix.cxx:138
 AliFmHelix.cxx:139
 AliFmHelix.cxx:140
 AliFmHelix.cxx:141
 AliFmHelix.cxx:142
 AliFmHelix.cxx:143
 AliFmHelix.cxx:144
 AliFmHelix.cxx:145
 AliFmHelix.cxx:146
 AliFmHelix.cxx:147
 AliFmHelix.cxx:148
 AliFmHelix.cxx:149
 AliFmHelix.cxx:150
 AliFmHelix.cxx:151
 AliFmHelix.cxx:152
 AliFmHelix.cxx:153
 AliFmHelix.cxx:154
 AliFmHelix.cxx:155
 AliFmHelix.cxx:156
 AliFmHelix.cxx:157
 AliFmHelix.cxx:158
 AliFmHelix.cxx:159
 AliFmHelix.cxx:160
 AliFmHelix.cxx:161
 AliFmHelix.cxx:162
 AliFmHelix.cxx:163
 AliFmHelix.cxx:164
 AliFmHelix.cxx:165
 AliFmHelix.cxx:166
 AliFmHelix.cxx:167
 AliFmHelix.cxx:168
 AliFmHelix.cxx:169
 AliFmHelix.cxx:170
 AliFmHelix.cxx:171
 AliFmHelix.cxx:172
 AliFmHelix.cxx:173
 AliFmHelix.cxx:174
 AliFmHelix.cxx:175
 AliFmHelix.cxx:176
 AliFmHelix.cxx:177
 AliFmHelix.cxx:178
 AliFmHelix.cxx:179
 AliFmHelix.cxx:180
 AliFmHelix.cxx:181
 AliFmHelix.cxx:182
 AliFmHelix.cxx:183
 AliFmHelix.cxx:184
 AliFmHelix.cxx:185
 AliFmHelix.cxx:186
 AliFmHelix.cxx:187
 AliFmHelix.cxx:188
 AliFmHelix.cxx:189
 AliFmHelix.cxx:190
 AliFmHelix.cxx:191
 AliFmHelix.cxx:192
 AliFmHelix.cxx:193
 AliFmHelix.cxx:194
 AliFmHelix.cxx:195
 AliFmHelix.cxx:196
 AliFmHelix.cxx:197
 AliFmHelix.cxx:198
 AliFmHelix.cxx:199
 AliFmHelix.cxx:200
 AliFmHelix.cxx:201
 AliFmHelix.cxx:202
 AliFmHelix.cxx:203
 AliFmHelix.cxx:204
 AliFmHelix.cxx:205
 AliFmHelix.cxx:206
 AliFmHelix.cxx:207
 AliFmHelix.cxx:208
 AliFmHelix.cxx:209
 AliFmHelix.cxx:210
 AliFmHelix.cxx:211
 AliFmHelix.cxx:212
 AliFmHelix.cxx:213
 AliFmHelix.cxx:214
 AliFmHelix.cxx:215
 AliFmHelix.cxx:216
 AliFmHelix.cxx:217
 AliFmHelix.cxx:218
 AliFmHelix.cxx:219
 AliFmHelix.cxx:220
 AliFmHelix.cxx:221
 AliFmHelix.cxx:222
 AliFmHelix.cxx:223
 AliFmHelix.cxx:224
 AliFmHelix.cxx:225
 AliFmHelix.cxx:226
 AliFmHelix.cxx:227
 AliFmHelix.cxx:228
 AliFmHelix.cxx:229
 AliFmHelix.cxx:230
 AliFmHelix.cxx:231
 AliFmHelix.cxx:232
 AliFmHelix.cxx:233
 AliFmHelix.cxx:234
 AliFmHelix.cxx:235
 AliFmHelix.cxx:236
 AliFmHelix.cxx:237
 AliFmHelix.cxx:238
 AliFmHelix.cxx:239
 AliFmHelix.cxx:240
 AliFmHelix.cxx:241
 AliFmHelix.cxx:242
 AliFmHelix.cxx:243
 AliFmHelix.cxx:244
 AliFmHelix.cxx:245
 AliFmHelix.cxx:246
 AliFmHelix.cxx:247
 AliFmHelix.cxx:248
 AliFmHelix.cxx:249
 AliFmHelix.cxx:250
 AliFmHelix.cxx:251
 AliFmHelix.cxx:252
 AliFmHelix.cxx:253
 AliFmHelix.cxx:254
 AliFmHelix.cxx:255
 AliFmHelix.cxx:256
 AliFmHelix.cxx:257
 AliFmHelix.cxx:258
 AliFmHelix.cxx:259
 AliFmHelix.cxx:260
 AliFmHelix.cxx:261
 AliFmHelix.cxx:262
 AliFmHelix.cxx:263
 AliFmHelix.cxx:264
 AliFmHelix.cxx:265
 AliFmHelix.cxx:266
 AliFmHelix.cxx:267
 AliFmHelix.cxx:268
 AliFmHelix.cxx:269
 AliFmHelix.cxx:270
 AliFmHelix.cxx:271
 AliFmHelix.cxx:272
 AliFmHelix.cxx:273
 AliFmHelix.cxx:274
 AliFmHelix.cxx:275
 AliFmHelix.cxx:276
 AliFmHelix.cxx:277
 AliFmHelix.cxx:278
 AliFmHelix.cxx:279
 AliFmHelix.cxx:280
 AliFmHelix.cxx:281
 AliFmHelix.cxx:282
 AliFmHelix.cxx:283
 AliFmHelix.cxx:284
 AliFmHelix.cxx:285
 AliFmHelix.cxx:286
 AliFmHelix.cxx:287
 AliFmHelix.cxx:288
 AliFmHelix.cxx:289
 AliFmHelix.cxx:290
 AliFmHelix.cxx:291
 AliFmHelix.cxx:292
 AliFmHelix.cxx:293
 AliFmHelix.cxx:294
 AliFmHelix.cxx:295
 AliFmHelix.cxx:296
 AliFmHelix.cxx:297
 AliFmHelix.cxx:298
 AliFmHelix.cxx:299
 AliFmHelix.cxx:300
 AliFmHelix.cxx:301
 AliFmHelix.cxx:302
 AliFmHelix.cxx:303
 AliFmHelix.cxx:304
 AliFmHelix.cxx:305
 AliFmHelix.cxx:306
 AliFmHelix.cxx:307
 AliFmHelix.cxx:308
 AliFmHelix.cxx:309
 AliFmHelix.cxx:310
 AliFmHelix.cxx:311
 AliFmHelix.cxx:312
 AliFmHelix.cxx:313
 AliFmHelix.cxx:314
 AliFmHelix.cxx:315
 AliFmHelix.cxx:316
 AliFmHelix.cxx:317
 AliFmHelix.cxx:318
 AliFmHelix.cxx:319
 AliFmHelix.cxx:320
 AliFmHelix.cxx:321
 AliFmHelix.cxx:322
 AliFmHelix.cxx:323
 AliFmHelix.cxx:324
 AliFmHelix.cxx:325
 AliFmHelix.cxx:326
 AliFmHelix.cxx:327
 AliFmHelix.cxx:328
 AliFmHelix.cxx:329
 AliFmHelix.cxx:330
 AliFmHelix.cxx:331
 AliFmHelix.cxx:332
 AliFmHelix.cxx:333
 AliFmHelix.cxx:334
 AliFmHelix.cxx:335
 AliFmHelix.cxx:336
 AliFmHelix.cxx:337
 AliFmHelix.cxx:338
 AliFmHelix.cxx:339
 AliFmHelix.cxx:340
 AliFmHelix.cxx:341
 AliFmHelix.cxx:342
 AliFmHelix.cxx:343
 AliFmHelix.cxx:344
 AliFmHelix.cxx:345
 AliFmHelix.cxx:346
 AliFmHelix.cxx:347
 AliFmHelix.cxx:348
 AliFmHelix.cxx:349
 AliFmHelix.cxx:350
 AliFmHelix.cxx:351
 AliFmHelix.cxx:352
 AliFmHelix.cxx:353
 AliFmHelix.cxx:354
 AliFmHelix.cxx:355
 AliFmHelix.cxx:356
 AliFmHelix.cxx:357
 AliFmHelix.cxx:358
 AliFmHelix.cxx:359
 AliFmHelix.cxx:360
 AliFmHelix.cxx:361
 AliFmHelix.cxx:362
 AliFmHelix.cxx:363
 AliFmHelix.cxx:364
 AliFmHelix.cxx:365
 AliFmHelix.cxx:366
 AliFmHelix.cxx:367
 AliFmHelix.cxx:368
 AliFmHelix.cxx:369
 AliFmHelix.cxx:370
 AliFmHelix.cxx:371
 AliFmHelix.cxx:372
 AliFmHelix.cxx:373
 AliFmHelix.cxx:374
 AliFmHelix.cxx:375
 AliFmHelix.cxx:376
 AliFmHelix.cxx:377
 AliFmHelix.cxx:378
 AliFmHelix.cxx:379
 AliFmHelix.cxx:380
 AliFmHelix.cxx:381
 AliFmHelix.cxx:382
 AliFmHelix.cxx:383
 AliFmHelix.cxx:384
 AliFmHelix.cxx:385
 AliFmHelix.cxx:386
 AliFmHelix.cxx:387
 AliFmHelix.cxx:388
 AliFmHelix.cxx:389
 AliFmHelix.cxx:390
 AliFmHelix.cxx:391
 AliFmHelix.cxx:392
 AliFmHelix.cxx:393
 AliFmHelix.cxx:394
 AliFmHelix.cxx:395
 AliFmHelix.cxx:396
 AliFmHelix.cxx:397
 AliFmHelix.cxx:398
 AliFmHelix.cxx:399
 AliFmHelix.cxx:400
 AliFmHelix.cxx:401
 AliFmHelix.cxx:402
 AliFmHelix.cxx:403
 AliFmHelix.cxx:404
 AliFmHelix.cxx:405
 AliFmHelix.cxx:406
 AliFmHelix.cxx:407
 AliFmHelix.cxx:408
 AliFmHelix.cxx:409
 AliFmHelix.cxx:410
 AliFmHelix.cxx:411
 AliFmHelix.cxx:412
 AliFmHelix.cxx:413
 AliFmHelix.cxx:414
 AliFmHelix.cxx:415
 AliFmHelix.cxx:416
 AliFmHelix.cxx:417
 AliFmHelix.cxx:418
 AliFmHelix.cxx:419
 AliFmHelix.cxx:420
 AliFmHelix.cxx:421
 AliFmHelix.cxx:422
 AliFmHelix.cxx:423
 AliFmHelix.cxx:424
 AliFmHelix.cxx:425
 AliFmHelix.cxx:426
 AliFmHelix.cxx:427
 AliFmHelix.cxx:428
 AliFmHelix.cxx:429
 AliFmHelix.cxx:430
 AliFmHelix.cxx:431
 AliFmHelix.cxx:432
 AliFmHelix.cxx:433
 AliFmHelix.cxx:434
 AliFmHelix.cxx:435
 AliFmHelix.cxx:436
 AliFmHelix.cxx:437
 AliFmHelix.cxx:438
 AliFmHelix.cxx:439
 AliFmHelix.cxx:440
 AliFmHelix.cxx:441
 AliFmHelix.cxx:442
 AliFmHelix.cxx:443
 AliFmHelix.cxx:444
 AliFmHelix.cxx:445
 AliFmHelix.cxx:446
 AliFmHelix.cxx:447
 AliFmHelix.cxx:448
 AliFmHelix.cxx:449
 AliFmHelix.cxx:450
 AliFmHelix.cxx:451
 AliFmHelix.cxx:452
 AliFmHelix.cxx:453
 AliFmHelix.cxx:454
 AliFmHelix.cxx:455
 AliFmHelix.cxx:456
 AliFmHelix.cxx:457
 AliFmHelix.cxx:458
 AliFmHelix.cxx:459
 AliFmHelix.cxx:460
 AliFmHelix.cxx:461
 AliFmHelix.cxx:462
 AliFmHelix.cxx:463
 AliFmHelix.cxx:464
 AliFmHelix.cxx:465
 AliFmHelix.cxx:466
 AliFmHelix.cxx:467
 AliFmHelix.cxx:468
 AliFmHelix.cxx:469
 AliFmHelix.cxx:470
 AliFmHelix.cxx:471
 AliFmHelix.cxx:472
 AliFmHelix.cxx:473
 AliFmHelix.cxx:474
 AliFmHelix.cxx:475
 AliFmHelix.cxx:476
 AliFmHelix.cxx:477
 AliFmHelix.cxx:478
 AliFmHelix.cxx:479
 AliFmHelix.cxx:480
 AliFmHelix.cxx:481
 AliFmHelix.cxx:482
 AliFmHelix.cxx:483
 AliFmHelix.cxx:484
 AliFmHelix.cxx:485
 AliFmHelix.cxx:486
 AliFmHelix.cxx:487
 AliFmHelix.cxx:488
 AliFmHelix.cxx:489
 AliFmHelix.cxx:490
 AliFmHelix.cxx:491
 AliFmHelix.cxx:492
 AliFmHelix.cxx:493
 AliFmHelix.cxx:494
 AliFmHelix.cxx:495
 AliFmHelix.cxx:496
 AliFmHelix.cxx:497
 AliFmHelix.cxx:498
 AliFmHelix.cxx:499
 AliFmHelix.cxx:500
 AliFmHelix.cxx:501
 AliFmHelix.cxx:502
 AliFmHelix.cxx:503
 AliFmHelix.cxx:504
 AliFmHelix.cxx:505
 AliFmHelix.cxx:506
 AliFmHelix.cxx:507
 AliFmHelix.cxx:508
 AliFmHelix.cxx:509
 AliFmHelix.cxx:510
 AliFmHelix.cxx:511
 AliFmHelix.cxx:512
 AliFmHelix.cxx:513
 AliFmHelix.cxx:514
 AliFmHelix.cxx:515
 AliFmHelix.cxx:516
 AliFmHelix.cxx:517
 AliFmHelix.cxx:518
 AliFmHelix.cxx:519
 AliFmHelix.cxx:520
 AliFmHelix.cxx:521
 AliFmHelix.cxx:522
 AliFmHelix.cxx:523
 AliFmHelix.cxx:524
 AliFmHelix.cxx:525
 AliFmHelix.cxx:526
 AliFmHelix.cxx:527
 AliFmHelix.cxx:528
 AliFmHelix.cxx:529
 AliFmHelix.cxx:530
 AliFmHelix.cxx:531
 AliFmHelix.cxx:532
 AliFmHelix.cxx:533
 AliFmHelix.cxx:534
 AliFmHelix.cxx:535
 AliFmHelix.cxx:536
 AliFmHelix.cxx:537
 AliFmHelix.cxx:538
 AliFmHelix.cxx:539
 AliFmHelix.cxx:540
 AliFmHelix.cxx:541
 AliFmHelix.cxx:542
 AliFmHelix.cxx:543
 AliFmHelix.cxx:544
 AliFmHelix.cxx:545
 AliFmHelix.cxx:546
 AliFmHelix.cxx:547
 AliFmHelix.cxx:548
 AliFmHelix.cxx:549
 AliFmHelix.cxx:550
 AliFmHelix.cxx:551
 AliFmHelix.cxx:552
 AliFmHelix.cxx:553
 AliFmHelix.cxx:554
 AliFmHelix.cxx:555
 AliFmHelix.cxx:556
 AliFmHelix.cxx:557
 AliFmHelix.cxx:558
 AliFmHelix.cxx:559
 AliFmHelix.cxx:560
 AliFmHelix.cxx:561
 AliFmHelix.cxx:562
 AliFmHelix.cxx:563
 AliFmHelix.cxx:564
 AliFmHelix.cxx:565
 AliFmHelix.cxx:566
 AliFmHelix.cxx:567
 AliFmHelix.cxx:568
 AliFmHelix.cxx:569
 AliFmHelix.cxx:570
 AliFmHelix.cxx:571
 AliFmHelix.cxx:572
 AliFmHelix.cxx:573
 AliFmHelix.cxx:574
 AliFmHelix.cxx:575
 AliFmHelix.cxx:576
 AliFmHelix.cxx:577
 AliFmHelix.cxx:578
 AliFmHelix.cxx:579
 AliFmHelix.cxx:580
 AliFmHelix.cxx:581
 AliFmHelix.cxx:582
 AliFmHelix.cxx:583
 AliFmHelix.cxx:584
 AliFmHelix.cxx:585
 AliFmHelix.cxx:586
 AliFmHelix.cxx:587
 AliFmHelix.cxx:588
 AliFmHelix.cxx:589
 AliFmHelix.cxx:590
 AliFmHelix.cxx:591
 AliFmHelix.cxx:592
 AliFmHelix.cxx:593
 AliFmHelix.cxx:594
 AliFmHelix.cxx:595
 AliFmHelix.cxx:596
 AliFmHelix.cxx:597
 AliFmHelix.cxx:598
 AliFmHelix.cxx:599
 AliFmHelix.cxx:600
 AliFmHelix.cxx:601
 AliFmHelix.cxx:602
 AliFmHelix.cxx:603
 AliFmHelix.cxx:604
 AliFmHelix.cxx:605
 AliFmHelix.cxx:606
 AliFmHelix.cxx:607
 AliFmHelix.cxx:608
 AliFmHelix.cxx:609
 AliFmHelix.cxx:610
 AliFmHelix.cxx:611
 AliFmHelix.cxx:612
 AliFmHelix.cxx:613
 AliFmHelix.cxx:614
 AliFmHelix.cxx:615
 AliFmHelix.cxx:616
 AliFmHelix.cxx:617
 AliFmHelix.cxx:618
 AliFmHelix.cxx:619
 AliFmHelix.cxx:620
 AliFmHelix.cxx:621
 AliFmHelix.cxx:622
 AliFmHelix.cxx:623
 AliFmHelix.cxx:624
 AliFmHelix.cxx:625
 AliFmHelix.cxx:626
 AliFmHelix.cxx:627
 AliFmHelix.cxx:628
 AliFmHelix.cxx:629
 AliFmHelix.cxx:630
 AliFmHelix.cxx:631
 AliFmHelix.cxx:632
 AliFmHelix.cxx:633
 AliFmHelix.cxx:634
 AliFmHelix.cxx:635
 AliFmHelix.cxx:636
 AliFmHelix.cxx:637
 AliFmHelix.cxx:638
 AliFmHelix.cxx:639
 AliFmHelix.cxx:640
 AliFmHelix.cxx:641
 AliFmHelix.cxx:642
 AliFmHelix.cxx:643
 AliFmHelix.cxx:644
 AliFmHelix.cxx:645
 AliFmHelix.cxx:646
 AliFmHelix.cxx:647
 AliFmHelix.cxx:648
 AliFmHelix.cxx:649
 AliFmHelix.cxx:650