]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCROCVoltError3D.cxx
Triggered Balance Function analysis (multidimensions)
[u/mrichter/AliRoot.git] / TPC / AliTPCROCVoltError3D.cxx
index 4f4514e70172580edfc89d5db07c8a4adf02e538..f93e38dab11833340deee611d363c37981f5e451 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-//////////////////////////////////////////////////////////////////////////////
-//                                                                          //
-// AliTPCROCVoltError3D class                                               //
-// The class calculates the space point distortions due to residual voltage //
-// errors on Read Out Chambers of the TPC in 3D.                            //
-//                                                                          //
-// The class allows "effective Omega Tau" corrections.                      // 
-//                                                                          //
-// NOTE: This class is capable of calculating z distortions due to          //
-//       misalignment and the vd dependency on the residual drift field     //
-//                                                                          //
-// date: 08/08/2010                                                         //
-// Authors: Jim Thomas, Stefan Rossegger                                    //
-//                                                                          //
-// Example usage :                                                          //
-//  AliTPCROCVoltError3D ROCerror;                                            //
-//////////////////////////////////////////////////////////////////////////////
+// _________________________________________________________________
+//
+// Begin_Html
+//   <h2> AliTPCROCVoltError3D class   </h2>    
+//   The class calculates the space point distortions due to z offsets of the 
+//   ROCs via the residual voltage technique (Poisson relaxation) in 3D. 
+//   Since the GG (part of the ROCs) represents the closure of the FC in z direction,
+//   every misalignment in z produces not only dz distortions but also electrical 
+//   field inhomogeneities throughout the volume, which produces additional dr and rd$\phi$ distortions.
+//   <p>
+//   Each ROC can be misaligned (in z direction) in three ways. A general z0 offset, 
+//   an inclination along the x and an inclination along the y axis. The z-misalignment's
+//   can be set via the function SetROCData(TMatrixD *mat) for each single chamber (ROC). 
+//   The array size has to be (72,3) representing the 72 chambers according to the 
+//   offline numbering scheme (IROC: roc$<$36; OROC: roc$\geq$36) and the three misalignment's
+//   (see the source code for further details).
+//   <p>
+//   Internally, these z offsets (unit is cm)  are recalculated into residual voltage 
+//   equivalents in order to make use of the relaxation technique. 
+//   <p>
+//   One has two possibilities when calculating the $dz$ distortions. The resulting 
+//   distortions are purely due to the change of the drift velocity (along with the 
+//   change of the drift field) when the SetROCDisplacement is FALSE. <br>
+//   For this class, this is a rather unphysical setting and should be avoided. <br>
+//   When the flag is set to TRUE, the corresponding offset in z is added to the dz 
+//   calculation of the outer ROCs. <br>
+//   For the Alice TPC gas, both effects are of similar magnitude. This means, if the 
+//   drift length is sufficiently large, a z-offset of a chamber appears to have (approx.) 
+//   twice the magnitude when one looks at the actual dz distortions.
+//   <p>
+//   In addition, this class allows a correction regarding the different arrival times 
+//   of the electrons due to the geometrical difference of the inner and outer chambers.
+//   The impact was simulated via Garfield. If the flag is set via the 
+//   function SetElectronArrivalCorrection, the electron-arrival correction is added to the dz calculation.
+// End_Html
+//
+// Begin_Macro(source)
+//   {
+//   gROOT->SetStyle("Plain"); gStyle->SetPalette(1);
+//   TCanvas *c2 = new TCanvas("cAliTPCROCVoltError3D","cAliTPCROCVoltError3D",500,400); 
+//   AliTPCROCVoltError3D roc; 
+//   roc.SetElectronArrivalCorrection(kFALSE);  // Correction for electron arrival offset, IROC vs OROC
+//   roc.SetROCDisplacement(kTRUE);   // include the chamber offset in z when calculating the dz 
+//   roc.SetOmegaTauT1T2(0,1,1); // B=0
+//   roc.CreateHistoDZinXY(1.,300,300)->Draw("colz"); 
+//   return c2;
+//   } 
+// End_Macro
+//
+// Begin_Html
+//   <p>
+//   Date: 08/08/2010    <br>                                                 
+//   Authors: Jim Thomas, Stefan Rossegger                                
+// End_Html 
+// _________________________________________________________________
+
 
 #include "AliMagF.h"
 #include "TGeoGlobalMagField.h"
