ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

////////////////////////////////////////////////////////////////////////////
// AliTPCGGVoltError class                                                //
////////////////////////////////////////////////////////////////////////////


#include "AliMagF.h"
#include "TGeoGlobalMagField.h"
#include "AliTPCcalibDB.h"
#include "AliTPCParam.h"
#include "AliLog.h"

#include "AliTPCGGVoltError.h"
#include <TMath.h>

AliTPCGGVoltError::AliTPCGGVoltError()
  : AliTPCCorrection("GGVoltError","GatingGrid (GG) Voltage Error"),
    fC0(0.),fC1(0.),
    fDeltaVGGA(0.),fDeltaVGGC(0.),
    fInitLookUp(kFALSE)
{
  //
  // default constructor
  //
}

AliTPCGGVoltError::~AliTPCGGVoltError() {
  //
  // default destructor
  //
}

void AliTPCGGVoltError::Init() {
  //
  // Init function
  //
  AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
  if (!magF) AliError("Magneticd field - not initialized");
  Double_t bzField = magF->SolenoidField()/10.; //field in T
  AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
  if (!param) AliError("Parameters - not initialized");
  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)
  Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ; 
  //
  SetOmegaTauT1T2(wt,fT1,fT2);
  InitGGVoltErrorDistortion();
  //SetDeltaVGGA(0.0);//  ideally from the database
  //SetDeltaVGGC(0.0);//  ideally from the database
}

void AliTPCGGVoltError::Update(const TTimeStamp &/*timeStamp*/) {
  //
  // Update function
  //
  AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
  if (!magF) AliError("Magneticd field - not initialized");
  Double_t bzField = magF->SolenoidField()/10.; //field in T
  AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
  if (!param) AliError("Parameters - not initialized");
  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)
  Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ; 

  SetOmegaTauT1T2(wt,fT1,fT2);
  //  InitGGVoltErrorDistortion(); // not necessary in here since the Voltage should not change!
}



void AliTPCGGVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {

  //
  // Gated Grid Voltage Error
  //
  // Calculates the effect of having an incorrect voltage on the A or C end plate Gated Grids.
  //
  // Electrostatic Equations from StarNote SN0253 by Howard Wieman.
  //
  
  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
  
  Int_t   order     = 1 ;               // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2         
 
  Double_t intEr, intEphi ;
  Double_t r, phi, z ;
  Int_t    sign ;

  Double_t deltaVGG;
  
  r   = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
  phi = TMath::ATan2(x[1],x[0]);
  if ( phi < 0 ) phi += TMath::TwoPi();                   // Table uses phi from 0 to 2*Pi
  z   = x[2] ;

  if ( (roc%36) < 18 ) {
    sign =  1; 
    deltaVGG = fDeltaVGGA;           // (TPC End A)
  } else {
    sign = -1;                       // (TPC End C)
    deltaVGG = fDeltaVGGC; 
  }

  if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
  if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE

  Interpolate2DEdistortion( order, r, z, fGGVoltErrorER, intEr );
  intEphi = 0.0;  // Efield is symmetric in phi

  // Calculate distorted position
  if ( r > 0.0 ) {
    phi =  phi + deltaVGG*( fC0*intEphi - fC1*intEr ) / r;      
    r   =  r   + deltaVGG*( fC0*intEr   + fC1*intEphi );  
  }
  
  // Calculate correction in cartesian coordinates
  dx[0] = r * TMath::Cos(phi) - x[0];
  dx[1] = r * TMath::Sin(phi) - x[1]; 
  dx[2] = 0.; // z distortion not implemented (1st order distortions) - see e.g. AliTPCBoundaryVoltError-class



}


Float_t AliTPCGGVoltError::GetIntErOverEz(const Float_t x[],const Short_t roc) {
  //
  // This function is purely for calibration purposes
  // Calculates the integral (int Er/Ez dz) for the setted GG voltage offset 
  // 

  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");

  Int_t   order     = 1 ;     // FIXME: so far hardcoded? Linear interpolation = 1, Quadratic = 2         
  
  Double_t intEr;
  Double_t r, phi, z ;
  Int_t    sign ;
  
  Double_t deltaVGG;
  
  r   = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
  phi = TMath::ATan2(x[1],x[0]);
  if ( phi < 0 ) phi += TMath::TwoPi();        // Table uses phi from 0 to 2*Pi
  z   = x[2] ;

  if ( (roc%36) < 18 ) {
    sign =  1; 
    deltaVGG = fDeltaVGGA;           // (TPC End A)
  } else {
    sign = -1;                       // (TPC End C)
    deltaVGG = fDeltaVGGC; 
  }

  if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
  if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE

  Interpolate2DEdistortion(order, r, z, fGGVoltErrorER, intEr );

  return (intEr*deltaVGG);

}

