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.     //
//                                                                       //
///////////////////////////////////////////////////////////////////////////
#include <math.h>
#include "AliFmHelix.h"
#include "AliFmPhysicalHelix.h"
#include "PhysicalConstants.h" 
#include "SystemOfUnits.h"
#ifdef __ROOT__
ClassImpT(AliFmPhysicalHelix,double);
#endif
AliFmPhysicalHelix::AliFmPhysicalHelix(){}

AliFmPhysicalHelix::~AliFmPhysicalHelix() { /* nop */ }

AliFmPhysicalHelix::AliFmPhysicalHelix(const AliFmThreeVector<double>& p,
				       const AliFmThreeVector<double>& o,
				       double B, double q)
{
  // Constructor from given parameters
  fH = (q*B <= 0) ? 1 : -1;
  if(p.y() == 0 && p.x() == 0)
    SetPhase((M_PI/4)*(1-2.*fH));
  else
    SetPhase(atan2(p.y(),p.x())-fH*M_PI/2);
  SetDipAngle(atan2(p.z(),p.Perp()));
  fOrigin = o;
  
#ifndef ST_NO_NAMESPACES
  {
    using namespace units;
#endif
    SetCurvature(fabs((kCLight*nanosecond/meter*q*B/tesla)/
		      (abs(p.Mag())/GeV*fCosDipAngle)/meter));   
#ifndef ST_NO_NAMESPACES
  }
#endif
}

AliFmPhysicalHelix::AliFmPhysicalHelix(double c, double d, double phase,
				       const AliFmThreeVector<double>& o, int h)
  : AliFmHelix(c, d, phase, o, h) { /* nop */}


AliFmThreeVector<double> AliFmPhysicalHelix::Momentum(double B) const
{
  // momentum for given magnetic field
  if (fSingularity)
    return(AliFmThreeVector<double>(0,0,0));
  else {
#ifndef ST_NO_NAMESPACES
    {
	    using namespace units;
#endif
	    double pt = GeV*fabs(kCLight*nanosecond/meter*B/tesla)/(fabs(fCurvature)*meter);
	    
	    return (AliFmThreeVector<double>(pt*cos(fPhase+fH*M_PI/2),   // pos part pos field
					  pt*sin(fPhase+fH*M_PI/2),
					  pt*tan(fDipAngle)));
#ifndef ST_NO_NAMESPACES
	}
#endif
    }
}

AliFmThreeVector<double> AliFmPhysicalHelix::MomentumAt(double S, double B) const
{
    // Obtain phase-shifted momentum from phase-shift of origin
    double xc = this->XCenter();
    double yc = this->YCenter();
    double rx = (Y(S)-yc)/(fOrigin.y()-yc);
    double ry = (X(S)-xc)/(fOrigin.x()-xc);
    return (this->Momentum(B)).PseudoProduct(rx,ry,1.0);
}

int AliFmPhysicalHelix::Charge(double B) const
{
  // charge
    return (B > 0 ? -fH : fH);
}

double AliFmPhysicalHelix::GeometricSignedDistance(double x, double y)  
{
    // Geometric signed distance
    double thePath = this->PathLength(x,y);
    AliFmThreeVector<double> tDCA2dPosition = this->At(thePath);
    tDCA2dPosition.SetZ(0);
    AliFmThreeVector<double> position(x,y,0);
    AliFmThreeVector<double> tDCAVec = (tDCA2dPosition-position);
    AliFmThreeVector<double> momVec;
    // Deal with straight tracks
    if (this->fSingularity) {
	momVec = this->At(1)- this->At(0);
	momVec.SetZ(0);
    }
    else {
	momVec = this->MomentumAt(thePath,1./tesla); // Don't care about Bmag.  Helicity is what matters.
	momVec.SetZ(0);
    }
    
    double cross = tDCAVec.x()*momVec.y() - tDCAVec.y()*momVec.x();
    double theSign = (cross>=0) ? 1. : -1.;
    return theSign*tDCAVec.Perp();
}