@@ -49,8 +88,9 @@ AliTPCROCVoltError3D::AliTPCROCVoltError3D()
   : AliTPCCorrection("ROCVoltErrors","ROC z alignment Errors"),
     fC0(0.),fC1(0.),
     fROCdisplacement(kTRUE),
+    fElectronArrivalCorrection(kTRUE),
     fInitLookUp(kFALSE),
-    fROCDataFileName("$(ALICE_ROOT)/TPC/Calib/maps/TPCROCdzSurvey.root"),  // standard file name of ROC survey
+    fROCDataFileName(""),  
     fdzDataLinFit(0)
 {
   //
@@ -61,12 +101,12 @@ AliTPCROCVoltError3D::AliTPCROCVoltError3D()
   // main input: z alignment of the Read Out chambers
   // see InitROCVoltError3D() function
   for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
-    fLookUpErOverEz[k]   =  new TMatrixD(kNR,kNZ);  
-    fLookUpEphiOverEz[k] =  new TMatrixD(kNR,kNZ);
-    fLookUpDeltaEz[k]    =  new TMatrixD(kNR,kNZ);   
+    fLookUpErOverEz[k]   =  new TMatrixF(kNR,kNZ);  
+    fLookUpEphiOverEz[k] =  new TMatrixF(kNR,kNZ);
+    fLookUpDeltaEz[k]    =  new TMatrixF(kNR,kNZ);   
   }
-
-  SetROCDataFileName(fROCDataFileName); // initialization of fdzDataLinFit is included
+  fROCDataFileName="$ALICE_ROOT/TPC/Calib/maps/TPCROCdzSurvey.root";
+  SetROCDataFileName(fROCDataFileName.Data()); // initialization of fdzDataLinFit is included
 
 }
 
@@ -84,6 +124,16 @@ AliTPCROCVoltError3D::~AliTPCROCVoltError3D() {
   delete fdzDataLinFit;
 }
 