void AliTPCGGVoltError::InitGGVoltErrorDistortion() {
  //
  // Initialization of the Lookup table which contains the solutions of the GG Error problem
  //

  Double_t r,z;
  Int_t nterms = 100 ;
  for ( Int_t i = 0 ; i < kNZ ; ++i ) {
    z = fgkZList[i] ;
    for ( Int_t j = 0 ; j < kNR ; ++j ) {
      r = fgkRList[j] ;
      fGGVoltErrorER[i][j] = 0.0 ; 	    
      Double_t intz = 0.0 ;
      for ( Int_t n = 1 ; n < nterms ; ++n ) {
	Double_t k    =  n * TMath::Pi() / fgkTPCZ0 ;
	Double_t ein  =  0 ;                    // Error potential on the IFC
	Double_t eout =  0 ;                    // Error potential on the OFC
	if ( z < 0 ) {
	  ein   =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;       
	  eout  =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;       
	}
	if ( z == 0 ) continue ;
	if ( z > 0 ) {
	  ein   =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;       
	  eout  =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;       
	}
	Double_t an   =  ein  * TMath::BesselK0( k*fgkOFCRadius ) - eout * TMath::BesselK0( k*fgkIFCRadius ) ;
	Double_t bn   =  eout * TMath::BesselI0( k*fgkIFCRadius ) - ein  * TMath::BesselI0( k*fgkOFCRadius ) ;
	Double_t numerator =
	  an * TMath::BesselI1( k*r ) - bn * TMath::BesselK1( k*r ) ;
	Double_t denominator =
	  TMath::BesselK0( k*fgkOFCRadius ) * TMath::BesselI0( k*fgkIFCRadius ) -
	  TMath::BesselK0( k*fgkIFCRadius ) * TMath::BesselI0( k*fgkOFCRadius ) ;
	Double_t zterm = TMath::Cos( k*(fgkTPCZ0-TMath::Abs(z)) ) - 1 ;
	intz += zterm * numerator / denominator ;
	// Assume series converges, break if small terms
	if ( n>10 && TMath::Abs(intz)*1.e-10 > TMath::Abs(numerator/denominator) ) break;   
      }
      fGGVoltErrorER[i][j] = (Double_t) intz ;

    }
  }
  
  fInitLookUp = kTRUE;
}



