#ifndef ALIITSTPARRAYFIT_H
#define ALIITSTPARRAYFIT_H
#include <TObject.h>
#include <TMath.h>
#include <AliTrackPointArray.h>
class AliSymMatrix;
class AliLog;
class AliParamSolver;
class AliITSTPArrayFit : public TObject
{
public:
enum {kFitDoneBit=BIT(14),kCovInvBit=BIT(15),
kCosmicsBit=BIT(16),kELossBit=BIT(17),
kIgnoreCovBit=BIT(18),
kMask=BIT(24)-1};
enum {kXX=0,kXY=1,kXZ=2,kYX=kXY,kYY=3,kYZ=4,kZX=kXZ,kZY=kYZ,kZZ=5,kScl=6,kNCov};
enum {kA0,kB0,kA1,kB1};
enum {kD0,kPhi0,kR0,kDZ,kDip};
enum {kX,kY,kZ};
enum {kMaxParam=6,kMaxParamSq = kMaxParam*(kMaxParam+1)/2};
enum {kLrBeamPime, kLrSPD1,kLrSPD2, kLrShield1, kLrSDD1,kLrSDD2, kLrShield2, kLrSSD1,kLrSSD2,kMaxLrITS};
public:
AliITSTPArrayFit();
AliITSTPArrayFit(Int_t npoints);
AliITSTPArrayFit(const AliITSTPArrayFit &fit);
AliITSTPArrayFit& operator= (const AliITSTPArrayFit& src);
virtual ~AliITSTPArrayFit();
void AttachPoints(const AliTrackPointArray* points, Int_t pfirst=-1,Int_t plast=-1);
Bool_t SetFirstLast(Int_t pfirst=-1,Int_t plast=-1);
AliTrackPointArray* GetPoints() const {return (AliTrackPointArray*)fkPoints;}
void SetBz(Double_t bz) {fBz = bz;}
Double_t GetBz() const {return fBz;}
Bool_t IsHelix() const {return fParAxis<0;}
Bool_t IsFieldON() const {return TMath::Abs(fBz)>1e-5;}
Bool_t IsTypeCosmics() const {return TestBit(kCosmicsBit);}
Bool_t IsTypeCollision() const {return !IsTypeCosmics();}
Int_t GetCharge() const {return fCharge;}
Int_t GetSignQB() const {return fBz<0 ? -fCharge:fCharge;}
void GetResiduals(Double_t *res, Int_t ipnt) const;
void GetResiduals(Double_t *resPCA, const Double_t* xyz, const Double_t* covI=0, Double_t sclCovI=-1) const;
Double_t GetPosition( Double_t *xyzPCA, const Double_t* xyz, const Double_t* covI=0, Double_t sclCovI=-1) const;
Double_t GetPosition( Double_t *xyzPCA, const AliTrackPoint *pntCovInv,Bool_t useErr=kFALSE) const;
void GetResiduals(Double_t *xyzPCA, const AliTrackPoint *pntCovInv,Bool_t useErr=kFALSE) const;
void GetPosition(Double_t *xyz, Double_t t) const;
void GetPosition(Double_t *xyz, Int_t pnt) const;
void GetDirCos(Double_t *dircos, Double_t t) const;
Double_t GetPCA2PlaneInfo(Double_t *xyz, Double_t *dir=0, Int_t axis=kY, Double_t axval=0) const;
void GetT0Info(Double_t *xyz, Double_t *dir=0) const;
Double_t CalcChi2NDF() const;
Double_t GetChi2NDF() const {return fChi2NDF;}
Double_t GetParPCA(const double *xyz, const double *covI=0, Double_t sclCovI=-1) const;
Double_t CalcParPCA(Int_t ipnt) const;
Bool_t CalcErrorMatrix();
void GetDResDParamsLine (Double_t *dXYZdP, const Double_t *xyz, const Double_t *covI=0) const;
void GetDResDParamsLine (Double_t *dXYZdP, Int_t ipnt) const;
void GetDResDParams(Double_t *dXYZdP, const Double_t *xyz, const Double_t *covI=0, Double_t sclCovI=-1);
void GetDResDParams(Double_t *dXYZdP, Int_t ipnt);
void GetDResDPosLine (Double_t *dXYZdP, const Double_t *covI=0) const;
void GetDResDPosLine (Double_t *dXYZdP, Int_t ipnt) const;
void GetDResDPos(Double_t *dXYZdP, const Double_t *xyz, const Double_t *covI=0, Double_t sclCovI=-1) const;
void GetDResDPos(Double_t *dXYZdP, Int_t ipnt);
Double_t* GetPoint(int ip) const;
Bool_t Converged() const {return fIter<fMaxIter;}
Double_t Fit(Int_t extQ=0, Double_t extPT=-1,Double_t extPTerr=0);
Double_t FitLine();
Double_t FitHelix(Int_t extQ=0, Double_t extPT=-1,Double_t extPTerr=0);
Bool_t FitLineCrude();
Bool_t FitHelixCrude(Int_t imposedQ=0);
Int_t GetParAxis() const {return fParAxis;}
Int_t GetAxID(Int_t id) const {return fkAxID ? fkAxID[id] : -1;}
Int_t GetAxCID(Int_t id) const {return fkAxCID ? fkAxCID[id] : -1;}
Int_t GetFirst() const {return fPntFirst;}
Int_t GetLast() const {return fPntLast;}
Int_t GetNParams() const {return IsFieldON() ? 5:4;}
Bool_t InvertPointsCovMat();
Int_t* GetElsId() const {return fElsId;}
Double_t* GetElsDR() const {return fElsDR;}
Double_t GetCovIScale(Int_t ip) const {return ip<fNPBooked ? fCovI[ip*kNCov+kScl] : -1.0;}
Double_t* GetCovI(Int_t ip) const {return fCovI + kNCov*ip;}
Double_t* GetCovI() const {return fCovI;}
Double_t* GetParams() const {return (Double_t*)&fParams[0];}
Double_t GetParam(Int_t ip) const {return fParams[ip];}
Double_t* GetTs() const {return (Double_t*)fCurT;}
Double_t GetT(Int_t ip) const {return fCurT[ip];}
Double_t GetLineOffset(Int_t axis) const;
Double_t GetLineSlope(Int_t axis) const;
Bool_t IsSwitched2Line() const {return fSwitch2Line;}
Bool_t IsELossON() const {return TestBit(kELossBit)&&IsFieldON();}
Bool_t IsFitDone() const {return TestBit(kFitDoneBit);}
Bool_t IsCovInv() const {return TestBit(kCovInvBit);}
Bool_t IsCovIgnored() const {return TestBit(kIgnoreCovBit);}
Int_t GetMaxIterations() const {return fMaxIter;}
Int_t GetNIterations() const {return fIter;}
Double_t GetEps() const {return fEps;}
Double_t GetMass() const {return fMass;}
Double_t GetPt() const;
Double_t GetP() const;
void Switch2Line(Bool_t v=kTRUE) {fSwitch2Line = v;}
void SetMaxRforHelix(Double_t r) {fMaxRforHelix = r>0 ? r : 1e9;}
void SetCharge(Int_t q=1) {fCharge = q<0 ? -1:1;}
void SetELossON(Bool_t v=kTRUE) {SetBit(kELossBit,v);}
void SetTypeCosmics(Bool_t v=kTRUE) {SetBit(kCosmicsBit,v);}
void SetTypeCollision(Bool_t v=kTRUE) {SetTypeCosmics(!v);}
void SetFitDone(Bool_t v=kTRUE) {SetBit(kFitDoneBit,v);}
void SetCovInv(Bool_t v=kTRUE) {SetBit(kCovInvBit,v);}
void SetIgnoreCov(Bool_t v=kTRUE) {SetBit(kIgnoreCovBit,v);}
void SetParAxis(Int_t ax);
void SetMaxIterations(Int_t n=20) {fMaxIter = n<2 ? 2:n;}
void SetEps(Double_t eps=1e-6) {fEps = eps<0 ? GetMachinePrec() : eps;}
void SetMass(Double_t m=0.13957) {fMass = m<5E-4 ? 5E-4 : m;}
void Reset();
void BuildMaterialLUT(Int_t ntri=3000);
void SetCovIScale(Int_t ip, Double_t scl=-1.0);
void ResetCovIScale(Double_t scl=-1.0) {for (int i=fNPBooked;i--;) SetCovIScale(i,scl);}
virtual void Print(Option_t *opt="") const;
static void GetNormal(Double_t *norm,const Float_t *covMat);
protected:
void InitAux();
Int_t ChoseParAxis() const;
Double_t GetParPCALine(const Double_t *xyz, const Double_t *covI=0) const;
Double_t GetParPCAHelix(const Double_t *xyz, const Double_t *covI=0, Double_t sclCovI=-1) const;
Double_t GetParPCACircle(Double_t x, Double_t y) const;
Double_t GetHelixParAtR(Double_t r) const;
void GetDtDPosLine(Double_t *dtpos, const Double_t *covI=0) const;
Double_t GetDtDParamsLine(Double_t *dtparam,const Double_t *xyz, const Double_t *covI=0) const;
Double_t GetDRofELoss(Double_t t,Double_t cdip,Double_t rhoL,
const Double_t *normS, Double_t &p,Double_t &e) const;
static Bool_t IsZero(Double_t v,Double_t threshold = 1e-16) {return TMath::Abs(v)<threshold; }
static Double_t GetMachinePrec();
protected:
const AliTrackPointArray *fkPoints;
AliParamSolver* fParSol;
Double_t fBz;
Int_t fCharge;
Int_t fPntFirst;
Int_t fPntLast;
Int_t fNPBooked;
Int_t fParAxis;
Double_t *fCovI;
Double_t fParams[kMaxParam];
Double_t fParamsCov[kMaxParamSq];
Double_t fChi2NDF;
Int_t fMaxIter;
Int_t fIter;
Double_t fEps;
Double_t fMass;
Bool_t fSwitch2Line;
Double_t fMaxRforHelix;
const Int_t *fkAxID;
const Int_t *fkAxCID;
Double_t *fCurT;
Int_t fFirstPosT;
Int_t fNElsPnt;
Int_t *fElsId;
Double_t *fElsDR;
static Double_t fgRhoLITS[kMaxLrITS];
static const Double_t fgkRLayITS[kMaxLrITS];
static const Double_t fgkZSpanITS[kMaxLrITS];
static const Int_t fgkPassivLrITS[3];
static const Int_t fgkActiveLrITS[6];
static const Double_t fgkAlmostZero;
static const Double_t fgkCQConv;
static const Int_t fgkAxisID[3][3];
static const Int_t fgkAxisCID[3][6];
ClassDef(AliITSTPArrayFit,0);
};
inline void AliITSTPArrayFit::GetPosition(Double_t *xyz, Int_t pnt) const
{
GetPosition(xyz,fCurT[pnt]);
}
inline Double_t AliITSTPArrayFit::GetParPCA(const double *xyz, const double *covI, Double_t sclCovI) const
{
if (IsFieldON()) return GetParPCAHelix(xyz,covI,sclCovI);
else return GetParPCALine(xyz,covI);
}
inline Double_t* AliITSTPArrayFit::GetPoint(Int_t ip) const
{
static double xyz[3];
xyz[kX] = fkPoints->GetX()[ip];
xyz[kY] = fkPoints->GetY()[ip];
xyz[kZ] = fkPoints->GetZ()[ip];
return &xyz[0];
}
inline Double_t AliITSTPArrayFit::Fit(Int_t extQ,Double_t extPT,Double_t extPTerr)
{
if (IsFieldON()) return FitHelix(extQ,extPT,extPTerr);
else return FitLine();
}
inline void AliITSTPArrayFit::SetCovIScale(Int_t ip, Double_t scl)
{
if (ip>=fNPBooked) return;
if (TMath::Abs(scl-GetCovIScale(ip))<1e-7) ResetBit(kFitDoneBit);
fCovI[ip*kNCov+kScl] = scl;
}
#endif