+void AliTPCROCVoltError3D::SetROCData(TMatrixD * matrix){
+  //
+  // Set a z alignment map of the chambers not via a file, but
+  // directly via a TMatrix(72,3), where dz = p0 + p1*(lx-133.4) + p2*ly (all in cm)
+  //
+  if (!fdzDataLinFit) fdzDataLinFit=new TMatrixD(*matrix);
+  else *fdzDataLinFit = *matrix;
+}
+
+
 void AliTPCROCVoltError3D::Init() {
   //
   // Initialization funtion
@@ -100,7 +150,7 @@ void AliTPCROCVoltError3D::Init() {
   // Correction Terms for effective omegaTau; obtained by a laser calibration run
   SetOmegaTauT1T2(wt,fT1,fT2);
 
-  InitROCVoltError3D();
+  if (!fInitLookUp) InitROCVoltError3D();
 }
 
 void AliTPCROCVoltError3D::Update(const TTimeStamp &/*timeStamp*/) {
@@ -120,14 +170,14 @@ void AliTPCROCVoltError3D::Update(const TTimeStamp &/*timeStamp*/) {
 
 }
 
-void  AliTPCROCVoltError3D::SetROCDataFileName(char *const fname) {
+void  AliTPCROCVoltError3D::SetROCDataFileName(const char * fname) {
   //
   // Set / load the ROC data (linear fit of ROC misalignments)
   //
 
   fROCDataFileName = fname;
   
-  TFile f(fROCDataFileName,"READ");
+  TFile f(fROCDataFileName.Data(),"READ");
   TMatrixD *m = (TMatrixD*) f.Get("dzSurveyLinFitData");
   TMatrixD &mf = *m;
 
@@ -153,16 +203,23 @@ void AliTPCROCVoltError3D::GetCorrection(const Float_t x[],const Short_t roc,Flo
   //
   // Calculates the correction due e.g. residual voltage errors on the TPC boundaries
   //   
-
+  const Double_t kEpsilon=Double_t(FLT_MIN);
   if (!fInitLookUp) {
     AliInfo("Lookup table was not initialized! Perform the inizialisation now ...");
     InitROCVoltError3D();
-    return;
+  }
+  static Bool_t forceInit=kTRUE; //temporary needed for back compatibility with old OCDB entries
+  if (forceInit&&fLookUpErOverEz[0]){
+    if (TMath::Abs(fLookUpErOverEz[0]->Sum())<kEpsilon){//temporary needed for back compatibility with old OCDB entries
+      ForceInitROCVoltError3D();
+    }
+    forceInit=kFALSE;
   }
 
-  Int_t   order     = 1 ;               // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2         
+  
+  Int_t   order     = 1 ;    // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2         
 
-  Double_t intEr, intEphi, intDeltaEz;
+  Float_t intEr, intEphi, intDeltaEz;
   Double_t r, phi, z ;
   Int_t    sign;
 
@@ -206,6 +263,26 @@ void AliTPCROCVoltError3D::GetCorrection(const Float_t x[],const Short_t roc,Flo
   dx[2] = intDeltaEz;  // z distortion - (internally scaled with driftvelocity dependency 
                        // on the Ez field plus the actual ROC misalignment (if set TRUE)
 
+
+  if (fElectronArrivalCorrection) {
+
+    // correction for the OROC (in average, a 0.014usec longer drift time
+    // due to different position of the anode wires) -> vd*dt -> 2.64*0.014 = 0.0369 cm
+    // FIXME: correction are token from Magboltz simulations
+    //        should be loaded from a database
+    AliTPCROC * rocInfo = AliTPCROC::Instance();
+    Double_t rCrossingROC  =  (rocInfo->GetPadRowRadii(0,62)+rocInfo->GetPadRowRadii(36,0))/2;
+  
+    if (r>rCrossingROC) {
+      if (sign==1)
+       dx[2] += 0.0369; // A side - negative correction
+      else
+       dx[2] -= 0.0369; // C side - positive correction
+    }
+    
+  }
+
 }
 
 void AliTPCROCVoltError3D::InitROCVoltError3D() {
@@ -273,9 +350,12 @@ void AliTPCROCVoltError3D::InitROCVoltError3D() {
            Float_t phi0    = gridSizePhi * k ;
            
            // To avoid problems at sector boundaries, use an average of +- 1 degree from actual phi location
-           if ( j == (kColumns-1) ) 
+           if ( j == (kColumns-1) ) {
              arrayV(i,j) = 0.5*  ( GetROCVoltOffset( side, radius0, phi0+0.02 ) + GetROCVoltOffset( side, radius0, phi0-0.02 ) ) ;
 
+             if (side==1) // C side
+               arrayV(i,j) = -arrayV(i,j); // minus sign on the C side to allow a consistent usage of global z when setting the boundaries
+           }
          }
        }      
        
@@ -300,9 +380,9 @@ void AliTPCROCVoltError3D::InitROCVoltError3D() {
       for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
        phi = fgkPhiList[k] ;
        
-       TMatrixD &erOverEz   =  *fLookUpErOverEz[k]  ;
-       TMatrixD &ephiOverEz =  *fLookUpEphiOverEz[k];
-       TMatrixD &deltaEz    =  *fLookUpDeltaEz[k]   ;
+       TMatrixF &erOverEz   =  *fLookUpErOverEz[k]  ;
+       TMatrixF &ephiOverEz =  *fLookUpEphiOverEz[k];
+       TMatrixF &deltaEz    =  *fLookUpDeltaEz[k]   ;
        
        for ( Int_t j = 0 ; j < kNZ ; j++ ) {
 
@@ -363,9 +443,21 @@ Float_t AliTPCROCVoltError3D::GetROCVoltOffset(Int_t side, Float_t r0, Float_t p
   if (side==1) roc+=18; // C side
   if (r0>132) roc+=36;  // OROC 
   
-  // linear-plane data:  z = z0 + kx*x + ky*y
+  // linear-plane data:  z = z0 + kx*lx + ky*ly (rotation in local coordinates)
   TMatrixD &fitData = *fdzDataLinFit;
-  Float_t dz = fitData(roc,0)+fitData(roc,1)*xp + fitData(roc,2)*yp; // value in cm
+
+  // local coordinates                                                          
+  Double_t secAlpha = TMath::DegToRad()*(10.+20.*(((Int_t)roc)%18));
+  Float_t lx = xp*TMath::Cos(secAlpha)+yp*TMath::Sin(secAlpha);
+  Float_t ly = yp*TMath::Cos(secAlpha)-xp*TMath::Sin(secAlpha);
+
+  // reference of rotation in lx is at the intersection between OROC and IROC
+  // necessary, since the Fitprozedure is otherwise useless
+  
+  AliTPCROC * rocInfo = AliTPCROC::Instance();
+  Double_t lxRef  = (rocInfo->GetPadRowRadii(0,62)+rocInfo->GetPadRowRadii(36,0))/2;
+  
+  Float_t dz = fitData(roc,0)+fitData(roc,1)*(lx-lxRef) + fitData(roc,2)*ly; // value in cm
 
   // aproximated Voltage-offset-aquivalent to the z misalignment
   // (linearly scaled with the z position)
@@ -375,14 +467,14 @@ Float_t AliTPCROCVoltError3D::GetROCVoltOffset(Int_t side, Float_t r0, Float_t p
   return voltOff;
 }
 
-TH2F * AliTPCROCVoltError3D::CreateHistoOfZSurvey(Int_t side, Int_t nx, Int_t ny) {
+TH2F * AliTPCROCVoltError3D::CreateHistoOfZAlignment(Int_t side, Int_t nx, Int_t ny) {
   //
   // return a simple histogramm containing the input to the poisson solver
   // (z positions of the Read-out chambers, linearly interpolated)
 
   char hname[100];
-  if (side==0) sprintf(hname,"survey_dz_Aside");
-  if (side==1) sprintf(hname,"survey_dz_Cside");
+  if (side==0) snprintf(hname,100,"survey_dz_Aside");
+  if (side==1) snprintf(hname,100,"survey_dz_Cside");
 
   TH2F *h = new TH2F(hname,hname,nx,-250.,250.,ny,-250.,250.);
 
@@ -424,10 +516,25 @@ void AliTPCROCVoltError3D::Print(const Option_t* option) const {
 
   TString opt = option; opt.ToLower();
   printf("%s\n",GetTitle());
-  printf(" - Voltage settings on the TPC Read-Out chambers - linearly interpolated\n");
-  printf("   info: Check the following data-file for more details: %s \n",fROCDataFileName);
+  printf(" - z aligmnet of the TPC Read-Out chambers \n");
+  printf("   (linear interpolation within the chamber:  dz = z0 + kx*(lx-133) + ky*ly [cm] ) \n");
+  printf("   Info: Check the following data-file for more details: %s \n",fROCDataFileName.Data());
 
   if (opt.Contains("a")) { // Print all details
+    TMatrixD &fitData = *fdzDataLinFit;
+    printf(" A side:  IROC   ROCX=(z0,kx,ky): \n");
+    for (Int_t roc = 0; roc<18; roc++) 
+      printf("ROC%d:(%.2e,%.2e,%.2e) ",roc,fitData(roc,0),fitData(roc,1),fitData(roc,2));
+    printf("\n A side:  OROC   ROCX=(z0,kx,ky): \n");
+    for (Int_t roc = 36; roc<54; roc++) 
+      printf("ROC%d:(%.2e,%.2e,%.2e) ",roc,fitData(roc,0),fitData(roc,1),fitData(roc,2));
+    printf("\n C side:  IROC   ROCX=(z0,kx,ky): \n");
+    for (Int_t roc = 18; roc<36; roc++) 
+      printf("ROC%d:(%.2e,%.2e,%.2e) ",roc,fitData(roc,0),fitData(roc,1),fitData(roc,2));
+    printf("\n C side:  OROC   ROCX=(z0,kx,ky): \n");
+    for (Int_t roc = 54; roc<72; roc++) 
+      printf("ROC%d:(%.2e,%.2e,%.2e) ",roc,fitData(roc,0),fitData(roc,1),fitData(roc,2));
+    printf("\n\n");
     printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
     printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
   }