#include <TObjArray.h>
#include <TFile.h>
#include <TString.h>
#include <TSystem.h>
#include "AliLog.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBPath.h"
#include "AliTPCLaserTrack.h"
#include "AliTPCROC.h"
ClassImp(AliTPCLaserTrack)
TObjArray *AliTPCLaserTrack::fgArrLaserTracks=0x0;
AliTPCLaserTrack::AliTPCLaserTrack() :
AliExternalTrackParam(),
fId(-1),
fSide(-1),
fRod(-1),
fBundle(-1),
fBeam(-1),
fRayLength(0),
fVecSec(0),
fVecP2(0),
fVecPhi(0),
fVecGX(0),
fVecGY(0),
fVecGZ(0),
fVecLX(0),
fVecLY(0),
fVecLZ(0)
{
}
AliTPCLaserTrack::AliTPCLaserTrack(const AliTPCLaserTrack <r) :
AliExternalTrackParam(ltr),
fId(ltr.fId),
fSide(ltr.fSide),
fRod(ltr.fRod),
fBundle(ltr.fBundle),
fBeam(ltr.fBeam),
fRayLength(ltr.fRayLength),
fVecSec(0),
fVecP2(0),
fVecPhi(0),
fVecGX(0),
fVecGY(0),
fVecGZ(0),
fVecLX(0),
fVecLY(0),
fVecLZ(0)
{
fVecSec=new TVectorD(*ltr.fVecSec);
fVecP2 =new TVectorD(*ltr.fVecP2);
fVecPhi=new TVectorD(*ltr.fVecPhi);
fVecGX =new TVectorD(*ltr.fVecGX);
fVecGY =new TVectorD(*ltr.fVecGY);
fVecGZ =new TVectorD(*ltr.fVecGZ);
fVecLX =new TVectorD(*ltr.fVecLX);
fVecLY =new TVectorD(*ltr.fVecLY);
fVecLZ =new TVectorD(*ltr.fVecLZ);
}
AliTPCLaserTrack::AliTPCLaserTrack(const Int_t id, const Int_t side, const Int_t rod,
const Int_t bundle, const Int_t beam,
Double_t x, Double_t alpha,
const Double_t param[5],
const Double_t covar[15], const Float_t rayLength) :
AliExternalTrackParam(x,alpha,param,covar),
fId(id),
fSide(side),
fRod(rod),
fBundle(bundle),
fBeam(beam),
fRayLength(rayLength),
fVecSec(new TVectorD(159)),
fVecP2(new TVectorD(159)),
fVecPhi(new TVectorD(159)),
fVecGX(new TVectorD(159)),
fVecGY(new TVectorD(159)),
fVecGZ(new TVectorD(159)),
fVecLX(new TVectorD(159)),
fVecLY(new TVectorD(159)),
fVecLZ(new TVectorD(159))
{
}
AliTPCLaserTrack& AliTPCLaserTrack::operator = (const AliTPCLaserTrack &source)
{
if (&source == this) return *this;
new (this) AliTPCLaserTrack(source);
return *this;
}
AliTPCLaserTrack::~AliTPCLaserTrack(){
delete fVecSec;
delete fVecP2;
delete fVecPhi;
delete fVecGX;
delete fVecGY;
delete fVecGZ;
delete fVecLX;
delete fVecLY;
delete fVecLZ;
}
void AliTPCLaserTrack::LoadTracks()
{
if ( fgArrLaserTracks ) return;
TObjArray *arrLaserTracks = 0x0;
AliCDBManager *man=AliCDBManager::Instance();
if (!man->GetDefaultStorage() && gSystem->Getenv("ALICE_ROOT")) man->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
if (man->GetDefaultStorage()){
if (man->GetRun()<0) man->SetRun(0);
AliCDBEntry *entry=man->Get(AliCDBPath("TPC/Calib/LaserTracks"));
if (!entry) return;
arrLaserTracks = (TObjArray*)entry->GetObject();
entry->SetOwner(kTRUE);
} else {
if (!gSystem->AccessPathName("LaserTracks.root")){
TFile f("LaserTracks.root");
arrLaserTracks=(TObjArray*)f.Get("arrLaserTracks");
f.Close();
}
}
if ( !arrLaserTracks ) {
return;
}
arrLaserTracks->SetOwner();
fgArrLaserTracks = new TObjArray(fgkNLaserTracks);
fgArrLaserTracks->SetOwner();
for (Int_t itrack=0; itrack<fgkNLaserTracks; itrack++){
AliTPCLaserTrack *ltr = (AliTPCLaserTrack*)arrLaserTracks->At(itrack);
if ( !ltr ){
continue;
}
ltr->UpdatePoints();
fgArrLaserTracks->AddAt(new AliTPCLaserTrack(*ltr),itrack);
}
delete arrLaserTracks;
}
void AliTPCLaserTrack::UpdatePoints(){
const Double_t kMaxSnp=0.97;
AliTPCROC* roc = AliTPCROC::Instance();
if (!fVecSec){
fVecSec=new TVectorD(159);
fVecP2 =new TVectorD(159);
fVecPhi=new TVectorD(159);
fVecGX=new TVectorD(159);
fVecGY=new TVectorD(159);
fVecGZ=new TVectorD(159);
fVecLX=new TVectorD(159);
fVecLY=new TVectorD(159);
fVecLZ=new TVectorD(159);
}
for (Int_t irow=158; irow>=0; irow--){
(*fVecSec)[irow]= -1;
(*fVecP2)[irow] = 0;
(*fVecPhi)[irow]= 0;
(*fVecGX)[irow] = 0;
(*fVecGY)[irow] = 0;
(*fVecGZ)[irow] = 0;
(*fVecLX)[irow] = 0;
(*fVecLY)[irow] = 0;
(*fVecLZ)[irow] = 0;
}
Double_t gxyz[3];
Double_t lxyz[3];
AliTPCLaserTrack*ltrp=new AliTPCLaserTrack(*this);
for (Int_t irow=158; irow>=0; irow--){
UInt_t srow = irow;
Int_t sector=0;
if (srow >=roc->GetNRows(0)) {
srow-=roc->GetNRows(0);
sector=36 ;
}
lxyz[0]= roc->GetPadRowRadii(sector,srow);
if (!ltrp->PropagateTo(lxyz[0],5)) break;
ltrp->GetXYZ(gxyz);
Double_t alpha=TMath::ATan2(gxyz[1],gxyz[0]);
if (alpha<0) alpha+=2*TMath::Pi();
sector +=TMath::Nint(-0.5+9*alpha/TMath::Pi());
if (gxyz[2]<0) sector+=18;
Double_t salpha = TMath::Pi()*(sector+0.5)/9.;
if (!ltrp->Rotate(salpha)) break;
if (!ltrp->PropagateTo(lxyz[0],5)) break;
if (TMath::Abs(ltrp->GetSnp())>kMaxSnp) break;
ltrp->GetXYZ(gxyz);
lxyz[1]=ltrp->GetY();
lxyz[2]=ltrp->GetZ();
(*fVecSec)[irow]= sector;
(*fVecP2)[irow] = ltrp->GetSnp();
(*fVecPhi)[irow]= TMath::ATan2(gxyz[1],gxyz[0]);
(*fVecGX)[irow] = gxyz[0];
(*fVecGY)[irow] = gxyz[1];
(*fVecGZ)[irow] = gxyz[2];
(*fVecLX)[irow] = lxyz[0];
(*fVecLY)[irow] = lxyz[1];
(*fVecLZ)[irow] = lxyz[2];
}
delete ltrp;
}
Int_t AliTPCLaserTrack::IdentifyTrack(AliExternalTrackParam *track, Int_t side)
{
const Float_t kMaxdphi=0.2;
const Float_t kMaxdphiP=0.05;
const Float_t kMaxdz=40;
if ( !fgArrLaserTracks ) LoadTracks();
TObjArray *arrTracks = GetTracks();
Double_t lxyz0[3];
Double_t lxyz1[3];
Double_t pxyz0[3];
Double_t pxyz1[3];
track->GetXYZ(lxyz0);
track->GetDirection(pxyz0);
Float_t mindist=10;
Int_t id = -1;
for (Int_t itrack=0; itrack<fgkNLaserTracks; itrack++){
AliTPCLaserTrack *ltr = (AliTPCLaserTrack*)arrTracks->UncheckedAt(itrack);
if (side>=0) if (ltr->GetSide()!=side) continue;
Double_t * kokot = (Double_t*)ltr->GetParameter();
kokot[4]=-0.0000000001;
ltr->GetXYZ(lxyz1);
if (TMath::Abs(lxyz1[2]-lxyz0[2])>kMaxdz) continue;
Double_t phi0 = TMath::ATan2(lxyz0[1],lxyz0[0]);
Double_t phi1 = TMath::ATan2(lxyz1[1],lxyz1[0]);
if (TMath::Abs(phi0-phi1)>kMaxdphi) continue;
ltr->GetDirection(pxyz1);
Float_t direction= pxyz0[0]*pxyz1[0] + pxyz0[1]*pxyz1[1] + pxyz0[2]*pxyz1[2];
Float_t distdir = (1-TMath::Abs(direction))*90.;
if (1-TMath::Abs(direction)>kMaxdphiP)
continue;
Float_t dist=0;
dist+=TMath::Abs(lxyz1[0]-lxyz0[0]);
dist+=TMath::Abs(lxyz1[1]-lxyz0[1]);
dist+=distdir;
if (id<0) {
id =itrack;
mindist=dist;
continue;
}
if (dist>mindist) continue;
id = itrack;
mindist=dist;
}
return id;
}