double AliFmPhysicalHelix::CurvatureSignedDistance(double x, double y) 
{
    // Protect against fH = 0 or zero field
    if (this->fSingularity || abs(this->fH)<=0) {
	return (this->GeometricSignedDistance(x,y));
    }
    else {
	return (this->GeometricSignedDistance(x,y))/(this->fH);
    }
    
}

double AliFmPhysicalHelix::GeometricSignedDistance(const AliFmThreeVector<double>& pos) 
{
  // Geometric distance
    double sdca2d = this->GeometricSignedDistance(pos.x(),pos.y());
    double theSign = (sdca2d>=0) ? 1. : -1.;
    return (this->Distance(pos))*theSign;
}

double AliFmPhysicalHelix::CurvatureSignedDistance(const AliFmThreeVector<double>& pos) 
{
  // Distance with the sign dependent on curvature sigm
    double sdca2d = this->CurvatureSignedDistance(pos.x(),pos.y());
    double theSign = (sdca2d>=0) ? 1. : -1.;
    return (this->Distance(pos))*theSign;
}
 AliFmPhysicalHelix.cxx:1
 AliFmPhysicalHelix.cxx:2
 AliFmPhysicalHelix.cxx:3
 AliFmPhysicalHelix.cxx:4
 AliFmPhysicalHelix.cxx:5
 AliFmPhysicalHelix.cxx:6
 AliFmPhysicalHelix.cxx:7
 AliFmPhysicalHelix.cxx:8
 AliFmPhysicalHelix.cxx:9
 AliFmPhysicalHelix.cxx:10
 AliFmPhysicalHelix.cxx:11
 AliFmPhysicalHelix.cxx:12
 AliFmPhysicalHelix.cxx:13
 AliFmPhysicalHelix.cxx:14
 AliFmPhysicalHelix.cxx:15
 AliFmPhysicalHelix.cxx:16
 AliFmPhysicalHelix.cxx:17
 AliFmPhysicalHelix.cxx:18
 AliFmPhysicalHelix.cxx:19
 AliFmPhysicalHelix.cxx:20
 AliFmPhysicalHelix.cxx:21
 AliFmPhysicalHelix.cxx:22
 AliFmPhysicalHelix.cxx:23
 AliFmPhysicalHelix.cxx:24
 AliFmPhysicalHelix.cxx:25
 AliFmPhysicalHelix.cxx:26
 AliFmPhysicalHelix.cxx:27
 AliFmPhysicalHelix.cxx:28
 AliFmPhysicalHelix.cxx:29
 AliFmPhysicalHelix.cxx:30
 AliFmPhysicalHelix.cxx:31
 AliFmPhysicalHelix.cxx:32
 AliFmPhysicalHelix.cxx:33
 AliFmPhysicalHelix.cxx:34
 AliFmPhysicalHelix.cxx:35
 AliFmPhysicalHelix.cxx:36
 AliFmPhysicalHelix.cxx:37
 AliFmPhysicalHelix.cxx:38
 AliFmPhysicalHelix.cxx:39
 AliFmPhysicalHelix.cxx:40
 AliFmPhysicalHelix.cxx:41
 AliFmPhysicalHelix.cxx:42
 AliFmPhysicalHelix.cxx:43
 AliFmPhysicalHelix.cxx:44
 AliFmPhysicalHelix.cxx:45
 AliFmPhysicalHelix.cxx:46
 AliFmPhysicalHelix.cxx:47
 AliFmPhysicalHelix.cxx:48
 AliFmPhysicalHelix.cxx:49
 AliFmPhysicalHelix.cxx:50
 AliFmPhysicalHelix.cxx:51
 AliFmPhysicalHelix.cxx:52
 AliFmPhysicalHelix.cxx:53
 AliFmPhysicalHelix.cxx:54
 AliFmPhysicalHelix.cxx:55
 AliFmPhysicalHelix.cxx:56
 AliFmPhysicalHelix.cxx:57
 AliFmPhysicalHelix.cxx:58
 AliFmPhysicalHelix.cxx:59
 AliFmPhysicalHelix.cxx:60
 AliFmPhysicalHelix.cxx:61
 AliFmPhysicalHelix.cxx:62
 AliFmPhysicalHelix.cxx:63
 AliFmPhysicalHelix.cxx:64
 AliFmPhysicalHelix.cxx:65
 AliFmPhysicalHelix.cxx:66
 AliFmPhysicalHelix.cxx:67
 AliFmPhysicalHelix.cxx:68
 AliFmPhysicalHelix.cxx:69
 AliFmPhysicalHelix.cxx:70
 AliFmPhysicalHelix.cxx:71
 AliFmPhysicalHelix.cxx:72
 AliFmPhysicalHelix.cxx:73
 AliFmPhysicalHelix.cxx:74
 AliFmPhysicalHelix.cxx:75
 AliFmPhysicalHelix.cxx:76
 AliFmPhysicalHelix.cxx:77
 AliFmPhysicalHelix.cxx:78
 AliFmPhysicalHelix.cxx:79
 AliFmPhysicalHelix.cxx:80
 AliFmPhysicalHelix.cxx:81
 AliFmPhysicalHelix.cxx:82
 AliFmPhysicalHelix.cxx:83
 AliFmPhysicalHelix.cxx:84
 AliFmPhysicalHelix.cxx:85
 AliFmPhysicalHelix.cxx:86
 AliFmPhysicalHelix.cxx:87
 AliFmPhysicalHelix.cxx:88
 AliFmPhysicalHelix.cxx:89
 AliFmPhysicalHelix.cxx:90
 AliFmPhysicalHelix.cxx:91
 AliFmPhysicalHelix.cxx:92
 AliFmPhysicalHelix.cxx:93
 AliFmPhysicalHelix.cxx:94
 AliFmPhysicalHelix.cxx:95
 AliFmPhysicalHelix.cxx:96
 AliFmPhysicalHelix.cxx:97
 AliFmPhysicalHelix.cxx:98
 AliFmPhysicalHelix.cxx:99
 AliFmPhysicalHelix.cxx:100
 AliFmPhysicalHelix.cxx:101
 AliFmPhysicalHelix.cxx:102
 AliFmPhysicalHelix.cxx:103
 AliFmPhysicalHelix.cxx:104
 AliFmPhysicalHelix.cxx:105
 AliFmPhysicalHelix.cxx:106
 AliFmPhysicalHelix.cxx:107
 AliFmPhysicalHelix.cxx:108
 AliFmPhysicalHelix.cxx:109
 AliFmPhysicalHelix.cxx:110
 AliFmPhysicalHelix.cxx:111
 AliFmPhysicalHelix.cxx:112
 AliFmPhysicalHelix.cxx:113
 AliFmPhysicalHelix.cxx:114
 AliFmPhysicalHelix.cxx:115
 AliFmPhysicalHelix.cxx:116
 AliFmPhysicalHelix.cxx:117
 AliFmPhysicalHelix.cxx:118
 AliFmPhysicalHelix.cxx:119
 AliFmPhysicalHelix.cxx:120
 AliFmPhysicalHelix.cxx:121
 AliFmPhysicalHelix.cxx:122
 AliFmPhysicalHelix.cxx:123
 AliFmPhysicalHelix.cxx:124
 AliFmPhysicalHelix.cxx:125
 AliFmPhysicalHelix.cxx:126
 AliFmPhysicalHelix.cxx:127
 AliFmPhysicalHelix.cxx:128
 AliFmPhysicalHelix.cxx:129
 AliFmPhysicalHelix.cxx:130
 AliFmPhysicalHelix.cxx:131
 AliFmPhysicalHelix.cxx:132
 AliFmPhysicalHelix.cxx:133
 AliFmPhysicalHelix.cxx:134
 AliFmPhysicalHelix.cxx:135
 AliFmPhysicalHelix.cxx:136