void AliTPCGGVoltError::Print(const Option_t* option) const {
  //
  // Print function to check the settings (e.g. voltage offsets)
  // option=="a" prints the C0 and C1 coefficents for calibration purposes
  //

  TString opt = option; opt.ToLower();
  printf("%s\n",GetTitle());
  printf(" - GG Voltage offset: A-side: %3.1f V, C-side: %3.1f V \n",fDeltaVGGA,fDeltaVGGC);  
  if (opt.Contains("a")) { // Print all details
    printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
    printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
  }    

  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");

  
}
 AliTPCGGVoltError.cxx:1
 AliTPCGGVoltError.cxx:2
 AliTPCGGVoltError.cxx:3
 AliTPCGGVoltError.cxx:4
 AliTPCGGVoltError.cxx:5
 AliTPCGGVoltError.cxx:6
 AliTPCGGVoltError.cxx:7
 AliTPCGGVoltError.cxx:8
 AliTPCGGVoltError.cxx:9
 AliTPCGGVoltError.cxx:10
 AliTPCGGVoltError.cxx:11
 AliTPCGGVoltError.cxx:12
 AliTPCGGVoltError.cxx:13
 AliTPCGGVoltError.cxx:14
 AliTPCGGVoltError.cxx:15
 AliTPCGGVoltError.cxx:16
 AliTPCGGVoltError.cxx:17
 AliTPCGGVoltError.cxx:18
 AliTPCGGVoltError.cxx:19
 AliTPCGGVoltError.cxx:20
 AliTPCGGVoltError.cxx:21
 AliTPCGGVoltError.cxx:22
 AliTPCGGVoltError.cxx:23
 AliTPCGGVoltError.cxx:24
 AliTPCGGVoltError.cxx:25
 AliTPCGGVoltError.cxx:26
 AliTPCGGVoltError.cxx:27
 AliTPCGGVoltError.cxx:28
 AliTPCGGVoltError.cxx:29
 AliTPCGGVoltError.cxx:30
 AliTPCGGVoltError.cxx:31
 AliTPCGGVoltError.cxx:32
 AliTPCGGVoltError.cxx:33
 AliTPCGGVoltError.cxx:34
 AliTPCGGVoltError.cxx:35
 AliTPCGGVoltError.cxx:36
 AliTPCGGVoltError.cxx:37
 AliTPCGGVoltError.cxx:38
 AliTPCGGVoltError.cxx:39
 AliTPCGGVoltError.cxx:40
 AliTPCGGVoltError.cxx:41
 AliTPCGGVoltError.cxx:42
 AliTPCGGVoltError.cxx:43
 AliTPCGGVoltError.cxx:44
 AliTPCGGVoltError.cxx:45
 AliTPCGGVoltError.cxx:46
 AliTPCGGVoltError.cxx:47
 AliTPCGGVoltError.cxx:48
 AliTPCGGVoltError.cxx:49
 AliTPCGGVoltError.cxx:50
 AliTPCGGVoltError.cxx:51
 AliTPCGGVoltError.cxx:52
 AliTPCGGVoltError.cxx:53
 AliTPCGGVoltError.cxx:54
 AliTPCGGVoltError.cxx:55
 AliTPCGGVoltError.cxx:56
 AliTPCGGVoltError.cxx:57
 AliTPCGGVoltError.cxx:58
 AliTPCGGVoltError.cxx:59
 AliTPCGGVoltError.cxx:60
 AliTPCGGVoltError.cxx:61
 AliTPCGGVoltError.cxx:62
 AliTPCGGVoltError.cxx:63
 AliTPCGGVoltError.cxx:64
 AliTPCGGVoltError.cxx:65
 AliTPCGGVoltError.cxx:66
 AliTPCGGVoltError.cxx:67
 AliTPCGGVoltError.cxx:68
 AliTPCGGVoltError.cxx:69
 AliTPCGGVoltError.cxx:70
 AliTPCGGVoltError.cxx:71
 AliTPCGGVoltError.cxx:72
 AliTPCGGVoltError.cxx:73
 AliTPCGGVoltError.cxx:74
 AliTPCGGVoltError.cxx:75
 AliTPCGGVoltError.cxx:76
 AliTPCGGVoltError.cxx:77
 AliTPCGGVoltError.cxx:78
 AliTPCGGVoltError.cxx:79
 AliTPCGGVoltError.cxx:80
 AliTPCGGVoltError.cxx:81
 AliTPCGGVoltError.cxx:82
 AliTPCGGVoltError.cxx:83
 AliTPCGGVoltError.cxx:84
 AliTPCGGVoltError.cxx:85
 AliTPCGGVoltError.cxx:86
 AliTPCGGVoltError.cxx:87
 AliTPCGGVoltError.cxx:88
 AliTPCGGVoltError.cxx:89
 AliTPCGGVoltError.cxx:90
 AliTPCGGVoltError.cxx:91
 AliTPCGGVoltError.cxx:92
 AliTPCGGVoltError.cxx:93
 AliTPCGGVoltError.cxx:94
 AliTPCGGVoltError.cxx:95
 AliTPCGGVoltError.cxx:96
 AliTPCGGVoltError.cxx:97
 AliTPCGGVoltError.cxx:98
 AliTPCGGVoltError.cxx:99
 AliTPCGGVoltError.cxx:100
 AliTPCGGVoltError.cxx:101
 AliTPCGGVoltError.cxx:102
 AliTPCGGVoltError.cxx:103
 AliTPCGGVoltError.cxx:104
 AliTPCGGVoltError.cxx:105
 AliTPCGGVoltError.cxx:106
 AliTPCGGVoltError.cxx:107
 AliTPCGGVoltError.cxx:108
 AliTPCGGVoltError.cxx:109
 AliTPCGGVoltError.cxx:110
 AliTPCGGVoltError.cxx:111
 AliTPCGGVoltError.cxx:112
 AliTPCGGVoltError.cxx:113
 AliTPCGGVoltError.cxx:114
 AliTPCGGVoltError.cxx:115
 AliTPCGGVoltError.cxx:116
 AliTPCGGVoltError.cxx:117
 AliTPCGGVoltError.cxx:118
 AliTPCGGVoltError.cxx:119
 AliTPCGGVoltError.cxx:120
 AliTPCGGVoltError.cxx:121
 AliTPCGGVoltError.cxx:122
 AliTPCGGVoltError.cxx:123
 AliTPCGGVoltError.cxx:124
 AliTPCGGVoltError.cxx:125
 AliTPCGGVoltError.cxx:126
 AliTPCGGVoltError.cxx:127
 AliTPCGGVoltError.cxx:128
 AliTPCGGVoltError.cxx:129
 AliTPCGGVoltError.cxx:130
 AliTPCGGVoltError.cxx:131
 AliTPCGGVoltError.cxx:132
 AliTPCGGVoltError.cxx:133
 AliTPCGGVoltError.cxx:134
 AliTPCGGVoltError.cxx:135
 AliTPCGGVoltError.cxx:136
 AliTPCGGVoltError.cxx:137
 AliTPCGGVoltError.cxx:138
 AliTPCGGVoltError.cxx:139
 AliTPCGGVoltError.cxx:140
 AliTPCGGVoltError.cxx:141
 AliTPCGGVoltError.cxx:142
 AliTPCGGVoltError.cxx:143
 AliTPCGGVoltError.cxx:144
 AliTPCGGVoltError.cxx:145
 AliTPCGGVoltError.cxx:146
 AliTPCGGVoltError.cxx:147
 AliTPCGGVoltError.cxx:148
 AliTPCGGVoltError.cxx:149
 AliTPCGGVoltError.cxx:150
 AliTPCGGVoltError.cxx:151
 AliTPCGGVoltError.cxx:152
 AliTPCGGVoltError.cxx:153
 AliTPCGGVoltError.cxx:154
 AliTPCGGVoltError.cxx:155
 AliTPCGGVoltError.cxx:156
 AliTPCGGVoltError.cxx:157
 AliTPCGGVoltError.cxx:158
 AliTPCGGVoltError.cxx:159
 AliTPCGGVoltError.cxx:160
 AliTPCGGVoltError.cxx:161
 AliTPCGGVoltError.cxx:162
 AliTPCGGVoltError.cxx:163
 AliTPCGGVoltError.cxx:164
 AliTPCGGVoltError.cxx:165
 AliTPCGGVoltError.cxx:166
 AliTPCGGVoltError.cxx:167
 AliTPCGGVoltError.cxx:168
 AliTPCGGVoltError.cxx:169
 AliTPCGGVoltError.cxx:170
 AliTPCGGVoltError.cxx:171
 AliTPCGGVoltError.cxx:172
 AliTPCGGVoltError.cxx:173
 AliTPCGGVoltError.cxx:174
 AliTPCGGVoltError.cxx:175
 AliTPCGGVoltError.cxx:176
 AliTPCGGVoltError.cxx:177
 AliTPCGGVoltError.cxx:178
 AliTPCGGVoltError.cxx:179
 AliTPCGGVoltError.cxx:180
 AliTPCGGVoltError.cxx:181
 AliTPCGGVoltError.cxx:182
 AliTPCGGVoltError.cxx:183
 AliTPCGGVoltError.cxx:184
 AliTPCGGVoltError.cxx:185
 AliTPCGGVoltError.cxx:186
 AliTPCGGVoltError.cxx:187
 AliTPCGGVoltError.cxx:188
 AliTPCGGVoltError.cxx:189
 AliTPCGGVoltError.cxx:190
 AliTPCGGVoltError.cxx:191
 AliTPCGGVoltError.cxx:192
 AliTPCGGVoltError.cxx:193
 AliTPCGGVoltError.cxx:194
 AliTPCGGVoltError.cxx:195
 AliTPCGGVoltError.cxx:196
 AliTPCGGVoltError.cxx:197
 AliTPCGGVoltError.cxx:198
 AliTPCGGVoltError.cxx:199
 AliTPCGGVoltError.cxx:200
 AliTPCGGVoltError.cxx:201
 AliTPCGGVoltError.cxx:202
 AliTPCGGVoltError.cxx:203
 AliTPCGGVoltError.cxx:204
 AliTPCGGVoltError.cxx:205
 AliTPCGGVoltError.cxx:206
 AliTPCGGVoltError.cxx:207
 AliTPCGGVoltError.cxx:208
 AliTPCGGVoltError.cxx:209
 AliTPCGGVoltError.cxx:210
 AliTPCGGVoltError.cxx:211
 AliTPCGGVoltError.cxx:212
 AliTPCGGVoltError.cxx:213
 AliTPCGGVoltError.cxx:214
 AliTPCGGVoltError.cxx:215
 AliTPCGGVoltError.cxx:216
 AliTPCGGVoltError.cxx:217
 AliTPCGGVoltError.cxx:218
 AliTPCGGVoltError.cxx:219
 AliTPCGGVoltError.cxx:220
 AliTPCGGVoltError.cxx:221
 AliTPCGGVoltError.cxx:222
 AliTPCGGVoltError.cxx:223
 AliTPCGGVoltError.cxx:224
 AliTPCGGVoltError.cxx:225
 AliTPCGGVoltError.cxx:226
 AliTPCGGVoltError.cxx:227
 AliTPCGGVoltError.cxx:228
 AliTPCGGVoltError.cxx:229
 AliTPCGGVoltError.cxx:230
 AliTPCGGVoltError.cxx:231
 AliTPCGGVoltError.cxx:232
 AliTPCGGVoltError.cxx:233
 AliTPCGGVoltError.cxx:234
 AliTPCGGVoltError.cxx:235
 AliTPCGGVoltError.cxx:236
 AliTPCGGVoltError.cxx:237
 AliTPCGGVoltError.cxx:238
 AliTPCGGVoltError.cxx:239
 AliTPCGGVoltError.cxx:240
 AliTPCGGVoltError.cxx:241
 AliTPCGGVoltError.cxx:242
 AliTPCGGVoltError.cxx:243