Corrected UInt_t <-> Int_t conversion
[u/mrichter/AliRoot.git] / TPC / AliTPCFCVoltError3D.cxx
... / ...
CommitLineData
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// _________________________________________________________________
17//
18// Begin_Html
19// <h2>AliTPCFCVoltError3D class </h2>
20// The class calculates the space point distortions due to residual voltage errors
21// on the Field Cage (FC) boundaries (rods and strips) of the TPC in 3D. It uses
22// the Poisson relaxation technique in three dimension as implemented in the parent class.
23// <p>
24// Although the calculation is performed in 3D, the calculation time was significantly
25// reduced by using certain symmetry conditions within the calculation.
26// <p>
27// The input parameters can be set via the functions (e.g.) SetRodVoltShift(rod,dV) where
28// rod is the number of the rod on which the voltage offset dV is set. The corresponding
29// shift in z direction would be $dz=dV/40$ with an opposite sign for the C side. The
30// rods are numbered in anti-clock-wise direction starting at $\phi=0$. Rods in the IFC
31// are from 0 to 17, rods on the OFC go from 18 to 35. <br>
32// This convention is following the offline numbering scheme of the ROCs.
33// <p>
34// Different misalignment scenarios can be modeled:
35// <ul>
36// <li> A rotated clip scenario is only possible at two positions (Rod 11 at IFC, rod 3(+18) at OFC)
37// and can be set via SetRotatedClipVolt. The key feature is that at the mentioned positions,
38// the strip-ends were combined. At these positions, a systematic offset of one strip-end in
39// respect to the other is possible.
40// <li> A normal rod offset, where the strips follow the movement of the rod, can be set via
41// SetRodVoltShift. It has a anti-mirrored signature in terms of distortions when compared
42// to the rotated clip. This misalignment is possible at each single rod of the FC.
43// <li> A simple rod offset, where the strips do not follow the shift, results in an even more
44// localized distortion close to the rod. The difference to a rod shift, where the strips follow,
45// is more dominant on the OFC. This effect can be set via the function SetCopperRodShift.
46// </ul>
47// End_Html
48//
49// Begin_Macro(source)
50// {
51// gROOT->SetStyle("Plain"); gStyle->SetPalette(1);
52// TCanvas *c2 = new TCanvas("cAliTPCVoltError3D","cAliTPCVoltError3D",500,450);
53// AliTPCFCVoltError3D fc;
54// fc.SetOmegaTauT1T2(0,1,1);
55// fc.SetRotatedClipVoltA(0,40);
56// fc.SetRodVoltShiftA(3,40);
57// fc.SetCopperRodShiftA(7+18,40);
58// fc.SetRodVoltShiftA(15+18,40);
59// fc.CreateHistoDRPhiinXY(10)->Draw("cont4z");
60// return c2;
61// }
62// End_Macro
63//
64// Begin_Html
65// <p>
66// Date: 08/08/2010 <br>
67// Authors: Jim Thomas, Stefan Rossegger
68// End_Html
69// _________________________________________________________________
70
71
72#include "AliMagF.h"
73#include "TGeoGlobalMagField.h"
74#include "AliTPCcalibDB.h"
75#include "AliTPCParam.h"
76#include "AliLog.h"
77#include "TMatrixD.h"
78#include "TMatrixF.h"
79
80#include "TMath.h"
81#include "AliTPCROC.h"
82#include "AliTPCFCVoltError3D.h"
83
84ClassImp(AliTPCFCVoltError3D)
85
86AliTPCFCVoltError3D::AliTPCFCVoltError3D()
87 : AliTPCCorrection("FieldCageVoltErrors","FieldCage (Rods) Voltage Errors"),
88 fC0(0.),fC1(0.),
89 fInitLookUp(kFALSE)
90{
91 //
92 // default constructor
93 //
94
95 // flags for filled 'basic lookup tables'
96 for (Int_t i=0; i<6; i++){
97 fInitLookUpBasic[i]= kFALSE;
98 }
99
100 // Boundary settings
101 for (Int_t i=0; i<36; i++){
102 fRodVoltShiftA[i] = 0;
103 fRodVoltShiftC[i] = 0;
104 }
105 for (Int_t i=0; i<2; i++){
106 fRotatedClipVoltA[i] = 0;
107 fRotatedClipVoltC[i] = 0;
108 }
109 //
110 for (Int_t i=0; i<36; i++){
111 fCopperRodShiftA[i] = 0;
112 fCopperRodShiftC[i] = 0;
113 }
114
115 // Array which will contain the solution according to the setted boundary conditions
116 // it represents a sum up of the 4 basic look up tables (created individually)
117 // see InitFCVoltError3D() function
118 for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
119 fLookUpErOverEz[k] = new TMatrixF(kNR,kNZ);
120 fLookUpEphiOverEz[k] = new TMatrixF(kNR,kNZ);
121 fLookUpDeltaEz[k] = new TMatrixF(kNR,kNZ);
122 }
123
124 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
125 fLookUpBasic1ErOverEz[k] = 0;
126 fLookUpBasic1EphiOverEz[k] = 0;
127 fLookUpBasic1DeltaEz[k] = 0;
128
129 fLookUpBasic2ErOverEz[k] = 0;
130 fLookUpBasic2EphiOverEz[k] = 0;
131 fLookUpBasic2DeltaEz[k] = 0;
132
133 fLookUpBasic3ErOverEz[k] = 0;
134 fLookUpBasic3EphiOverEz[k] = 0;
135 fLookUpBasic3DeltaEz[k] = 0;
136
137 fLookUpBasic4ErOverEz[k] = 0;
138 fLookUpBasic4EphiOverEz[k] = 0;
139 fLookUpBasic4DeltaEz[k] = 0;
140
141 fLookUpBasic5ErOverEz[k] = 0;
142 fLookUpBasic5EphiOverEz[k] = 0;
143 fLookUpBasic5DeltaEz[k] = 0;
144
145 fLookUpBasic6ErOverEz[k] = 0;
146 fLookUpBasic6EphiOverEz[k] = 0;
147 fLookUpBasic6DeltaEz[k] = 0;
148 }
149
150}
151
152AliTPCFCVoltError3D::~AliTPCFCVoltError3D() {
153 //
154 // destructor
155 //
156
157 for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
158 delete fLookUpErOverEz[k];
159 delete fLookUpEphiOverEz[k];
160 delete fLookUpDeltaEz[k];
161 }
162
163 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
164 delete fLookUpBasic1ErOverEz[k]; // does nothing if pointer is zero!
165 delete fLookUpBasic1EphiOverEz[k];
166 delete fLookUpBasic1DeltaEz[k];
167
168 delete fLookUpBasic2ErOverEz[k]; // does nothing if pointer is zero!
169 delete fLookUpBasic2EphiOverEz[k];
170 delete fLookUpBasic2DeltaEz[k];
171
172 delete fLookUpBasic3ErOverEz[k]; // does nothing if pointer is zero!
173 delete fLookUpBasic3EphiOverEz[k];
174 delete fLookUpBasic3DeltaEz[k];
175
176 delete fLookUpBasic4ErOverEz[k]; // does nothing if pointer is zero!
177 delete fLookUpBasic4EphiOverEz[k];
178 delete fLookUpBasic4DeltaEz[k];
179
180 delete fLookUpBasic5ErOverEz[k]; // does nothing if pointer is zero!
181 delete fLookUpBasic5EphiOverEz[k];
182 delete fLookUpBasic5DeltaEz[k];
183
184 delete fLookUpBasic6ErOverEz[k]; // does nothing if pointer is zero!
185 delete fLookUpBasic6EphiOverEz[k];
186 delete fLookUpBasic6DeltaEz[k];
187
188 }
189}
190
191void AliTPCFCVoltError3D::Init() {
192 //
193 // Initialization funtion
194 //
195
196 AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
197 if (!magF) AliError("Magneticd field - not initialized");
198 Double_t bzField = magF->SolenoidField()/10.; //field in T
199 AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
200 if (!param) AliError("Parameters - not initialized");
201 Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
202 Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
203 Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
204 // Correction Terms for effective omegaTau; obtained by a laser calibration run
205 SetOmegaTauT1T2(wt,fT1,fT2);
206
207 if (!fInitLookUp) InitFCVoltError3D();
208}
209
210void AliTPCFCVoltError3D::Update(const TTimeStamp &/*timeStamp*/) {
211 //
212 // Update function
213 //
214 AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
215 if (!magF) AliError("Magneticd field - not initialized");
216 Double_t bzField = magF->SolenoidField()/10.; //field in T
217 AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
218 if (!param) AliError("Parameters - not initialized");
219 Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
220 Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
221 Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
222 // Correction Terms for effective omegaTau; obtained by a laser calibration run
223 SetOmegaTauT1T2(wt,fT1,fT2);
224
225
226}
227
228
229
230void AliTPCFCVoltError3D::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
231 //
232 // Calculates the correction due e.g. residual voltage errors on the TPC boundaries
233 //
234 const Double_t kEpsilon=Double_t(FLT_MIN);
235
236 if (!fInitLookUp) {
237 AliInfo("Lookup table was not initialized! Perform the inizialisation now ...");
238 InitFCVoltError3D();
239 }
240
241 static Bool_t forceInit=kTRUE; //temporary needed for back compatibility with old OCDB entries
242 if (forceInit &&fLookUpErOverEz[0]){
243 if (TMath::Abs(fLookUpErOverEz[0]->Sum())<kEpsilon){//temporary needed for back compatibility with old OCDB entries
244 ForceInitFCVoltError3D();
245 }
246 forceInit=kFALSE;
247 }
248
249
250 Int_t order = 1 ; // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
251 // note that the poisson solution was linearly mirroed on this grid!
252 Float_t intEr, intEphi, intDeltaEz;
253 Float_t r, phi, z ;
254 Int_t sign;
255
256 r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] ) ;
257 phi = TMath::ATan2(x[1],x[0]) ;
258 if ( phi < 0 ) phi += TMath::TwoPi() ; // Table uses phi from 0 to 2*Pi
259 z = x[2] ; // Create temporary copy of x[2]
260
261 if ( (roc%36) < 18 ) {
262 sign = 1; // (TPC A side)
263 } else {
264 sign = -1; // (TPC C side)
265 }
266
267 if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
268 if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
269
270
271 if ( (sign==1 && z<0) || (sign==-1 && z>0) ) // just a consistency check
272 AliError("ROC number does not correspond to z coordinate! Calculation of distortions is most likely wrong!");
273
274 // Get the Er and Ephi field integrals plus the integral over DeltaEz
275 intEr = Interpolate3DTable(order, r, z, phi, kNR, kNZ, kNPhi,
276 fgkRList, fgkZList, fgkPhiList, fLookUpErOverEz );
277 intEphi = Interpolate3DTable(order, r, z, phi, kNR, kNZ, kNPhi,
278 fgkRList, fgkZList, fgkPhiList, fLookUpEphiOverEz );
279 intDeltaEz = Interpolate3DTable(order, r, z, phi, kNR, kNZ, kNPhi,
280 fgkRList, fgkZList, fgkPhiList, fLookUpDeltaEz );
281
282 // printf("%lf %lf %lf\n",intEr,intEphi,intDeltaEz);
283
284 // Calculate distorted position
285 if ( r > 0.0 ) {
286 phi = phi + ( fC0*intEphi - fC1*intEr ) / r;
287 r = r + ( fC0*intEr + fC1*intEphi );
288 }
289
290 // Calculate correction in cartesian coordinates
291 dx[0] = r * TMath::Cos(phi) - x[0];
292 dx[1] = r * TMath::Sin(phi) - x[1];
293 dx[2] = intDeltaEz; // z distortion - (internally scaled with driftvelocity dependency
294 // on the Ez field plus the actual ROC misalignment (if set TRUE)
295
296}
297
298void AliTPCFCVoltError3D::InitFCVoltError3D() {
299 //
300 // Initialization of the Lookup table which contains the solutions of the
301 // Dirichlet boundary problem
302 // Calculation of the single 3D-Poisson solver is done just if needed
303 // (see basic lookup tables in header file)
304 //
305
306 const Int_t order = 1 ; // Linear interpolation = 1, Quadratic = 2
307 const Float_t gridSizeR = (fgkOFCRadius-fgkIFCRadius) / (kRows-1) ;
308 const Float_t gridSizeZ = fgkTPCZ0 / (kColumns-1) ;
309 const Float_t gridSizePhi = TMath::TwoPi() / ( 18.0 * kPhiSlicesPerSector);
310
311 // temporary arrays to create the boundary conditions
312 TMatrixD *arrayofArrayV[kPhiSlices], *arrayofCharge[kPhiSlices] ;
313 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
314 arrayofArrayV[k] = new TMatrixD(kRows,kColumns) ;
315 arrayofCharge[k] = new TMatrixD(kRows,kColumns) ;
316 }
317 Double_t innerList[kPhiSlices], outerList[kPhiSlices] ;
318
319 // list of point as used in the poisson relation and the interpolation (during sum up)
320 Double_t rlist[kRows], zedlist[kColumns] , philist[kPhiSlices];
321 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
322 philist[k] = gridSizePhi * k;
323 for ( Int_t i = 0 ; i < kRows ; i++ ) {
324 rlist[i] = fgkIFCRadius + i*gridSizeR ;
325 for ( Int_t j = 0 ; j < kColumns ; j++ ) { // Fill Vmatrix with Boundary Conditions
326 zedlist[j] = j * gridSizeZ ;
327 }
328 }
329 }
330
331 // ==========================================================================
332 // Solve Poisson's equation in 3D cylindrical coordinates by relaxation technique
333 // Allow for different size grid spacing in R and Z directions
334
335 const Int_t symmetry[6] = {1,1,-1,-1,1,1}; // shifted rod (2x), rotated clip (2x), only rod shift on OFC (1x)
336
337 // check which lookup tables are needed ---------------------------------
338
339 Bool_t needTable[6] ={kFALSE,kFALSE,kFALSE,kFALSE,kFALSE,kFALSE};
340
341 // Shifted rods & strips
342 for ( Int_t rod = 0 ; rod < 18 ; rod++ ) {
343 if (fRodVoltShiftA[rod]!=0) needTable[0]=kTRUE;
344 if (fRodVoltShiftC[rod]!=0) needTable[0]=kTRUE;
345 }
346 for ( Int_t rod = 18 ; rod < 36 ; rod++ ) {
347 if (fRodVoltShiftA[rod]!=0) needTable[1]=kTRUE;
348 if (fRodVoltShiftC[rod]!=0) needTable[1]=kTRUE;
349 }
350 // Rotated clips
351 if (fRotatedClipVoltA[0]!=0 || fRotatedClipVoltC[0]!=0) needTable[2]=kTRUE;
352 if (fRotatedClipVoltA[1]!=0 || fRotatedClipVoltC[1]!=0) needTable[3]=kTRUE;
353
354 // shifted Copper rods
355 for ( Int_t rod = 0 ; rod < 18 ; rod++ ) {
356 if (fCopperRodShiftA[rod]!=0) needTable[4]=kTRUE;
357 if (fCopperRodShiftC[rod]!=0) needTable[4]=kTRUE;
358 }
359 // shifted Copper rods
360 for ( Int_t rod = 18; rod < 36 ; rod++ ) {
361 if (fCopperRodShiftA[rod]!=0) needTable[5]=kTRUE;
362 if (fCopperRodShiftC[rod]!=0) needTable[5]=kTRUE;
363 }
364
365
366 // reserve the arrays for the basic lookup tables ----------------------
367 if (needTable[0] && !fInitLookUpBasic[0]) {
368 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
369 fLookUpBasic1ErOverEz[k] = new TMatrixD(kRows,kColumns);
370 fLookUpBasic1EphiOverEz[k] = new TMatrixD(kRows,kColumns);
371 fLookUpBasic1DeltaEz[k] = new TMatrixD(kRows,kColumns);
372 // will be deleted in destructor
373 }
374 }
375 if (needTable[1] && !fInitLookUpBasic[1]) {
376 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
377 fLookUpBasic2ErOverEz[k] = new TMatrixD(kRows,kColumns);
378 fLookUpBasic2EphiOverEz[k] = new TMatrixD(kRows,kColumns);
379 fLookUpBasic2DeltaEz[k] = new TMatrixD(kRows,kColumns);
380 // will be deleted in destructor
381 }
382 }
383 if (needTable[2] && !fInitLookUpBasic[2]) {
384 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
385 fLookUpBasic3ErOverEz[k] = new TMatrixD(kRows,kColumns);
386 fLookUpBasic3EphiOverEz[k] = new TMatrixD(kRows,kColumns);
387 fLookUpBasic3DeltaEz[k] = new TMatrixD(kRows,kColumns);
388 // will be deleted in destructor
389 }
390 }
391 if (needTable[3] && !fInitLookUpBasic[3]) {
392 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
393 fLookUpBasic4ErOverEz[k] = new TMatrixD(kRows,kColumns);
394 fLookUpBasic4EphiOverEz[k] = new TMatrixD(kRows,kColumns);
395 fLookUpBasic4DeltaEz[k] = new TMatrixD(kRows,kColumns);
396 // will be deleted in destructor
397 }
398 }
399 if (needTable[4] && !fInitLookUpBasic[4]) {
400 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
401 fLookUpBasic5ErOverEz[k] = new TMatrixD(kRows,kColumns);
402 fLookUpBasic5EphiOverEz[k] = new TMatrixD(kRows,kColumns);
403 fLookUpBasic5DeltaEz[k] = new TMatrixD(kRows,kColumns);
404 // will be deleted in destructor
405 }
406 }
407 if (needTable[5] && !fInitLookUpBasic[5]) {
408 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) { // Possibly make an extra table to be used for 0 == 360
409 fLookUpBasic6ErOverEz[k] = new TMatrixD(kRows,kColumns);
410 fLookUpBasic6EphiOverEz[k] = new TMatrixD(kRows,kColumns);
411 fLookUpBasic6DeltaEz[k] = new TMatrixD(kRows,kColumns);
412 // will be deleted in destructor
413 }
414 }
415
416 // Set bondaries and solve Poisson's equation --------------------------
417
418 for (Int_t look=0; look<6; look++) {
419
420 Float_t inner18[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
421 Float_t outer18[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
422
423 if (needTable[look] && !fInitLookUpBasic[look]) {
424
425 // Specify which rod is the reference; other distortions calculated by summing over multiple rotations of refrence
426 // Note: the interpolation later on depends on it!! Do not change if not really needed!
427 if (look==0) {
428 AliInfo(Form("IFC - ROD&Strip shift : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
429 inner18[0] = 1;
430 } else if (look==1) {
431 AliInfo(Form("OFC - ROD&Strip shift : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
432 outer18[0] = 1;
433 } else if (look==2) {
434 AliInfo(Form("IFC - Clip rot. : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
435 inner18[0] = 1;
436 } else if (look==3) {
437 AliInfo(Form("OFC - Clip rot. : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
438 outer18[0] = 1;
439 } else if (look==4) {
440 AliInfo(Form("IFC - CopperRod shift : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
441 inner18[0] = 1;
442 } else if (look==5) {
443 AliInfo(Form("OFC - CopperRod shift : Filling table (~ %d sec)",3*(int)(kPhiSlices/5)));
444 outer18[0] = 1;
445 }
446 // Build potentials on boundary stripes for a rotated clip (SYMMETRY==-1) or a shifted rod (SYMMETRY==1)
447 if (look<4) {
448 // in these cases, the strips follow the actual rod shift (linear interpolation between the rods)
449 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
450 Int_t slices = kPhiSlicesPerSector ;
451 Int_t ipoint = k/slices ;
452 innerList[k] = (((ipoint+1)*slices-k)*inner18[ipoint]-(k-ipoint*slices)*inner18[ipoint+1])/slices ;
453 outerList[k] = (((ipoint+1)*slices-k)*outer18[ipoint]-(k-ipoint*slices)*outer18[ipoint+1])/slices ;
454 if ( (k%slices) == 0 && symmetry[look] == -1 ) { innerList[k] = 0.0 ; outerList[k] = 0.0 ; }
455 // above, force Zero if Anti-Sym
456 }
457 } else if (look==4){
458 // in this case, we assume that the strips stay at the correct position, but the rods move
459 // the distortion is then much more localized around the rod (indicated by real data)
460 for ( Int_t k = 0 ; k < kPhiSlices ; k++ )
461 innerList[k] = outerList[k] = 0;
462 innerList[0] = inner18[0]; // point at rod
463 innerList[0] = inner18[0]/4*3; // point close to rod (educated guess)
464 } else if (look==5){
465 // in this case, we assume that the strips stay at the correct position, but the copper plated OFC-rods move
466 // the distortion is then much more localized around the rod (indicated by real data)
467 for ( Int_t k = 0 ; k < kPhiSlices ; k++ )
468 innerList[k] = outerList[k] = 0;
469 outerList[0] = outer18[0]; // point at rod
470 outerList[1] = outer18[0]/4; // point close to rod (educated-`guessed` scaling)
471 }
472
473 // Fill arrays with initial conditions. V on the boundary and Charge in the volume.
474 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
475 TMatrixD &arrayV = *arrayofArrayV[k] ;
476 TMatrixD &charge = *arrayofCharge[k] ;
477 for ( Int_t i = 0 ; i < kRows ; i++ ) {
478 for ( Int_t j = 0 ; j < kColumns ; j++ ) { // Fill Vmatrix with Boundary Conditions
479 arrayV(i,j) = 0.0 ;
480 charge(i,j) = 0.0 ;
481 if ( i == 0 ) arrayV(i,j) = innerList[k] ;
482 if ( i == kRows-1 ) arrayV(i,j) = outerList[k] ;
483 }
484 }
485 // no charge in the volume
486 for ( Int_t i = 1 ; i < kRows-1 ; i++ ) {
487 for ( Int_t j = 1 ; j < kColumns-1 ; j++ ) {
488 charge(i,j) = 0.0 ;
489 }
490 }
491 }
492
493 // Solve Poisson's equation in 3D cylindrical coordinates by relaxation technique
494 // Allow for different size grid spacing in R and Z directions
495 if (look==0) {
496 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
497 fLookUpBasic1ErOverEz, fLookUpBasic1EphiOverEz, fLookUpBasic1DeltaEz,
498 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[0]) ;
499 AliInfo("IFC - ROD&Strip shift : done ");
500 } else if (look==1) {
501 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
502 fLookUpBasic2ErOverEz, fLookUpBasic2EphiOverEz, fLookUpBasic2DeltaEz,
503 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[1]) ;
504
505 AliInfo("OFC - ROD&Strip shift : done ");
506 } else if (look==2) {
507 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
508 fLookUpBasic3ErOverEz, fLookUpBasic3EphiOverEz, fLookUpBasic3DeltaEz,
509 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[2]) ;
510 AliInfo("IFC - Clip rot. : done ");
511 } else if (look==3) {
512 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
513 fLookUpBasic4ErOverEz, fLookUpBasic4EphiOverEz, fLookUpBasic4DeltaEz,
514 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[3]) ;
515 AliInfo("OFC - Clip rot. : done ");
516 } else if (look==4) {
517 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
518 fLookUpBasic5ErOverEz, fLookUpBasic5EphiOverEz, fLookUpBasic5DeltaEz,
519 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[4]) ;
520 AliInfo("IFC - CopperRod shift : done ");
521 } else if (look==5) {
522 PoissonRelaxation3D( arrayofArrayV, arrayofCharge,
523 fLookUpBasic6ErOverEz, fLookUpBasic6EphiOverEz, fLookUpBasic6DeltaEz,
524 kRows, kColumns, kPhiSlices, gridSizePhi, kIterations, symmetry[5]) ;
525 AliInfo("OFC - CopperRod shift : done ");
526 }
527
528 fInitLookUpBasic[look] = kTRUE;
529 }
530 }
531
532
533 // =============================================================================
534 // Create the final lookup table with corresponding ROD shifts or clip rotations
535
536 Float_t erIntegralSum = 0.0 ;
537 Float_t ephiIntegralSum = 0.0 ;
538 Float_t ezIntegralSum = 0.0 ;
539
540 Double_t phiPrime = 0. ;
541 Double_t erIntegral = 0. ;
542 Double_t ephiIntegral = 0. ;
543 Double_t ezIntegral = 0. ;
544
545
546 AliInfo("Calculation of combined Look-up Table");
547
548 // Interpolate and sum the Basic lookup tables onto the standard grid
549 Double_t r, phi, z ;
550 for ( Int_t k = 0 ; k < kNPhi ; k++ ) {
551 phi = fgkPhiList[k] ;
552
553 TMatrixF &erOverEz = *fLookUpErOverEz[k] ;
554 TMatrixF &ephiOverEz = *fLookUpEphiOverEz[k];
555 TMatrixF &deltaEz = *fLookUpDeltaEz[k] ;
556
557 for ( Int_t i = 0 ; i < kNZ ; i++ ) {
558 z = TMath::Abs(fgkZList[i]) ; // Symmetric solution in Z that depends only on ABS(Z)
559 for ( Int_t j = 0 ; j < kNR ; j++ ) {
560 r = fgkRList[j] ;
561 // Interpolate basicLookup tables; once for each rod, then sum the results
562
563 erIntegralSum = 0.0 ;
564 ephiIntegralSum = 0.0 ;
565 ezIntegralSum = 0.0 ;
566
567 // SHIFTED RODS =========================================================
568
569 // IFC ROD SHIFTS +++++++++++++++++++++++++++++
570 for ( Int_t rod = 0 ; rod < 18 ; rod++ ) {
571
572 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
573
574 if ( fRodVoltShiftA[rod] == 0 && fgkZList[i] > 0) continue ;
575 if ( fRodVoltShiftC[rod] == 0 && fgkZList[i] < 0) continue ;
576
577 // Rotate to a position where we have maps and prepare to sum
578 phiPrime = phi - rod*kPhiSlicesPerSector*gridSizePhi ;
579
580 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
581
582 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
583
584 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
585 rlist, zedlist, philist, fLookUpBasic1ErOverEz );
586 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
587 rlist, zedlist, philist, fLookUpBasic1EphiOverEz);
588 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
589 rlist, zedlist, philist, fLookUpBasic1DeltaEz );
590
591 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
592
593 phiPrime = TMath::TwoPi() - phiPrime ;
594
595 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
596 rlist, zedlist, philist, fLookUpBasic1ErOverEz );
597 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
598 rlist, zedlist, philist, fLookUpBasic1EphiOverEz);
599 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
600 rlist, zedlist, philist, fLookUpBasic1DeltaEz );
601
602 // Flip symmetry of phi integral for symmetric boundary conditions
603 if ( symmetry[0] == 1 ) ephiIntegral *= -1 ;
604 // Flip symmetry of r integral if anti-symmetric boundary conditions
605 if ( symmetry[0] == -1 ) erIntegral *= -1 ;
606
607 }
608
609 if ( fgkZList[i] > 0 ) {
610 erIntegralSum += fRodVoltShiftA[rod]*erIntegral ;
611 ephiIntegralSum += fRodVoltShiftA[rod]*ephiIntegral ;
612 ezIntegralSum += fRodVoltShiftA[rod]*ezIntegral;
613 } else if ( fgkZList[i] < 0 ) {
614 erIntegralSum += fRodVoltShiftC[rod]*erIntegral ;
615 ephiIntegralSum += fRodVoltShiftC[rod]*ephiIntegral ;
616 ezIntegralSum -= fRodVoltShiftC[rod]*ezIntegral;
617 }
618 }
619
620 // OFC ROD SHIFTS +++++++++++++++++++++++++++++
621 for ( Int_t rod = 18 ; rod < 36 ; rod++ ) {
622
623 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
624
625 if ( fRodVoltShiftA[rod] == 0 && fgkZList[i] > 0) continue ;
626 if ( fRodVoltShiftC[rod] == 0 && fgkZList[i] < 0) continue ;
627
628 // Rotate to a position where we have maps and prepare to sum
629 phiPrime = phi - (rod-18)*kPhiSlicesPerSector*gridSizePhi ;
630
631 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
632
633 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
634
635 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
636 rlist, zedlist, philist, fLookUpBasic2ErOverEz );
637 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
638 rlist, zedlist, philist, fLookUpBasic2EphiOverEz);
639 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
640 rlist, zedlist, philist, fLookUpBasic2DeltaEz );
641
642 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
643
644 phiPrime = TMath::TwoPi() - phiPrime ;
645
646 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
647 rlist, zedlist, philist, fLookUpBasic2ErOverEz );
648 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
649 rlist, zedlist, philist, fLookUpBasic2EphiOverEz);
650 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
651 rlist, zedlist, philist, fLookUpBasic2DeltaEz );
652
653 // Flip symmetry of phi integral for symmetric boundary conditions
654 if ( symmetry[1] == 1 ) ephiIntegral *= -1 ;
655 // Flip symmetry of r integral if anti-symmetric boundary conditions
656 if ( symmetry[1] == -1 ) erIntegral *= -1 ;
657
658 }
659
660 if ( fgkZList[i] > 0 ) {
661 erIntegralSum += fRodVoltShiftA[rod]*erIntegral ;
662 ephiIntegralSum += fRodVoltShiftA[rod]*ephiIntegral ;
663 ezIntegralSum += fRodVoltShiftA[rod]*ezIntegral;
664 } else if ( fgkZList[i] < 0 ) {
665 erIntegralSum += fRodVoltShiftC[rod]*erIntegral ;
666 ephiIntegralSum += fRodVoltShiftC[rod]*ephiIntegral ;
667 ezIntegralSum -= fRodVoltShiftC[rod]*ezIntegral;
668 }
669
670 } // rod loop - shited ROD
671
672
673 // Rotated clips =========================================================
674
675 Int_t rodIFC = 11; // resistor rod positions, IFC
676 Int_t rodOFC = 3; // resistor rod positions, OFC
677 // just one rod on IFC and OFC
678
679 // IFC ROTATED CLIP +++++++++++++++++++++++++++++
680 for ( Int_t rod = rodIFC ; rod < rodIFC+1 ; rod++ ) { // loop over 1 to keep the "ignore"-functionality
681
682 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
683 if ( fRotatedClipVoltA[0] == 0 && fgkZList[i] > 0) continue ;
684 if ( fRotatedClipVoltC[0] == 0 && fgkZList[i] < 0) continue ;
685
686 // Rotate to a position where we have maps and prepare to sum
687 phiPrime = phi - rod*kPhiSlicesPerSector*gridSizePhi ;
688
689 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
690
691 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
692
693 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
694 rlist, zedlist, philist, fLookUpBasic3ErOverEz );
695 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
696 rlist, zedlist, philist, fLookUpBasic3EphiOverEz);
697 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
698 rlist, zedlist, philist, fLookUpBasic3DeltaEz );
699
700 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
701
702 phiPrime = TMath::TwoPi() - phiPrime ;
703
704 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
705 rlist, zedlist, philist, fLookUpBasic3ErOverEz );
706 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
707 rlist, zedlist, philist, fLookUpBasic3EphiOverEz);
708 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
709 rlist, zedlist, philist, fLookUpBasic3DeltaEz );
710
711 // Flip symmetry of phi integral for symmetric boundary conditions
712 if ( symmetry[2] == 1 ) ephiIntegral *= -1 ;
713 // Flip symmetry of r integral if anti-symmetric boundary conditions
714 if ( symmetry[2] == -1 ) erIntegral *= -1 ;
715
716 }
717
718 if ( fgkZList[i] > 0 ) {
719 erIntegralSum += fRotatedClipVoltA[0]*erIntegral ;
720 ephiIntegralSum += fRotatedClipVoltA[0]*ephiIntegral ;
721 ezIntegralSum += fRotatedClipVoltA[0]*ezIntegral;
722 } else if ( fgkZList[i] < 0 ) {
723 erIntegralSum += fRotatedClipVoltC[0]*erIntegral ;
724 ephiIntegralSum += fRotatedClipVoltC[0]*ephiIntegral ;
725 ezIntegralSum -= fRotatedClipVoltC[0]*ezIntegral;
726 }
727 }
728
729 // OFC: ROTATED CLIP +++++++++++++++++++++++++++++
730 for ( Int_t rod = rodOFC ; rod < rodOFC+1 ; rod++ ) { // loop over 1 to keep the "ignore"-functionality
731
732 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
733
734 if ( fRotatedClipVoltA[1] == 0 && fgkZList[i] > 0) continue ;
735 if ( fRotatedClipVoltC[1] == 0 && fgkZList[i] < 0) continue ;
736
737 // Rotate to a position where we have maps and prepare to sum
738 phiPrime = phi - rod*kPhiSlicesPerSector*gridSizePhi ;
739
740
741 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
742
743 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
744
745 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
746 rlist, zedlist, philist, fLookUpBasic4ErOverEz );
747 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
748 rlist, zedlist, philist, fLookUpBasic4EphiOverEz);
749 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
750 rlist, zedlist, philist, fLookUpBasic4DeltaEz );
751
752 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
753
754 phiPrime = TMath::TwoPi() - phiPrime ;
755
756 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
757 rlist, zedlist, philist, fLookUpBasic4ErOverEz );
758 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
759 rlist, zedlist, philist, fLookUpBasic4EphiOverEz);
760 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
761 rlist, zedlist, philist, fLookUpBasic4DeltaEz );
762
763 // Flip symmetry of phi integral for symmetric boundary conditions
764 if ( symmetry[3] == 1 ) ephiIntegral *= -1 ;
765 // Flip symmetry of r integral if anti-symmetric boundary conditions
766 if ( symmetry[3] == -1 ) erIntegral *= -1 ;
767
768 }
769
770 if ( fgkZList[i] > 0 ) {
771 erIntegralSum += fRotatedClipVoltA[1]*erIntegral ;
772 ephiIntegralSum += fRotatedClipVoltA[1]*ephiIntegral ;
773 ezIntegralSum += fRotatedClipVoltA[1]*ezIntegral;
774 } else if ( fgkZList[i] < 0 ) {
775 erIntegralSum += fRotatedClipVoltC[1]*erIntegral ;
776 ephiIntegralSum += fRotatedClipVoltC[1]*ephiIntegral ;
777 ezIntegralSum -= fRotatedClipVoltC[1]*ezIntegral;
778 }
779 }
780
781 // IFC Cooper rod shift +++++++++++++++++++++++++++++
782 for ( Int_t rod = 0 ; rod < 18 ; rod++ ) {
783
784 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
785
786 if ( fCopperRodShiftA[rod] == 0 && fgkZList[i] > 0) continue ;
787 if ( fCopperRodShiftC[rod] == 0 && fgkZList[i] < 0) continue ;
788
789 // Rotate to a position where we have maps and prepare to sum
790 phiPrime = phi - rod*kPhiSlicesPerSector*gridSizePhi ;
791
792 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
793
794 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
795
796 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
797 rlist, zedlist, philist, fLookUpBasic5ErOverEz );
798 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
799 rlist, zedlist, philist, fLookUpBasic5EphiOverEz);
800 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
801 rlist, zedlist, philist, fLookUpBasic5DeltaEz );
802
803 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
804
805 phiPrime = TMath::TwoPi() - phiPrime ;
806
807 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
808 rlist, zedlist, philist, fLookUpBasic5ErOverEz );
809 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
810 rlist, zedlist, philist, fLookUpBasic5EphiOverEz);
811 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
812 rlist, zedlist, philist, fLookUpBasic5DeltaEz );
813
814 // Flip symmetry of phi integral for symmetric boundary conditions
815 if ( symmetry[4] == 1 ) ephiIntegral *= -1 ;
816 // Flip symmetry of r integral if anti-symmetric boundary conditions
817 if ( symmetry[4] == -1 ) erIntegral *= -1 ;
818
819 }
820
821 if ( fgkZList[i] > 0 ) {
822 erIntegralSum += fCopperRodShiftA[rod]*erIntegral ;
823 ephiIntegralSum += fCopperRodShiftA[rod]*ephiIntegral ;
824 ezIntegralSum += fCopperRodShiftA[rod]*ezIntegral;
825 } else if ( fgkZList[i] < 0 ) {
826 erIntegralSum += fCopperRodShiftC[rod]*erIntegral ;
827 ephiIntegralSum += fCopperRodShiftC[rod]*ephiIntegral ;
828 ezIntegralSum -= fCopperRodShiftC[rod]*ezIntegral;
829 }
830 }
831
832 // OFC Cooper rod shift +++++++++++++++++++++++++++++
833 for ( Int_t rod = 18 ; rod < 36 ; rod++ ) {
834
835 erIntegral = ephiIntegral = ezIntegral = 0.0 ;
836
837 if ( fCopperRodShiftA[rod] == 0 && fgkZList[i] > 0) continue ;
838 if ( fCopperRodShiftC[rod] == 0 && fgkZList[i] < 0) continue ;
839
840 // Rotate to a position where we have maps and prepare to sum
841 phiPrime = phi - (rod-18)*kPhiSlicesPerSector*gridSizePhi ;
842
843 if ( phiPrime < 0 ) phiPrime += TMath::TwoPi() ; // Stay in range from 0 to TwoPi
844
845 if ( (phiPrime >= 0) && (phiPrime <= kPhiSlices*gridSizePhi) ) {
846
847 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
848 rlist, zedlist, philist, fLookUpBasic6ErOverEz );
849 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
850 rlist, zedlist, philist, fLookUpBasic6EphiOverEz);
851 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
852 rlist, zedlist, philist, fLookUpBasic6DeltaEz );
853
854 } else if ( (phiPrime <= TMath::TwoPi()) && (phiPrime >= (TMath::TwoPi()-kPhiSlices*gridSizePhi)) ){
855
856 phiPrime = TMath::TwoPi() - phiPrime ;
857
858 erIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
859 rlist, zedlist, philist, fLookUpBasic6ErOverEz );
860 ephiIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
861 rlist, zedlist, philist, fLookUpBasic6EphiOverEz);
862 ezIntegral = Interpolate3DTable(order, r, z, phiPrime, kRows, kColumns, kPhiSlices,
863 rlist, zedlist, philist, fLookUpBasic6DeltaEz );
864
865 // Flip symmetry of phi integral for symmetric boundary conditions
866 if ( symmetry[5] == 1 ) ephiIntegral *= -1 ;
867 // Flip symmetry of r integral if anti-symmetric boundary conditions
868 if ( symmetry[5] == -1 ) erIntegral *= -1 ;
869
870 }
871
872 if ( fgkZList[i] > 0 ) {
873 erIntegralSum += fCopperRodShiftA[rod]*erIntegral ;
874 ephiIntegralSum += fCopperRodShiftA[rod]*ephiIntegral ;
875 ezIntegralSum += fCopperRodShiftA[rod]*ezIntegral;
876 } else if ( fgkZList[i] < 0 ) {
877 erIntegralSum += fCopperRodShiftC[rod]*erIntegral ;
878 ephiIntegralSum += fCopperRodShiftC[rod]*ephiIntegral ;
879 ezIntegralSum -= fCopperRodShiftC[rod]*ezIntegral;
880 }
881 }
882
883 // put the sum into the final lookup table
884 erOverEz(j,i) = erIntegralSum;
885 ephiOverEz(j,i) = ephiIntegralSum;
886 deltaEz(j,i) = ezIntegralSum;
887
888 // if (j==1) printf("%lf %lf %lf: %lf %lf %lf\n",r, phi, z, erIntegralSum,ephiIntegralSum,ezIntegralSum);
889
890 } // endo r loop
891 } // end of z loop
892 } // end of phi loop
893
894
895 // clear the temporary arrays lists
896 for ( Int_t k = 0 ; k < kPhiSlices ; k++ ) {
897 delete arrayofArrayV[k];
898 delete arrayofCharge[k];
899 }
900
901 AliInfo(" done");
902 fInitLookUp = kTRUE;
903
904}
905
906void AliTPCFCVoltError3D::Print(const Option_t* option) const {
907 //
908 // Print function to check the settings of the Rod shifts and the rotated clips
909 // option=="a" prints the C0 and C1 coefficents for calibration purposes
910 //
911
912 TString opt = option; opt.ToLower();
913 printf("%s\n",GetTitle());
914 printf(" - ROD shifts (residual voltage settings): 40V correspond to 1mm of shift\n");
915 Int_t count = 0;
916 printf(" : A-side - (Rod & Strips) \n ");
917 for (Int_t i=0; i<36;i++) {
918 if (fRodVoltShiftA[i]!=0) {
919 printf("Rod%2d:%3.1fV ",i,fRodVoltShiftA[i]);
920 count++;
921 }
922 if (count==0&&i==35)
923 printf("-> all at 0 V\n");
924 else if (i==35){
925 printf("\n");
926 count=0;
927 }
928 }
929 printf(" : C-side - (Rod & Strips) \n ");
930 for (Int_t i=0; i<36;i++) {
931 if (fRodVoltShiftC[i]!=0) {
932 printf("Rod%2d:%3.1fV ",i,fRodVoltShiftC[i]);
933 count++;
934 }
935 if (count==0&&i==35)
936 printf("-> all at 0 V\n");
937 else if (i==35){
938 printf("\n");
939 count=0;
940 }
941 }
942
943 printf(" - Rotated clips (residual voltage settings): 40V correspond to 1mm of 'offset'\n");
944 if (fRotatedClipVoltA[0]!=0) { printf(" A side (IFC): HV Rod: %3.1f V \n",fRotatedClipVoltA[0]); count++; }
945 if (fRotatedClipVoltA[1]!=0) { printf(" A side (OFC): HV Rod: %3.1f V \n",fRotatedClipVoltA[1]); count++; }
946 if (fRotatedClipVoltC[0]!=0) { printf(" C side (IFC): HV Rod: %3.1f V \n",fRotatedClipVoltC[0]); count++; }
947 if (fRotatedClipVoltC[1]!=0) { printf(" C side (OFC): HV Rod: %3.1f V \n",fRotatedClipVoltC[1]); count++; }
948 if (count==0)
949 printf(" -> no rotated clips \n");
950
951 count=0;
952 printf(" - Copper ROD shifts (without strips):\n");
953 printf(" : A-side - (Copper Rod shift) \n ");
954 for (Int_t i=0; i<36;i++) {
955 if (fCopperRodShiftA[i]!=0) {
956 printf("Rod%2d:%3.1fV ",i,fCopperRodShiftA[i]);
957 count++;
958 }
959 if (count==0&&i==35)
960 printf("-> all at 0 V\n");
961 else if (i==35){
962 printf("\n");
963 count=0;
964 }
965 }
966 printf(" : C-side - (Copper Rod shift) \n ");
967 for (Int_t i=0; i<36;i++) {
968 if (fCopperRodShiftC[i]!=0) {
969 printf("Rod%2d:%3.1fV ",i,fCopperRodShiftC[i]);
970 count++;
971 }
972 if (count==0&&i==35)
973 printf("-> all at 0 V\n");
974 else if (i==35){
975 printf("\n");
976 count=0;
977 }
978 }
979
980 if (opt.Contains("a")) { // Print all details
981 printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
982 printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
983 }
984
985 if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitFCVoltError3D() ...");
986
987}