#include "AliTPCROC.h"
#include "AliTPCCalPad.h"
#include "AliTPCCalROC.h"
#include "AliTPCcalibDB.h"
#include "AliTPCParam.h"
#include "TMath.h"
#include "AliLog.h"
#include "AliTPCExB.h"
#include "AliTPCCorrection.h"
#include "TGeoMatrix.h"
#include "AliTPCRecoParam.h"
#include "AliTPCCalibVdrift.h"
#include "AliTPCTransform.h"
#include "AliMagF.h"
#include "TGeoGlobalMagField.h"
#include "AliTracker.h"
#include <AliCTPTimeParams.h>
ClassImp(AliTPCTransform)
AliTPCTransform::AliTPCTransform():
AliTransform(),
fCurrentRecoParam(0),
fCurrentRun(0),
fCurrentTimeStamp(0)
{
for (Int_t i=0;i<18;++i) {
Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
fSins[i]=TMath::Sin(alpha);
fCoss[i]=TMath::Cos(alpha);
}
fPrimVtx[0]=0;
fPrimVtx[1]=0;
fPrimVtx[2]=0;
}
AliTPCTransform::AliTPCTransform(const AliTPCTransform& transform):
AliTransform(transform),
fCurrentRecoParam(transform.fCurrentRecoParam),
fCurrentRun(transform.fCurrentRun),
fCurrentTimeStamp(transform.fCurrentTimeStamp)
{
for (Int_t i=0;i<18;++i) {
Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
fSins[i]=TMath::Sin(alpha);
fCoss[i]=TMath::Cos(alpha);
}
fPrimVtx[0]=0;
fPrimVtx[1]=0;
fPrimVtx[2]=0;
}
AliTPCTransform::~AliTPCTransform() {
}
void AliTPCTransform::SetPrimVertex(Double_t *vtx){
fPrimVtx[0]=vtx[0];
fPrimVtx[1]=vtx[1];
fPrimVtx[2]=vtx[2];
}
void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t ,
Int_t ) {
if (!fCurrentRecoParam) {
return;
}
Int_t row=TMath::Nint(x[0]);
Int_t pad=TMath::Nint(x[1]);
Int_t sector=i[0];
AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
AliTPCCalPad * time0TPC = calib->GetPadTime0();
AliTPCCalPad * distortionMapY = calib->GetDistortionMap(0);
AliTPCCalPad * distortionMapZ = calib->GetDistortionMap(1);
AliTPCCalPad * distortionMapR = calib->GetDistortionMap(2);
AliTPCParam * param = calib->GetParameters();
AliTPCCorrection * correction = calib->GetTPCComposedCorrection();
if (!correction) correction = calib->GetTPCComposedCorrection(AliTracker::GetBz());
if (!time0TPC){
AliFatal("Time unisochronity missing");
return ;
}
AliTPCCorrection * correctionDelta = calib->GetTPCComposedCorrectionDelta();
if (!param){
AliFatal("Parameters missing");
return;
}
Double_t xx[3];
if (!calib->HasAlignmentOCDB()) x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad);
Local2RotatedGlobal(sector,x);
RotatedGlobal2Global(sector,x);
if(fCurrentRecoParam->GetUseExBCorrection()) {
calib->GetExB()->Correct(x,xx);
} else {
xx[0] = x[0];
xx[1] = x[1];
xx[2] = x[2];
}
if(fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
Float_t distPoint[3]={static_cast<Float_t>(xx[0]),static_cast<Float_t>(xx[1]),static_cast<Float_t>(xx[2])};
correction->CorrectPoint(distPoint, sector);
xx[0]=distPoint[0];
xx[1]=distPoint[1];
xx[2]=distPoint[2];
if (correctionDelta&&fCurrentRecoParam->GetUseAlignmentTime()){
Float_t distPointDelta[3]={static_cast<Float_t>(xx[0]),static_cast<Float_t>(xx[1]),static_cast<Float_t>(xx[2])};
correctionDelta->CorrectPoint(distPointDelta, sector);
xx[0]=distPointDelta[0];
xx[1]=distPointDelta[1];
xx[2]=distPointDelta[2];
}
}
if (fCurrentRecoParam->GetUseTOFCorrection()){
const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
Float_t sign=1;
if (sector < kNIS) {
sign = (sector < kNIS/2) ? 1 : -1;
} else {
sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
}
Float_t deltaDr =0;
Float_t dist=0;
dist+=(fPrimVtx[0]-x[0])*(fPrimVtx[0]-x[0]);
dist+=(fPrimVtx[1]-x[1])*(fPrimVtx[1]-x[1]);
dist+=(fPrimVtx[2]-x[2])*(fPrimVtx[2]-x[2]);
dist = TMath::Sqrt(dist);
deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C();
xx[2]+=sign*deltaDr;
}
Global2RotatedGlobal(sector,xx);
if (distortionMapY ){
AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
Double_t bzField = magF->SolenoidField()/10.;
Double_t vdrift = param->GetDriftV()/1000000.;
Double_t ezField = 400;
if (sector%36<18) ezField*=-1;
Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
Double_t c0=1./(1.+wt*wt);
Double_t c1=wt/c0;
if (fCurrentRecoParam->GetUseFieldCorrection()&0x2)
if (distortionMapY){
xx[1]-= c0*distortionMapY->GetCalROC(sector)->GetValue(row,pad);
xx[0]-= c1*distortionMapY->GetCalROC(sector)->GetValue(row,pad);
}
if (fCurrentRecoParam->GetUseFieldCorrection()&0x4)
if (distortionMapZ)
xx[2]-=distortionMapZ->GetCalROC(sector)->GetValue(row,pad);
if (fCurrentRecoParam->GetUseFieldCorrection()&0x8)
if (distortionMapR){
xx[0]-= c0*distortionMapR->GetCalROC(sector)->GetValue(row,pad);
xx[1]-=-c1*distortionMapR->GetCalROC(sector)->GetValue(row,pad)*wt;
}
}
x[0]=xx[0];x[1]=xx[1];x[2]=xx[2];
}
void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
if (!fCurrentRecoParam) return;
const Int_t kMax =60;
static Int_t lastStamp=-1;
static Double_t lastCorr = 1;
AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
AliTPCParam * param = calib->GetParameters();
AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun);
Double_t driftCorr = 1.;
if (driftCalib){
if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){
driftCorr = lastCorr;
}else{
driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5;
lastCorr=driftCorr;
lastStamp=fCurrentTimeStamp;
}
}
static Double_t vdcorrectionTime=1;
static Double_t vdcorrectionTimeGY=0;
static Double_t time0corrTime=0;
static Double_t deltaZcorrTime=0;
static Int_t lastStampT=-1;
if (lastStampT!=(Int_t)fCurrentTimeStamp){
lastStampT=fCurrentTimeStamp;
if(fCurrentRecoParam->GetUseDriftCorrectionTime()>0) {
vdcorrectionTime = (1+AliTPCcalibDB::Instance()->
GetVDriftCorrectionTime(fCurrentTimeStamp,
fCurrentRun,
sector%36>=18,
fCurrentRecoParam->GetUseDriftCorrectionTime()));
time0corrTime= AliTPCcalibDB::Instance()->
GetTime0CorrectionTime(fCurrentTimeStamp,
fCurrentRun,
sector%36>=18,
fCurrentRecoParam->GetUseDriftCorrectionTime());
deltaZcorrTime= AliTPCcalibDB::Instance()->
GetVDriftCorrectionDeltaZ(fCurrentTimeStamp,
fCurrentRun,
sector%36>=18,
0);
}
if(fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
Double_t corrGy= AliTPCcalibDB::Instance()->
GetVDriftCorrectionGy(fCurrentTimeStamp,
AliTPCcalibDB::Instance()->GetRun(),
sector%36>=18,
fCurrentRecoParam->GetUseDriftCorrectionGY());
vdcorrectionTimeGY = corrGy;
}
}
if (!param){
AliFatal("Parameters missing");
return;
}
Int_t row=TMath::Nint(x[0]);
const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
Double_t sign = 1.;
Double_t zwidth = param->GetZWidth()*driftCorr;
Float_t xyzPad[3];
AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad);
if (AliTPCRecoParam:: GetUseTimeCalibration()) zwidth*=vdcorrectionTime*(1+xyzPad[1]*vdcorrectionTimeGY);
Double_t padWidth = 0;
Double_t padLength = 0;
Double_t maxPad = 0;
if (sector < kNIS) {
maxPad = param->GetNPadsLow(row);
sign = (sector < kNIS/2) ? 1 : -1;
padLength = param->GetPadPitchLength(sector,row);
padWidth = param->GetPadPitchWidth(sector);
} else {
maxPad = param->GetNPadsUp(row);
sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
padLength = param->GetPadPitchLength(sector,row);
padWidth = param->GetPadPitchWidth(sector);
}
x[0] = param->GetPadRowRadii(sector,row);
x[1]=(x[1]-0.5*maxPad)*padWidth;
if (sector%36>17){
x[1]*=-1;
}
if (AliTPCcalibDB::Instance()->IsTrgL0()){
AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
if (ctp){
Double_t delay = ctp->GetDelayL1L0()*0.000000025;
x[2]-=delay/param->GetTSample();
}
}
x[2]-= param->GetNTBinsL1();
x[2]*= zwidth;
x[2]-= 3.*param->GetZSigma() + time0corrTime;
x[2] = sign*( param->GetZLength(sector) - x[2]);
x[2]-=deltaZcorrTime;
}
void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
Double_t cos,sin;
GetCosAndSin(sector,cos,sin);
Double_t tmp=x[0];
x[0]= cos*tmp-sin*x[1];
x[1]=+sin*tmp+cos*x[1];
}
void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
Double_t cos,sin;
GetCosAndSin(sector,cos,sin);
Double_t tmp=x[0];
x[0]= cos*tmp+sin*x[1];
x[1]= -sin*tmp+cos*x[1];
}
void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
Double_t &sin) const {
cos=fCoss[sector%18];
sin=fSins[sector%18];
}
void AliTPCTransform::ApplyTransformations(Double_t *, Int_t ){
}