AliRoot Core  a565103 (a565103)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliTPCGGVoltError.cxx
Go to the documentation of this file.
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 
18 
19 
20 #include "AliMagF.h"
21 #include "TGeoGlobalMagField.h"
22 #include "AliTPCcalibDB.h"
23 #include "AliTPCParam.h"
24 #include "AliLog.h"
25 
26 #include "AliTPCGGVoltError.h"
27 #include <TMath.h>
28 
30  : AliTPCCorrection("GGVoltError","GatingGrid (GG) Voltage Error"),
31  fC0(0.),fC1(0.),
32  fDeltaVGGA(0.),fDeltaVGGC(0.),
33  fInitLookUp(kFALSE)
34 {
36 
37 }
38 
41 
42 }
43 
46 
47  AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
48  if (!magF) AliError("Magneticd field - not initialized");
49  Double_t bzField = magF->SolenoidField()/10.; //field in T
51  if (!param) AliError("Parameters - not initialized");
52  Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
53  Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
54  Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
55  //
58  //SetDeltaVGGA(0.0);// ideally from the database
59  //SetDeltaVGGC(0.0);// ideally from the database
60 }
61 
62 void AliTPCGGVoltError::Update(const TTimeStamp &/*timeStamp*/) {
64 
65  AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
66  if (!magF) AliError("Magneticd field - not initialized");
67  Double_t bzField = magF->SolenoidField()/10.; //field in T
69  if (!param) AliError("Parameters - not initialized");
70  Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
71  Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
72  Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
73 
75  // InitGGVoltErrorDistortion(); // not necessary in here since the Voltage should not change!
76 }
77 
78 
79 
80 void AliTPCGGVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
81 
87 
88  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
89 
90  Int_t order = 1 ; // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
91 
92  Double_t intEr, intEphi ;
93  Double_t r, phi, z ;
94  Int_t sign ;
95 
96  Double_t deltaVGG;
97 
98  r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
99  phi = TMath::ATan2(x[1],x[0]);
100  if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
101  z = x[2] ;
102 
103  if ( (roc%36) < 18 ) {
104  sign = 1;
105  deltaVGG = fDeltaVGGA; // (TPC End A)
106  } else {
107  sign = -1; // (TPC End C)
108  deltaVGG = fDeltaVGGC;
109  }
110 
111  if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
112  if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
113 
114  Interpolate2DEdistortion( order, r, z, fGGVoltErrorER, intEr );
115  intEphi = 0.0; // Efield is symmetric in phi
116 
117  // Calculate distorted position
118  if ( r > 0.0 ) {
119  phi = phi + deltaVGG*( fC0*intEphi - fC1*intEr ) / r;
120  r = r + deltaVGG*( fC0*intEr + fC1*intEphi );
121  }
122 
123  // Calculate correction in cartesian coordinates
124  dx[0] = r * TMath::Cos(phi) - x[0];
125  dx[1] = r * TMath::Sin(phi) - x[1];
126  dx[2] = 0.; // z distortion not implemented (1st order distortions) - see e.g. AliTPCBoundaryVoltError-class
127 
128 
129 
130 }
131 
132 
133 Float_t AliTPCGGVoltError::GetIntErOverEz(const Float_t x[],const Short_t roc) {
136 
137  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
138 
139  Int_t order = 1 ; // FIXME: so far hardcoded? Linear interpolation = 1, Quadratic = 2
140 
141  Double_t intEr;
142  Double_t r, phi, z ;
143  Int_t sign ;
144 
145  Double_t deltaVGG;
146 
147  r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
148  phi = TMath::ATan2(x[1],x[0]);
149  if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
150  z = x[2] ;
151 
152  if ( (roc%36) < 18 ) {
153  sign = 1;
154  deltaVGG = fDeltaVGGA; // (TPC End A)
155  } else {
156  sign = -1; // (TPC End C)
157  deltaVGG = fDeltaVGGC;
158  }
159 
160  if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
161  if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
162 
163  Interpolate2DEdistortion(order, r, z, fGGVoltErrorER, intEr );
164 
165  return (intEr*deltaVGG);
166 
167 }
168 
171 
172  Double_t r,z;
173  Int_t nterms = 100 ;
174  for ( Int_t i = 0 ; i < kNZ ; ++i ) {
175  z = fgkZList[i] ;
176  for ( Int_t j = 0 ; j < kNR ; ++j ) {
177  r = fgkRList[j] ;
178  fGGVoltErrorER[i][j] = 0.0 ;
179  Double_t intz = 0.0 ;
180  for ( Int_t n = 1 ; n < nterms ; ++n ) {
181  Double_t k = n * TMath::Pi() / fgkTPCZ0 ;
182  Double_t ein = 0 ; // Error potential on the IFC
183  Double_t eout = 0 ; // Error potential on the OFC
184  if ( z < 0 ) {
185  ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
186  eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
187  }
188  if ( z == 0 ) continue ;
189  if ( z > 0 ) {
190  ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
191  eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
192  }
193  Double_t an = ein * TMath::BesselK0( k*fgkOFCRadius ) - eout * TMath::BesselK0( k*fgkIFCRadius ) ;
194  Double_t bn = eout * TMath::BesselI0( k*fgkIFCRadius ) - ein * TMath::BesselI0( k*fgkOFCRadius ) ;
195  Double_t numerator =
196  an * TMath::BesselI1( k*r ) - bn * TMath::BesselK1( k*r ) ;
197  Double_t denominator =
198  TMath::BesselK0( k*fgkOFCRadius ) * TMath::BesselI0( k*fgkIFCRadius ) -
199  TMath::BesselK0( k*fgkIFCRadius ) * TMath::BesselI0( k*fgkOFCRadius ) ;
200  Double_t zterm = TMath::Cos( k*(fgkTPCZ0-TMath::Abs(z)) ) - 1 ;
201  intz += zterm * numerator / denominator ;
202  // Assume series converges, break if small terms
203  if ( n>10 && TMath::Abs(intz)*1.e-10 > TMath::Abs(numerator/denominator) ) break;
204  }
205  fGGVoltErrorER[i][j] = (Double_t) intz ;
206 
207  }
208  }
209 
210  fInitLookUp = kTRUE;
211 }
212 
213 
214 
215 void AliTPCGGVoltError::Print(const Option_t* option) const {
218 
219  TString opt = option; opt.ToLower();
220  printf("%s\n",GetTitle());
221  printf(" - GG Voltage offset: A-side: %3.1f V, C-side: %3.1f V \n",fDeltaVGGA,fDeltaVGGC);
222  if (opt.Contains("a")) { // Print all details
223  printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
224  printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
225  }
226 
227  if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
228 
229 
230 }
static AliTPCcalibDB * Instance()
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
Double_t fgkZList[kNZ]
points in the z direction (for the lookup table)
Double_t fDeltaVGGC
Missmatch of gating grid voltage on C-side [V].
Manager and of geomety classes for set: TPC.
Definition: AliTPCParam.h:18
Float_t GetDriftV() const
Definition: AliTPCParam.h:341
static const Double_t fgkOFCRadius
Mean Radius of the Outer Field Cage (252.55 min, 256.45 max) (cm)
Double_t fDeltaVGGA
Missmatch of gating grid voltage on A-side [V].
AliTPCParam * GetParameters() const
Bool_t fInitLookUp
flag to check it the Look Up table was created
virtual void Print(const Option_t *option="") const
Double_t fT1
tensor term of wt - T1
static const Double_t fgkZOffSet
Offset from CE: calculate all distortions closer to CE as if at this point.
virtual void GetCorrection(const Float_t x[], const Short_t roc, Float_t dx[])
AliTPCCorrection class.
Float_t GetIntErOverEz(const Float_t x[], const Short_t roc)
static const Double_t fgkTPCZ0
nominal gating grid position
Float_t fC1
coefficient C1 (compare Jim Thomas's notes for definitions)
Double_t fGGVoltErrorER[kNZ][kNR]
Array to store electric field for GGVoltError calculation.
virtual void Update(const TTimeStamp &timeStamp)
static const Double_t fgkCathodeV
Cathode Voltage (volts)
void Interpolate2DEdistortion(Int_t order, Double_t r, Double_t z, const Double_t er[kNZ][kNR], Double_t &erValue)
static const Double_t fgkGG
Gating Grid voltage (volts)
Double_t fT2
tensor term of wt - T2
Double_t vdrift
Definition: DriftKalman.C:98
Double_t fgkRList[kNR]
points in the radial direction (for the lookup table)
Float_t fC0
coefficient C0 (compare Jim Thomas's notes for definitions)
virtual void SetOmegaTauT1T2(Float_t omegaTau, Float_t t1, Float_t t2)
static const Double_t fgkIFCRadius
Mean Radius of the Inner Field Cage ( 82.43 min, 83.70 max) (cm)/hera/alice/wiechula/calib/guiTrees.