]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCTransform.cxx
Constant extrapolation for gain calibration
[u/mrichter/AliRoot.git] / TPC / AliTPCTransform.cxx
index 3a7be5b7cbc2bf335eebb960ef4cd5b3451c0795..a99c508b460852a024b29ca64d9166b410f9d7fd 100755 (executable)
 #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()
+AliTPCTransform::AliTPCTransform():
+  AliTransform(),
+  fCurrentRecoParam(0),       //! current reconstruction parameters
+  fCurrentRun(0),             //! current run
+  fCurrentTimeStamp(0)        //! current time stamp   
+{
+  //
+  // Speed it up a bit!
+  //
+  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),       //! current reconstruction parameters
+  fCurrentRun(transform.fCurrentRun),             //! current run
+  fCurrentTimeStamp(transform.fCurrentTimeStamp)        //! current time stamp   
 {
   //
   // Speed it up a bit!
@@ -113,14 +141,18 @@ void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
   //                line approximation  
   //
   
-
   Int_t row=TMath::Nint(x[0]);
   Int_t pad=TMath::Nint(x[1]);
   Int_t sector=i[0];
-  AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
+  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();   // first user defined correction  // if does not exist  try to get it from calibDB array
+  if (!correction) correction = calib->GetTPCComposedCorrection(AliTracker::GetBz());
   if (!time0TPC){
     AliFatal("Time unisochronity missing");
   }
@@ -143,33 +175,95 @@ void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
   // Alignment
   //TODO:  calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx);
   RotatedGlobal2Global(sector,x);
+  
+  //
+  // old ExB correction 
   //
+  if(fCurrentRecoParam&&fCurrentRecoParam->GetUseExBCorrection()) {
+
+    calib->GetExB()->Correct(x,xx);
+
+  } else {
+
+    xx[0] = x[0];
+    xx[1] = x[1];
+    xx[2] = x[2];
+  }
+
   //
-  // ExB correction
+  // new composed  correction  - will replace soon ExB correction
   //
-  calib->GetExB()->Correct(x,xx);
+  if(fCurrentRecoParam&&fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
+    Float_t distPoint[3]={xx[0],xx[1],xx[2]};
+    correction->CorrectPoint(distPoint, sector);
+    xx[0]=distPoint[0];
+    xx[1]=distPoint[1];
+    xx[2]=distPoint[2];
+  } 
+
+
   //
   // Time of flight correction
   // 
-  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;
+  if (fCurrentRecoParam&&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);
+    // drift length correction because of TOF
+    // the drift velocity is in cm/s therefore multiplication by 0.01
+    deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C(); 
+    xx[2]+=sign*deltaDr;
   }
-  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[0]-x[2])*(fPrimVtx[0]-x[2]);
-  dist = TMath::Sqrt(dist);
-  // drift length correction because of TOF
-  // the drift velocity is in cm/s therefore multiplication by 0.01
-  deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C(); 
-  xx[2]+=sign*deltaDr;
+  //
+  //
+  //
+
   //
   Global2RotatedGlobal(sector,xx);
+
+  //
+  // Apply non linear distortion correction  
+  //
+  if (distortionMapY ){
+    // wt - to get it form the OCDB
+    // ignore T1 and T2
+    AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+    Double_t bzField = magF->SolenoidField()/10.; //field in T
+    Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us]   // From dataBase: to be updated: per second (ideally)
+    Double_t ezField = 400; // [V/cm]   // to be updated: never (hopefully)
+    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;
+    
+    //can be switch on for each dimension separatelly
+    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];
 }
@@ -186,8 +280,61 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
   //
   //  
   //
+  const  Int_t kMax =60;  // cache for 60 seconds
+  static Int_t lastStamp=-1;  //cached values
+  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){
+    //
+    // caching drift correction - temp. fix
+    // Extremally slow procedure
+    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;
+      
+    }
+  }
+  //
+  // simple caching non thread save
+  static Double_t vdcorrectionTime=1;
+  static Double_t vdcorrectionTimeGY=0;
+  static Double_t time0corrTime=0;
+  static Int_t    lastStampT=-1;
+  //
+  if (lastStampT!=(Int_t)fCurrentTimeStamp){
+    lastStampT=fCurrentTimeStamp;
+    if(fCurrentRecoParam&&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()); 
+    }
+    //
+    if(fCurrentRecoParam&&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");
   }
@@ -196,7 +343,10 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
   //
   const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
   Double_t sign = 1.;
-  Double_t zwidth    = param->GetZWidth();
+  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;
@@ -219,11 +369,28 @@ void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
   // Y coordinate
   //
   x[1]=(x[1]-0.5*maxPad)*padWidth;
+  // pads are mirrorred on C-side
+  if (sector%36>17){
+    x[1]*=-1;
+  }
+  
+  //
+  
   //
   // Z coordinate
   //
+  if (AliTPCcalibDB::Instance()->IsTrgL0()){
+    // by defualt we assume L1 trigger is used - make a correction in case of  L0
+    AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
+    if (ctp){
+      //for TPC standalone runs no ctp info
+      Double_t delay = ctp->GetDelayL1L0()*0.000000025;
+      x[2]-=delay/param->GetTSample();
+    }
+  }
+  x[2]-= param->GetNTBinsL1();
   x[2]*= zwidth;  // tranform time bin to the distance to the ROC
-  x[2]-= 3.*param->GetZSigma() + param->GetNTBinsL1()*zwidth;
+  x[2]-= 3.*param->GetZSigma() + time0corrTime;
   // subtract the time offsets
   x[2] = sign*( param->GetZLength(sector) - x[2]);
 }
@@ -235,8 +402,8 @@ 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];
+  x[0]= cos*tmp-sin*x[1];
+  x[1]=+sin*tmp+cos*x[1];
 }
 
 void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
@@ -246,8 +413,8 @@ 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];
+  x[0]= cos*tmp+sin*x[1];
+  x[1]= -sin*tmp+cos*x[1];
 }
 
 void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
@@ -257,3 +424,12 @@ void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
 }
 
 
+void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){
+  //
+  // Modify global position
+  // xyz    - global xyz position
+  // volID  - volID of detector (sector number)
+  //
+  //
+  
+}