]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCGGVoltError.cxx
AliTPCpreprocessor update to handle 72 LDCs for TPC (sectors split in two LDCs)
[u/mrichter/AliRoot.git] / TPC / AliTPCGGVoltError.cxx
CommitLineData
0116859c 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////////////////////////////////////////////////////////////////////////////
0116859c 17// AliTPCGGVoltError class //
0116859c 18////////////////////////////////////////////////////////////////////////////
19
20
534fd34a 21#include "AliMagF.h"
22#include "TGeoGlobalMagField.h"
23#include "AliTPCcalibDB.h"
24#include "AliTPCParam.h"
25#include "AliLog.h"
0116859c 26
27#include "AliTPCGGVoltError.h"
28#include <TMath.h>
29
30AliTPCGGVoltError::AliTPCGGVoltError()
31 : AliTPCCorrection("GGVoltError","GatingGrid (GG) Voltage Error"),
32 fC0(0.),fC1(0.),
1b923461 33 fDeltaVGGA(0.),fDeltaVGGC(0.),
34 fInitLookUp(kFALSE)
0116859c 35{
36 //
37 // default constructor
38 //
39}
40
41AliTPCGGVoltError::~AliTPCGGVoltError() {
42 //
43 // default destructor
44 //
45}
46
e527a1b9 47void AliTPCGGVoltError::Init() {
48 //
b1f0a2a5 49 // Init function
534fd34a 50 //
51 AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
52 if (!magF) AliError("Magneticd field - not initialized");
53 Double_t bzField = magF->SolenoidField()/10.; //field in T
54 AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
55 if (!param) AliError("Parameters - not initialized");
56 Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
e527a1b9 57 Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
58 Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
534fd34a 59 //
60 SetOmegaTauT1T2(wt,fT1,fT2);
8b63d99c 61 InitGGVoltErrorDistortion();
534fd34a 62 //SetDeltaVGGA(0.0);// ideally from the database
63 //SetDeltaVGGC(0.0);// ideally from the database
e527a1b9 64}
65
66void AliTPCGGVoltError::Update(const TTimeStamp &/*timeStamp*/) {
67 //
534fd34a 68 // Update function
e527a1b9 69 //
534fd34a 70 AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
71 if (!magF) AliError("Magneticd field - not initialized");
72 Double_t bzField = magF->SolenoidField()/10.; //field in T
73 AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
74 if (!param) AliError("Parameters - not initialized");
75 Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
e527a1b9 76 Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
77 Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
78
534fd34a 79 SetOmegaTauT1T2(wt,fT1,fT2);
1b923461 80 // InitGGVoltErrorDistortion(); // not necessary in here since the Voltage should not change!
e527a1b9 81}
82
83
84
0116859c 85void AliTPCGGVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
86
87 //
88 // Gated Grid Voltage Error
89 //
90 // Calculates the effect of having an incorrect voltage on the A or C end plate Gated Grids.
91 //
92 // Electrostatic Equations from StarNote SN0253 by Howard Wieman.
93 //
94
1b923461 95 if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
96
0116859c 97 Int_t order = 1 ; // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
98
99 Double_t intEr, intEphi ;
100 Double_t r, phi, z ;
101 Int_t sign ;
102
103 Double_t deltaVGG;
104
105 r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
106 phi = TMath::ATan2(x[1],x[0]);
107 if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
108 z = x[2] ;
109
110 if ( (roc%36) < 18 ) {
111 sign = 1;
112 deltaVGG = fDeltaVGGA; // (TPC End A)
113 } else {
114 sign = -1; // (TPC End C)
115 deltaVGG = fDeltaVGGC;
116 }
117
118 if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
119 if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
120
121 Interpolate2DEdistortion( order, r, z, fGGVoltErrorER, intEr );
122 intEphi = 0.0; // Efield is symmetric in phi
123
124 // Calculate distorted position
125 if ( r > 0.0 ) {
126 phi = phi + deltaVGG*( fC0*intEphi - fC1*intEr ) / r;
127 r = r + deltaVGG*( fC0*intEr + fC1*intEphi );
128 }
129
130 // Calculate correction in cartesian coordinates
131 dx[0] = r * TMath::Cos(phi) - x[0];
132 dx[1] = r * TMath::Sin(phi) - x[1];
c9cbd2f2 133 dx[2] = 0.; // z distortion not implemented (1st order distortions) - see e.g. AliTPCBoundaryVoltError-class
0116859c 134
1b923461 135
136
0116859c 137}
138
139
140Float_t AliTPCGGVoltError::GetIntErOverEz(const Float_t x[],const Short_t roc) {
141 //
142 // This function is purely for calibration purposes
143 // Calculates the integral (int Er/Ez dz) for the setted GG voltage offset
144 //
1b923461 145
146 if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
147
0116859c 148 Int_t order = 1 ; // FIXME: so far hardcoded? Linear interpolation = 1, Quadratic = 2
149
150 Double_t intEr;
151 Double_t r, phi, z ;
152 Int_t sign ;
153
154 Double_t deltaVGG;
155
156 r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
157 phi = TMath::ATan2(x[1],x[0]);
158 if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
159 z = x[2] ;
160
161 if ( (roc%36) < 18 ) {
162 sign = 1;
163 deltaVGG = fDeltaVGGA; // (TPC End A)
164 } else {
165 sign = -1; // (TPC End C)
166 deltaVGG = fDeltaVGGC;
167 }
168
169 if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
170 if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
171
172 Interpolate2DEdistortion(order, r, z, fGGVoltErrorER, intEr );
173
174 return (intEr*deltaVGG);
175
176}
177
178void AliTPCGGVoltError::InitGGVoltErrorDistortion() {
179 //
180 // Initialization of the Lookup table which contains the solutions of the GG Error problem
181 //
182
183 Double_t r,z;
184 Int_t nterms = 100 ;
185 for ( Int_t i = 0 ; i < kNZ ; ++i ) {
186 z = fgkZList[i] ;
187 for ( Int_t j = 0 ; j < kNR ; ++j ) {
188 r = fgkRList[j] ;
189 fGGVoltErrorER[i][j] = 0.0 ;
190 Double_t intz = 0.0 ;
191 for ( Int_t n = 1 ; n < nterms ; ++n ) {
b1f0a2a5 192 Double_t k = n * TMath::Pi() / fgkTPCZ0 ;
0116859c 193 Double_t ein = 0 ; // Error potential on the IFC
194 Double_t eout = 0 ; // Error potential on the OFC
195 if ( z < 0 ) {
196 ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
197 eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
198 }
199 if ( z == 0 ) continue ;
200 if ( z > 0 ) {
201 ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
202 eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
203 }
204 Double_t an = ein * TMath::BesselK0( k*fgkOFCRadius ) - eout * TMath::BesselK0( k*fgkIFCRadius ) ;
205 Double_t bn = eout * TMath::BesselI0( k*fgkIFCRadius ) - ein * TMath::BesselI0( k*fgkOFCRadius ) ;
206 Double_t numerator =
207 an * TMath::BesselI1( k*r ) - bn * TMath::BesselK1( k*r ) ;
208 Double_t denominator =
209 TMath::BesselK0( k*fgkOFCRadius ) * TMath::BesselI0( k*fgkIFCRadius ) -
210 TMath::BesselK0( k*fgkIFCRadius ) * TMath::BesselI0( k*fgkOFCRadius ) ;
b1f0a2a5 211 Double_t zterm = TMath::Cos( k*(fgkTPCZ0-TMath::Abs(z)) ) - 1 ;
0116859c 212 intz += zterm * numerator / denominator ;
213 // Assume series converges, break if small terms
b9f518ba 214 if ( n>10 && TMath::Abs(intz)*1.e-10 > TMath::Abs(numerator/denominator) ) break;
0116859c 215 }
216 fGGVoltErrorER[i][j] = (Double_t) intz ;
217
218 }
219 }
1b923461 220
221 fInitLookUp = kTRUE;
0116859c 222}
223
224
225
b1f0a2a5 226void AliTPCGGVoltError::Print(const Option_t* option) const {
0116859c 227 //
228 // Print function to check the settings (e.g. voltage offsets)
229 // option=="a" prints the C0 and C1 coefficents for calibration purposes
230 //
231
232 TString opt = option; opt.ToLower();
233 printf("%s\n",GetTitle());
234 printf(" - GG Voltage offset: A-side: %3.1f V, C-side: %3.1f V \n",fDeltaVGGA,fDeltaVGGC);
235 if (opt.Contains("a")) { // Print all details
534fd34a 236 printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
0116859c 237 printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
238 }
239
1b923461 240 if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
0116859c 241
242
243}