]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/TPCbase/AliTPCBoundaryVoltError.cxx
doxy: TPC/TPCbase converted
[u/mrichter/AliRoot.git] / TPC / TPCbase / AliTPCBoundaryVoltError.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /// \class AliTPCBoundaryVoltError
17 ///
18 ///   <h2> AliTPCBoundaryVoltError class   </h2>
19 ///   This class calculates the space point distortions due to residual voltage errors on
20 ///   the main boundaries of the TPC. For example, the inner vessel of the TPC is shifted
21 ///   by a certain amount, whereas the ROCs on the A side and the C side follow this mechanical
22 ///   shift (at the inner vessel) in z direction. This example can be named "conical deformation"
23 ///   of the TPC field cage (see example below).
24 ///
25 ///   The boundary conditions can be set via two arrays (A and C side) which contain the
26 ///   residual voltage setting modeling a possible shift or an inhomogeneity on the TPC field
27 ///   cage. In order to avoid that the user splits the Central Electrode (CE), the settings for
28 ///   the C side is taken from the array on the A side (points: A.6 and A.7). The region betweem
29 ///    the points is interpolated linearly onto the boundaries.
30 ///
31 ///   The class uses the PoissonRelaxation2D (see AliTPCCorrection) to calculate the resulting
32 ///   electrical field inhomogeneities in the (r,z)-plane. Then, the Langevin-integral formalism
33 ///   is used to calculate the space point distortions.
34 ///   Note: This class assumes a homogeneous magnetic field.
35 ///
36 ///   One has two possibilities when calculating the $dz$ distortions. The resulting distortions
37 ///   are purely due to the change of the drift velocity (along with the change of the drift field)
38 ///   when the SetROCDisplacement is FALSE. This emulates for example a Gating-Grid Voltage offset
39 ///   without moving the ROCs. When the flag is set to TRUE, the ROCs are assumed to be misaligned
40 ///   and the corresponding offset in z is added.
41 /// ![Picture from ROOT macro](AliTPCBoundaryVoltError_cxx_1511bb7.png)
42 ///
43 /// \author Jim Thomas, Stefan Rossegger
44 /// \date 01/06/2010
45
46
47 #include "AliMagF.h"
48 #include "TGeoGlobalMagField.h"
49 #include "AliTPCcalibDB.h"
50 #include "AliTPCParam.h"
51 #include "AliLog.h"
52 #include "TMatrixD.h"
53
54 #include "TMath.h"
55 #include "AliTPCROC.h"
56 #include "AliTPCBoundaryVoltError.h"
57
58 /// \cond CLASSIMP
59 ClassImp(AliTPCBoundaryVoltError)
60 /// \endcond
61
62 AliTPCBoundaryVoltError::AliTPCBoundaryVoltError()
63   : AliTPCCorrection("BoundaryVoltError","Boundary Voltage Error"),
64     fC0(0.),fC1(0.),
65     fROCdisplacement(kTRUE),
66     fInitLookUp(kFALSE)
67 {
68   //
69   // default constructor
70   //
71   for (Int_t i=0; i<8; i++){
72     fBoundariesA[i]= 0;  
73     if (i<6) fBoundariesC[i]= 0;
74   }
75 }
76
77 AliTPCBoundaryVoltError::~AliTPCBoundaryVoltError() {
78   /// default destructor
79
80 }
81
82
83
84
85 Bool_t AliTPCBoundaryVoltError::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
86   /// Add correction  and make them compact
87   /// Assumptions:
88   ///  - origin of distortion/correction are additive
89   ///  - only correction ot the same type supported ()
90
91   if (corr==NULL) {
92     AliError("Zerro pointer - correction");
93     return kFALSE;
94   }  
95   AliTPCBoundaryVoltError* corrC = dynamic_cast<AliTPCBoundaryVoltError *>(corr);
96   if (corrC == NULL) {
97     AliError(TString::Format("Inconsistent class types: %s\%s",IsA()->GetName(),corr->IsA()->GetName()).Data());
98     return kFALSE;
99   }
100   if (fROCdisplacement!=corrC->fROCdisplacement){
101     AliError(TString::Format("Inconsistent fROCdisplacement : %s\%s",IsA()->GetName(),corr->IsA()->GetName()).Data());
102     return kFALSE;    
103   }
104   for (Int_t i=0;i <8; i++){
105     fBoundariesA[i]+= corrC->fBoundariesA[i]*weight;
106     fBoundariesC[i]+= corrC->fBoundariesC[i]*weight;
107   }
108   //
109   return kTRUE;
110 }
111
112
113
114
115 void AliTPCBoundaryVoltError::Init() {
116   /// Initialization funtion
117
118   AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
119   if (!magF) AliError("Magneticd field - not initialized");
120   Double_t bzField = magF->SolenoidField()/10.; //field in T
121   AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
122   if (!param) AliError("Parameters - not initialized");
123   Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us]   // From dataBase: to be updated: per second (ideally)
124   Double_t ezField = 400; // [V/cm]   // to be updated: never (hopefully)
125   Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ; 
126   // Correction Terms for effective omegaTau; obtained by a laser calibration run
127   SetOmegaTauT1T2(wt,fT1,fT2);
128
129   InitBoundaryVoltErrorDistortion();
130 }
131
132 void AliTPCBoundaryVoltError::Update(const TTimeStamp &/*timeStamp*/) {
133   /// Update function
134
135   AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
136   if (!magF) AliError("Magneticd field - not initialized");
137   Double_t bzField = magF->SolenoidField()/10.; //field in T
138   AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
139   if (!param) AliError("Parameters - not initialized");
140   Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us]  // From dataBase: to be updated: per second (ideally)
141   Double_t ezField = 400; // [V/cm]   // to be updated: never (hopefully)
142   Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ; 
143   // Correction Terms for effective omegaTau; obtained by a laser calibration run
144   SetOmegaTauT1T2(wt,fT1,fT2);
145
146 }
147
148
149
150 void AliTPCBoundaryVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
151   /// Calculates the correction due e.g. residual voltage errors on the TPC boundaries
152
153   if (!fInitLookUp) {
154     AliInfo("Lookup table was not initialized!  Perform the inizialisation now ...");
155     InitBoundaryVoltErrorDistortion();
156   }
157
158   Int_t   order     = 1 ;               // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2         
159                                         // note that the poisson solution was linearly mirroed on this grid!
160   Double_t intEr, intEphi, intdEz ;
161   Double_t r, phi, z ;
162   Int_t    sign;
163
164   r      =  TMath::Sqrt( x[0]*x[0] + x[1]*x[1] ) ;
165   phi    =  TMath::ATan2(x[1],x[0]) ;
166   if ( phi < 0 ) phi += TMath::TwoPi() ;                   // Table uses phi from 0 to 2*Pi
167   z      =  x[2] ;                                         // Create temporary copy of x[2]
168
169   if ( (roc%36) < 18 ) {
170     sign =  1;       // (TPC A side)
171   } else {
172     sign = -1;       // (TPC C side)
173   }
174   
175   if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
176   if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE
177   
178
179   intEphi = 0.0;  // Efield is symmetric in phi - 2D calculation
180
181   if ( (sign==1 && z<0) || (sign==-1 && z>0) ) // just a consistency check
182     AliError("ROC number does not correspond to z coordinate! Calculation of distortions is most likely wrong!");
183
184   // Get the E field integral
185   Interpolate2DEdistortion( order, r, z, fLookUpErOverEz, intEr );
186   // Get DeltaEz field integral
187   Interpolate2DEdistortion( order, r, z, fLookUpDeltaEz, intdEz );
188   
189   // Calculate distorted position
190   if ( r > 0.0 ) {
191     phi =  phi + ( fC0*intEphi - fC1*intEr ) / r;      
192     r   =  r   + ( fC0*intEr   + fC1*intEphi );  
193   }
194   
195   // Calculate correction in cartesian coordinates
196   dx[0] = r * TMath::Cos(phi) - x[0];
197   dx[1] = r * TMath::Sin(phi) - x[1]; 
198   dx[2] = intdEz;  // z distortion - (internally scaled with driftvelocity dependency 
199                    // on the Ez field plus the actual ROC misalignment (if set TRUE)
200
201
202 }
203
204 void AliTPCBoundaryVoltError::InitBoundaryVoltErrorDistortion() {
205   /// Initialization of the Lookup table which contains the solutions of the
206   /// Dirichlet boundary problem
207
208   const Float_t  gridSizeR   =  (fgkOFCRadius-fgkIFCRadius) / (kRows-1) ;
209   const Float_t  gridSizeZ   =  fgkTPCZ0 / (kColumns-1) ;
210
211   TMatrixD voltArrayA(kRows,kColumns), voltArrayC(kRows,kColumns); // boundary vectors
212   TMatrixD chargeDensity(kRows,kColumns);                              // dummy charge
213   TMatrixD arrayErOverEzA(kRows,kColumns), arrayErOverEzC(kRows,kColumns); // solution
214   TMatrixD arrayDeltaEzA(kRows,kColumns),  arrayDeltaEzC(kRows,kColumns); // solution
215
216   Double_t  rList[kRows], zedList[kColumns] ;
217   
218   // Fill arrays with initial conditions.  V on the boundary and ChargeDensity in the volume.      
219   for ( Int_t j = 0 ; j < kColumns ; j++ ) {
220     Double_t zed = j*gridSizeZ ;
221     zedList[j] = zed ;
222     for ( Int_t i = 0 ; i < kRows ; i++ )  {
223       Double_t radius = fgkIFCRadius + i*gridSizeR ;
224       rList[i]           = radius ;
225       voltArrayA(i,j)        = 0;  // Initialize voltArrayA to zero
226       voltArrayC(i,j)        = 0;  // Initialize voltArrayC to zero
227       chargeDensity(i,j)     = 0;  // Initialize ChargeDensity to zero - not used in this class
228     }
229   }      
230
231
232   // check if boundary values are the same for the C side (for later, saving some calculation time)
233
234   Int_t symmetry = -1; // assume that  A and C side are identical (but anti-symmetric!) // e.g conical deformation
235   Int_t sVec[8];
236
237   // check if boundaries are different (regardless the sign)
238   for (Int_t i=0; i<8; i++) { 
239     if (TMath::Abs(TMath::Abs(fBoundariesA[i]) - TMath::Abs(fBoundariesC[i])) > 1e-5) 
240       symmetry = 0;  
241     sVec[i] = (Int_t)( TMath::Sign((Float_t)1.,fBoundariesA[i]) * TMath::Sign((Float_t)1.,fBoundariesC[i])); 
242   }
243   if (symmetry==-1) { // still the same values?
244     // check the kind of symmetry , if even ...
245     if (sVec[0]==1 && sVec[1]==1 && sVec[2]==1 && sVec[3]==1 && sVec[4]==1 && sVec[5]==1 && sVec[6]==1 && sVec[7]==1 ) 
246       symmetry =  1;
247     else if (sVec[0]==-1 && sVec[1]==-1 && sVec[2]==-1 && sVec[3]==-1 && sVec[4]==-1 && sVec[5]==-1 && sVec[6]==-1 && sVec[7]==-1 ) 
248       symmetry = -1;
249     else
250       symmetry =  0; // some of the values differ in the sign -> neither symmetric nor antisymmetric
251   }
252
253
254
255   // Solve the electrosatic problem in 2D 
256
257   // Fill the complete Boundary vectors
258   // Start at IFC at CE and work anti-clockwise through IFC, ROC, OFC, and CE (clockwise for C side)
259   for ( Int_t j = 0 ; j < kColumns ; j++ ) {
260     Double_t zed = j*gridSizeZ ;
261     for ( Int_t i = 0 ; i < kRows ; i++ ) { 
262       Double_t radius = fgkIFCRadius + i*gridSizeR ;
263
264       // A side boundary vectors
265       if ( i == 0 ) voltArrayA(i,j) += zed   *((fBoundariesA[1]-fBoundariesA[0])/((kColumns-1)*gridSizeZ))
266         + fBoundariesA[0] ; // IFC
267       if ( j == kColumns-1 ) voltArrayA(i,j) += (radius-fgkIFCRadius)*((fBoundariesA[3]-fBoundariesA[2])/((kRows-1)*gridSizeR))
268         + fBoundariesA[2] ; // ROC
269       if ( i == kRows-1 ) voltArrayA(i,j) += zed   *((fBoundariesA[4]-fBoundariesA[5])/((kColumns-1)*gridSizeZ))
270         + fBoundariesA[5] ; // OFC
271       if ( j == 0 ) voltArrayA(i,j) += (radius-fgkIFCRadius)*((fBoundariesA[6]-fBoundariesA[7])/((kRows-1)*gridSizeR))
272         + fBoundariesA[7] ; // CE
273       
274       if (symmetry==0) {
275         // C side boundary vectors
276         if ( i == 0 ) voltArrayC(i,j) += zed   *((fBoundariesC[1]-fBoundariesC[0])/((kColumns-1)*gridSizeZ))
277           + fBoundariesC[0] ; // IFC
278         if ( j == kColumns-1 ) voltArrayC(i,j) += (radius-fgkIFCRadius)*((fBoundariesC[3]-fBoundariesC[2])/((kRows-1)*gridSizeR))
279           + fBoundariesC[2] ; // ROC
280         if ( i == kRows-1 ) voltArrayC(i,j) += zed   *((fBoundariesC[4]-fBoundariesC[5])/((kColumns-1)*gridSizeZ))
281           + fBoundariesC[5] ; // OFC
282         if ( j == 0 ) voltArrayC(i,j) += (radius-fgkIFCRadius)*((fBoundariesC[6]-fBoundariesC[7])/((kRows-1)*gridSizeR))
283           + fBoundariesC[7] ; // CE
284       }
285
286     }
287   }
288
289   voltArrayA(0,0)               *= 0.5 ; // Use average boundary condition at corner
290   voltArrayA(kRows-1,0)         *= 0.5 ; // Use average boundary condition at corner
291   voltArrayA(0,kColumns-1)      *= 0.5 ; // Use average boundary condition at corner
292   voltArrayA(kRows-1,kColumns-1)*= 0.5 ; // Use average boundary condition at corner
293
294   if (symmetry==0) {
295     voltArrayC(0,0)               *= 0.5 ; // Use average boundary condition at corner
296     voltArrayC(kRows-1,0)         *= 0.5 ; // Use average boundary condition at corner
297     voltArrayC(0,kColumns-1)      *= 0.5 ; // Use average boundary condition at corner
298     voltArrayC(kRows-1,kColumns-1)*= 0.5 ; // Use average boundary condition at corner
299   }
300
301
302   // always solve the problem on the A side
303   PoissonRelaxation2D( voltArrayA, chargeDensity, arrayErOverEzA, arrayDeltaEzA, 
304                        kRows, kColumns, kIterations, fROCdisplacement ) ;
305
306   if (symmetry!=0) { // A and C side are the same ("anti-symmetric" or "symmetric")
307     for ( Int_t j = 0 ; j < kColumns ; j++ ) {
308       for ( Int_t i = 0 ; i < kRows ; i++ ) { 
309         arrayErOverEzC(i,j) = symmetry*arrayErOverEzA(i,j);
310         arrayDeltaEzC(i,j) = -symmetry*arrayDeltaEzA(i,j);
311       }
312     }
313   } else if (symmetry==0) { // A and C side are different - Solve the problem on the C side too
314     PoissonRelaxation2D( voltArrayC, chargeDensity, arrayErOverEzC, arrayDeltaEzC,
315                          kRows, kColumns, kIterations, fROCdisplacement ) ;
316     for ( Int_t j = 0 ; j < kColumns ; j++ ) {
317       for ( Int_t i = 0 ; i < kRows ; i++ ) { 
318         arrayDeltaEzC(i,j) = -arrayDeltaEzC(i,j); // negative z coordinate!
319       }
320     }
321   }
322
323   // Interpolate results onto standard grid for Electric Fields
324   Int_t ilow=0, jlow=0 ;
325   Double_t z,r;
326   Float_t saveEr[2] ;         
327   Float_t saveEz[2] ;         
328   for ( Int_t i = 0 ; i < kNZ ; ++i )  {
329     z = TMath::Abs( fgkZList[i] ) ;
330     for ( Int_t j = 0 ; j < kNR ; ++j ) {
331       // Linear interpolation !!
332       r = fgkRList[j] ;
333       Search( kRows,   rList, r, ilow ) ;          // Note switch - R in rows and Z in columns
334       Search( kColumns, zedList, z, jlow ) ;
335       if ( ilow < 0 ) ilow = 0 ;                   // check if out of range
336       if ( jlow < 0 ) jlow = 0 ;   
337       if ( ilow + 1  >=  kRows - 1 ) ilow =  kRows - 2 ;              
338       if ( jlow + 1  >=  kColumns - 1 ) jlow =  kColumns - 2 ; 
339       
340       if (fgkZList[i]>0) {         // A side solution
341         saveEr[0] = arrayErOverEzA(ilow,jlow) + 
342           (arrayErOverEzA(ilow,jlow+1)-arrayErOverEzA(ilow,jlow))*(z-zedList[jlow])/gridSizeZ ;
343         saveEr[1] = arrayErOverEzA(ilow+1,jlow) + 
344           (arrayErOverEzA(ilow+1,jlow+1)-arrayErOverEzA(ilow+1,jlow))*(z-zedList[jlow])/gridSizeZ ;
345         saveEz[0] = arrayDeltaEzA(ilow,jlow) + 
346           (arrayDeltaEzA(ilow,jlow+1)-arrayDeltaEzA(ilow,jlow))*(z-zedList[jlow])/gridSizeZ ;
347         saveEz[1] = arrayDeltaEzA(ilow+1,jlow) + 
348           (arrayDeltaEzA(ilow+1,jlow+1)-arrayDeltaEzA(ilow+1,jlow))*(z-zedList[jlow])/gridSizeZ ;
349
350       } else if (fgkZList[i]<0) {  // C side solution
351         saveEr[0] = arrayErOverEzC(ilow,jlow) + 
352           (arrayErOverEzC(ilow,jlow+1)-arrayErOverEzC(ilow,jlow))*(z-zedList[jlow])/gridSizeZ ;
353         saveEr[1] = arrayErOverEzC(ilow+1,jlow) + 
354           (arrayErOverEzC(ilow+1,jlow+1)-arrayErOverEzC(ilow+1,jlow))*(z-zedList[jlow])/gridSizeZ ;
355         saveEz[0] = arrayDeltaEzC(ilow,jlow) + 
356           (arrayDeltaEzC(ilow,jlow+1)-arrayDeltaEzC(ilow,jlow))*(z-zedList[jlow])/gridSizeZ ;
357         saveEz[1] = arrayDeltaEzC(ilow+1,jlow) + 
358           (arrayDeltaEzC(ilow+1,jlow+1)-arrayDeltaEzC(ilow+1,jlow))*(z-zedList[jlow])/gridSizeZ ;
359
360       } else {
361         AliWarning("Field calculation at z=0 (CE) is not allowed!");
362         saveEr[0]=0; saveEr[1]=0;
363         saveEz[0]=0; saveEz[1]=0;
364       }
365       fLookUpErOverEz[i][j] = saveEr[0] + (saveEr[1]-saveEr[0])*(r-rList[ilow])/gridSizeR ;
366       fLookUpDeltaEz[i][j]  = saveEz[0] + (saveEz[1]-saveEz[0])*(r-rList[ilow])/gridSizeR ;
367     }
368   }
369   
370   voltArrayA.Clear();
371   voltArrayC.Clear();
372   chargeDensity.Clear();
373   arrayErOverEzA.Clear();
374   arrayErOverEzC.Clear();
375   arrayDeltaEzA.Clear();
376   arrayDeltaEzC.Clear();
377   
378   fInitLookUp = kTRUE;
379
380 }
381
382 void AliTPCBoundaryVoltError::Print(const Option_t* option) const {
383   /// Print function to check the settings of the boundary vectors
384   /// option=="a" prints the C0 and C1 coefficents for calibration purposes
385
386   TString opt = option; opt.ToLower();
387   printf("%s\n",GetTitle());
388   printf(" - Voltage settings (on the TPC boundaries) - linearly interpolated\n");
389   printf("  : A-side (anti-clockwise)\n"); 
390   printf("     (0,1):\t IFC (CE) : %3.1f V \t IFC (ROC): %3.1f V \n",fBoundariesA[0],fBoundariesA[1]);
391   printf("     (2,3):\t ROC (IFC): %3.1f V \t ROC (OFC): %3.1f V \n",fBoundariesA[2],fBoundariesA[3]);
392   printf("     (4,5):\t OFC (ROC): %3.1f V \t OFC (CE) : %3.1f V \n",fBoundariesA[4],fBoundariesA[5]);
393   printf("     (6,7):\t CE  (OFC): %3.1f V \t CE  (IFC): %3.1f V \n",fBoundariesA[6],fBoundariesA[7]);
394   printf("  : C-side (clockwise)\n"); 
395   printf("     (0,1):\t IFC (CE) : %3.1f V \t IFC (ROC): %3.1f V \n",fBoundariesC[0],fBoundariesC[1]);
396   printf("     (2,3):\t ROC (IFC): %3.1f V \t ROC (OFC): %3.1f V \n",fBoundariesC[2],fBoundariesC[3]);
397   printf("     (4,5):\t OFC (ROC): %3.1f V \t OFC (CE) : %3.1f V \n",fBoundariesC[4],fBoundariesC[5]);
398   printf("     (6,7):\t CE  (OFC): %3.1f V \t CE  (IFC): %3.1f V \n",fBoundariesC[6],fBoundariesC[7]);
399
400   // Check wether the settings of the Central Electrode agree (on the A and C side)
401   // Note: they have to be antisymmetric!
402   if (( TMath::Abs(fBoundariesA[6]+fBoundariesC[6])>1e-5) || ( TMath::Abs(fBoundariesA[7]+fBoundariesC[7])>1e-5 ) ){
403     AliWarning("Boundary parameters for the Central Electrode (CE) are not anti-symmetric! HOW DID YOU MANAGE THAT?");
404     AliWarning("Congratulations, you just splitted the Central Electrode of the TPC!");
405     AliWarning("Non-physical settings of the boundary parameter at the Central Electrode");
406   }
407
408   if (opt.Contains("a")) { // Print all details
409     printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
410     printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
411   } 
412    
413   if (!fInitLookUp) 
414     AliError("Lookup table was not initialized! You should do InitBoundaryVoltErrorDistortion() ...");
415
416 }
417
418
419 void AliTPCBoundaryVoltError::SetBoundariesA(Float_t boundariesA[8]){
420   /// set voltage errors on the TPC boundaries - A side
421   ///
422   /// Start at IFC at the Central electrode and work anti-clockwise (clockwise for C side) through
423   /// IFC, ROC, OFC, and CE. The boundary conditions are currently defined to be a linear
424   /// interpolation between pairs of numbers in the Boundary (e.g. fBoundariesA) vector.
425   /// The first pair of numbers represent the beginning and end of the Inner Field cage, etc.
426   /// The unit of the error potential vector is [Volt], whereas 1mm shift of the IFC would
427   /// correspond to ~ 40 V
428   ///
429   /// Note: The setting for the CE will be passed to the C side!
430
431   for (Int_t i=0; i<8; i++) {
432     fBoundariesA[i]= boundariesA[i];  
433     if (i>5) fBoundariesC[i]= -boundariesA[i]; // setting for the CE is passed to C side
434   }
435   fInitLookUp=kFALSE;
436 }
437 void AliTPCBoundaryVoltError::SetBoundariesC(Float_t boundariesC[6]){
438   /// set voltage errors on the TPC boundaries - C side
439   ///
440   /// Start at IFC at the Central electrode and work clockwise (for C side) through
441   /// IFC, ROC and OFC. The boundary conditions are currently defined to be a linear
442   /// interpolation between pairs of numbers in the Boundary (e.g. fBoundariesC) vector.
443   /// The first pair of numbers represent the beginning and end of the Inner Field cage, etc.
444   /// The unit of the error potential vector is [Volt], whereas 1mm shift of the IFC would
445   /// correspond to ~ 40 V
446   ///
447   /// Note: The setting for the CE will be taken from the A side (pos 6 and 7)!
448
449   for (Int_t i=0; i<6; i++) {
450     fBoundariesC[i]= boundariesC[i];  
451   }
452   fInitLookUp=kFALSE;
453 }