]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCParam.cxx
Add a more fine grained HV treatment during reconstruction to handle the voltage...
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////
19 //  Manager and of geomety  classes for set: TPC                     //
20 //                                                                   //
21 //  !sectors are numbered from  0                                     //
22 //  !pad rows are numbered from 0                                     //
23 //  
24 //  12.6.   changed z relative 
25 //  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
26 //                                                                   //  
27 ///////////////////////////////////////////////////////////////////////
28
29 //
30
31 #include <AliTPCParam.h>
32
33 #include <TGeoManager.h>
34 #include <TGeoPhysicalNode.h>
35 #include <TString.h>
36 #include "AliAlignObj.h"
37 #include "AliAlignObjParams.h"
38 #include "AliLog.h"
39
40 ClassImp(AliTPCParam)
41
42
43 //___________________________________________
44 AliTPCParam::AliTPCParam()
45             :AliDetectorParam(),
46              fbStatus(kFALSE),
47              fInnerRadiusLow(0.),
48              fInnerRadiusUp(0.),
49              fOuterRadiusUp(0.),
50              fOuterRadiusLow(0.),
51              fInnerAngle(0.),
52              fInnerAngleShift(0.),
53              fOuterAngle(0.),
54              fOuterAngleShift(0.),
55              fInnerFrameSpace(0.),
56              fOuterFrameSpace(0.),
57              fInnerWireMount(0.),
58              fOuterWireMount(0.),
59              fNInnerSector(0),
60              fNOuterSector(0),
61              fNSector(0),
62              fZLength(0),
63              fRotAngle(),
64              fGeometryType(0),
65              fTrackingMatrix(0),
66              fClusterMatrix(0), 
67              fGlobalMatrix(0),
68              fNInnerWiresPerPad(0),
69              fInnerWWPitch(0),
70              fInnerDummyWire(0),
71              fInnerOffWire(0.),
72              fRInnerFirstWire(0.),
73              fRInnerLastWire(0.),
74              fLastWireUp1(0.),
75              fNOuter1WiresPerPad(0),
76              fNOuter2WiresPerPad(0),
77              fOuterWWPitch(0.),
78              fOuterDummyWire(0),
79              fOuterOffWire(0.),
80              fROuterFirstWire(0.),
81              fROuterLastWire(0.),
82              fInnerPadPitchLength(0.),
83              fInnerPadPitchWidth(0.),
84              fInnerPadLength(0.),
85              fInnerPadWidth(0.),
86              fOuter1PadPitchLength(0.),
87              fOuter2PadPitchLength(0.),
88              fOuterPadPitchWidth(0.),
89              fOuter1PadLength(0.),
90              fOuter2PadLength(0.),
91              fOuterPadWidth(0.),
92              fBMWPCReadout(kFALSE),
93              fNCrossRows(0),
94              fNRowLow(0),
95              fNRowUp1(0),
96              fNRowUp2(0),
97              fNRowUp(0),
98              fNtRows(0),
99              fDiffT(0.),
100              fDiffL(0.),
101              fGasGain(0.),
102              fDriftV(0.),
103              fOmegaTau(0.),
104              fAttCoef(0.),
105              fOxyCont(0.),
106              fPadCoupling(0.),
107              fZeroSup(0),
108              fNoise(0.),
109              fChipGain(0.),
110              fChipNorm(0.),
111              fTSample(0.),
112              fZWidth(0.),
113              fTSigma(0.),
114              fMaxTBin(0),
115              fADCSat(0),
116              fADCDynRange(0.),
117              fTotalNormFac(0.),
118              fNoiseNormFac(0.),
119              fNominalVoltage(),
120              fMaxVoltageDeviation(40.),
121              fMaxDipVoltage(2.),
122              fMaxHVfractionBad(.4),
123              fVoltageDipScanPeriod(1.),
124              fNResponseMax(0),
125              fResponseThreshold(0.),
126              fCurrentMax(0),
127              fResponseBin(0),
128              fResponseWeight(0),
129              fGateDelay(0.),
130              fL1Delay(0.),
131              fNTBinsBeforeL1(0),
132              fNTBinsL1(0.)   
133 {   
134   //
135   //constructor sets the default parameters
136   //
137
138   SetTitle("75x40_100x60_150x60");
139   SetDefault();  
140 }
141
142 AliTPCParam::~AliTPCParam()
143 {
144   //
145   //destructor deletes some dynamicaly alocated variables
146   //
147
148   if (fResponseBin!=0)    delete [] fResponseBin;
149   if (fResponseWeight!=0) delete [] fResponseWeight;
150   if (fRotAngle      !=0) delete [] fRotAngle;
151
152   CleanGeoMatrices();
153
154 }
155
156 Int_t  AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index)  const
157 {
158   //
159   // calculates sector number (index[1], undefined on input)
160   // xyz intact
161   //
162
163   Float_t angle,x1;
164   Int_t sector;
165   Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
166   if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
167   else
168     {
169       angle =TMath::ASin(xyz[1]/r);
170       if   (xyz[0]<0)   angle=TMath::Pi()-angle;
171       if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
172     }
173
174   sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));      
175  
176   Float_t cos,sin;
177   AdjustCosSin(sector,cos,sin);
178   x1=xyz[0]*cos + xyz[1]*sin;
179
180   if (x1>fOuterRadiusLow)
181     {
182       sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
183       if (xyz[2]<0)     sector+=(fNOuterSector>>1);            
184     }
185     else   
186       if (xyz[2]<0) sector+=(fNInnerSector>>1);  
187   if (sector<0 || sector>=fNSector) AliError(Form("Wrong sector %d",sector));
188   index[1]=sector; // calculated sector number
189   index[0]=1; // indicates system after transformation
190   return sector;
191 }
192
193 Bool_t  AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
194 {
195   //transformation from input coodination system to output coordination system
196   switch (index[0]){
197   case 0:
198     break;
199   };
200
201   return kFALSE;
202
203 }
204
205 Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const 
206 {
207   //
208   //calculates pad row of point xyz - transformation to system 8 (digit system)
209   //
210   Int_t system = index[0];
211   if (0==system) {
212     Transform0to1(xyz,index); 
213     system=1;
214   }
215   if (1==system) {
216     Transform1to2(xyz,index); 
217     system=2;
218   }
219     
220   if (fGeometryType==0){ //straight row    
221     if (2==system) {
222       Transform2to3(xyz,index);       
223       system=3;
224     } 
225     if (3==system) {
226       Transform3to4(xyz,index);
227       system=4; 
228     }
229     if (4==system) {
230       Transform4to8(xyz,index);
231       system=8;     
232     }
233     if (8==system) {
234       index[0]=8;
235       return index[2];
236     } 
237   }
238
239   if (fGeometryType==1){ //cylindrical geometry    
240     if (2==system) {
241       Transform2to5(xyz,index);       
242       system=5;
243     } 
244     if (5==system) {
245       Transform2to3(xyz,index);
246       system=6;
247     }
248     if (6==system) {
249       Transform3to4(xyz,index); 
250       system=7;
251     }
252     if (8==system) {
253       index[0]=8;
254       return index[2];
255     }
256   } 
257   index[0]=system;
258   return -1; //if no reasonable system     
259 }
260
261 void  AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
262                         Float_t outershift)
263 {
264   //
265   // set opening angles  
266   static const  Float_t  kDegtoRad = 0.01745329251994;
267   fInnerAngle = innerangle;       //opening angle of Inner sector
268   fInnerAngleShift = innershift;  //shift of first inner sector center to the 0
269   fOuterAngle = outerangle;       //opening angle of outer sector
270   fOuterAngleShift = outershift;  //shift of first sector center to the 0  
271   fInnerAngle *=kDegtoRad;
272   fInnerAngleShift *=kDegtoRad;
273   fOuterAngle *=kDegtoRad;
274   fOuterAngleShift *=kDegtoRad;
275 }
276
277 Float_t  AliTPCParam::GetInnerAngle() const
278 {
279   //return angle 
280   return fInnerAngle;
281
282 }
283
284 Float_t  AliTPCParam::GetInnerAngleShift() const
285 {  
286   //return angle   
287   return fInnerAngleShift;  
288 }
289 Float_t  AliTPCParam::GetOuterAngle() const
290
291   //return angle 
292   return fOuterAngle;
293
294 Float_t  AliTPCParam::GetOuterAngleShift() const
295
296   //return angle 
297
298      return fOuterAngleShift;
299
300
301
302 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
303 {
304   //
305   //give index of the given sector and pad row 
306   //no control if the sectors and rows  are reasonable !!!
307   //
308   if (sector<fNInnerSector) return sector*fNRowLow+row;
309   return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;  
310 }
311
312 Bool_t   AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
313 {
314   //
315   //return sector and padrow for given index
316   //if index is reasonable returns true else return false
317   //
318   if ( (index<0) || (index>fNtRows))  return kFALSE;
319   Int_t outindex = fNInnerSector*fNRowLow;
320   if (index<outindex) {
321     sector = index/fNRowLow;
322     row    = index - sector*fNRowLow;
323     return kTRUE;
324   }
325   index-= outindex;
326   sector = index/fNRowUp;
327   row    = index - sector*fNRowUp;
328   sector += fNInnerSector;
329   return kTRUE;         
330
331
332 void AliTPCParam::SetDefault()
333 {
334   //
335   //set default parameters
336   //
337   //const static  Int_t kMaxRows=600; 
338   //
339   //sector default parameters
340   //
341   static const  Float_t kInnerRadiusLow = 83.65;
342   static const  Float_t kInnerRadiusUp  = 133.3;
343   static const  Float_t kOuterRadiusLow = 133.5;
344   static const  Float_t kOuterRadiusUp  = 247.7;
345   static const  Float_t kInnerAngle = 20; // 20 degrees
346   static const  Float_t kInnerAngleShift = 10;
347   static const  Float_t kOuterAngle = 20; //  20 degrees
348   static const  Float_t kOuterAngleShift = 10;
349   static const  Float_t kInnerFrameSpace = 1.5;
350   static const  Float_t kOuterFrameSpace = 1.5;
351   static const  Float_t kInnerWireMount = 1.2;
352   static const  Float_t kOuterWireMount = 1.4;
353   static const  Float_t kZLength =250.;
354   static const  Int_t   kGeometryType = 0; //straight rows 
355   static const Int_t kNRowLow = 63;
356   static const Int_t kNRowUp1 = 64;
357   static const Int_t kNRowUp2 = 32;
358   static const Int_t  kNRowUp = 96;
359   //
360   //wires default parameters
361   //
362   static const Int_t    kNInnerWiresPerPad = 3;
363   static const Int_t    kInnerDummyWire = 2;
364   static const Float_t  kInnerWWPitch = 0.25;
365   static const Float_t  kRInnerFirstWire = 84.475;
366   static const Float_t  kRInnerLastWire = 132.475;
367   static const Float_t  kInnerOffWire = 0.5;
368   static const Int_t    kNOuter1WiresPerPad = 4;
369   static const Int_t    kNOuter2WiresPerPad = 6;
370   static const Float_t  kOuterWWPitch = 0.25;  
371   static const Float_t  kROuterFirstWire = 134.225;
372   static const Float_t  kROuterLastWire = 246.975;
373   static const Int_t    kOuterDummyWire = 2;
374   static const Float_t  kOuterOffWire = 0.5;
375   //
376   //pad default parameters
377   // 
378   static const Float_t  kInnerPadPitchLength = 0.75;
379   static const Float_t  kInnerPadPitchWidth = 0.40;
380   static const Float_t  kInnerPadLength = 0.75;
381   static const Float_t  kInnerPadWidth = 0.40;
382   static const Float_t  kOuter1PadPitchLength = 1.0;
383   static const Float_t  kOuterPadPitchWidth = 0.6;
384   static const Float_t  kOuter1PadLength = 1.0;
385   static const Float_t  kOuterPadWidth = 0.6;
386   static const Float_t  kOuter2PadPitchLength = 1.5;
387   static const Float_t  kOuter2PadLength = 1.5;
388
389   static const Bool_t   kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM 
390   static const Int_t    kNCrossRows = 1; //number of rows to cross-talk
391   
392   //
393   //gas default parameters
394   //
395   static const  Float_t  kDiffT = 2.2e-2; 
396   static const  Float_t  kDiffL = 2.2e-2;
397   static const  Float_t  kGasGain = 2.e4;
398   static const  Float_t  kDriftV  =2.83e6;
399   static const  Float_t  kOmegaTau = 0.145;
400   static const  Float_t  kAttCoef = 250.;
401   static const  Float_t  kOxyCont = 5.e-6;
402   //
403   //electronic default parameters
404   //
405   static const  Float_t  kPadCoupling=0.5;
406   static const  Int_t    kZeroSup=2;
407   static const  Float_t  kNoise = 1000;                            
408   static const  Float_t  kChipGain = 12;
409   static const  Float_t  kChipNorm = 0.4;
410   static const  Float_t  kTSample = 2.e-7; 
411   static const  Float_t  kTFWHM   = 1.9e-7;  //fwhm of charge distribution
412   static const  Int_t    kMaxTBin =445;  
413   static const  Int_t    kADCSat  =1024;  
414   static const  Float_t  kADCDynRange =2000.;  
415   // 
416   //response constants
417   //
418   static const Int_t     kNResponseMax=100;
419   static const Float_t   kResponseThreshold=0.01;     
420   //L1 constants
421   //  static const Float_t   kGateDelay=6.1e-6; //In s
422   static const Float_t   kGateDelay=0.; //For the moment no gating
423   //  static const Float_t   kL1Delay=6.5e-6; //In s
424   static const Float_t   kL1Delay=0.; //For the moment no delay
425   //  static const UShort_t  kNTBinsBeforeL1=14;
426   static const UShort_t  kNTBinsBeforeL1=0; //For the moment no shift
427   fbStatus = kFALSE;
428   //
429   //set sector parameters
430   //
431   SetInnerRadiusLow(kInnerRadiusLow);
432   SetOuterRadiusLow(kOuterRadiusLow);
433   SetInnerRadiusUp(kInnerRadiusUp);
434   SetOuterRadiusUp(kOuterRadiusUp);
435   SetInnerFrameSpace(kInnerFrameSpace);
436   SetOuterFrameSpace(kOuterFrameSpace);
437   SetInnerWireMount(kInnerWireMount);
438   SetOuterWireMount(kOuterWireMount);
439   SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
440   SetZLength(kZLength);
441   SetGeometryType(kGeometryType);
442   SetRowNLow(kNRowLow);
443   SetRowNUp1 (kNRowUp1);
444   SetRowNUp2(kNRowUp2);
445   SetRowNUp(kNRowUp);
446   //
447   //set wire parameters
448   //
449   SetInnerNWires(kNInnerWiresPerPad);
450   SetInnerDummyWire(kInnerDummyWire);
451   SetInnerOffWire(kInnerOffWire);
452   SetOuter1NWires(kNOuter1WiresPerPad);
453   SetOuter2NWire(kNOuter2WiresPerPad);
454   SetOuterDummyWire(kOuterDummyWire);
455   SetOuterOffWire(kOuterOffWire);
456   SetInnerWWPitch(kInnerWWPitch);
457   SetRInnerFirstWire(kRInnerFirstWire);
458   SetRInnerLastWire(kRInnerLastWire);
459   SetOuterWWPitch(kOuterWWPitch);
460   SetROuterFirstWire(kROuterFirstWire);
461   SetROuterLastWire(kROuterLastWire);  
462   //
463   //set pad parameter
464   //
465   SetInnerPadPitchLength(kInnerPadPitchLength);
466   SetInnerPadPitchWidth(kInnerPadPitchWidth);
467   SetInnerPadLength(kInnerPadLength);
468   SetInnerPadWidth(kInnerPadWidth);
469   SetOuter1PadPitchLength(kOuter1PadPitchLength); 
470   SetOuter2PadPitchLength(kOuter2PadPitchLength);
471   SetOuterPadPitchWidth(kOuterPadPitchWidth);
472   SetOuter1PadLength(kOuter1PadLength);
473   SetOuter2PadLength(kOuter2PadLength);
474   SetOuterPadWidth(kOuterPadWidth); 
475   SetMWPCReadout(kBMWPCReadout);
476   SetNCrossRows(kNCrossRows);
477   //
478   //set gas paremeters
479   //
480   SetDiffT(kDiffT);
481   SetDiffL(kDiffL);
482   SetGasGain(kGasGain);
483   SetDriftV(kDriftV);
484   SetOmegaTau(kOmegaTau);
485   SetAttCoef(kAttCoef);
486   SetOxyCont(kOxyCont);
487   //
488   //set electronivc parameters  
489   //
490   SetPadCoupling(kPadCoupling);
491   SetZeroSup(kZeroSup);
492   SetNoise(kNoise);
493   SetChipGain(kChipGain);
494   SetChipNorm(kChipNorm);   
495   SetTSample(kTSample);
496   SetTFWHM(kTFWHM);
497   SetMaxTBin(kMaxTBin);
498   SetADCSat(kADCSat);
499   SetADCDynRange(kADCDynRange);
500   for (UInt_t i=0; i<36; i++)
501   {
502     SetNominalVoltage(1196.0, i);
503   }
504   for (UInt_t i=36; i<72; i++)
505   {
506     SetNominalVoltage(1417.0, i);
507   }
508 //   //set magnetic field
509 //   SetBField(kBField);
510 //   SetNPrimLoss(kNPrimLoss);
511 //   SetNTotalLoss(kNTotalLoss);
512   //
513   //set response  parameters  
514   //
515   SetNResponseMax(kNResponseMax); 
516   SetResponseThreshold(static_cast<int>(kResponseThreshold));
517   //L1 data
518   SetGateDelay(kGateDelay);
519   SetL1Delay(kL1Delay);
520   SetNTBinsBeforeL1(kNTBinsBeforeL1);
521 }
522
523           
524 Bool_t AliTPCParam::Update()
525 {
526   //
527   // update some calculated parameter which must be updated after changing "base"
528   // parameters 
529   // for example we can change size of pads and according this recalculate number
530   // of pad rows, number of of pads in given row ....
531   //
532   const Float_t kQel = 1.602e-19; // elementary charge
533   fbStatus = kFALSE;
534
535   Int_t i,j;  //loop variables because HP 
536   //-----------------Sector section------------------------------------------
537   //calclulate number of sectors
538   fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); 
539        // number of inner sectors - factor 0.2 to don't be influnced by inprecision
540   if (fNInnerSector%2) return kFALSE;
541   fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2); 
542   if (fNOuterSector%2) return kFALSE;
543   fNSector  = fNInnerSector+fNOuterSector;
544
545   if (fRotAngle!=0) delete [] fRotAngle;
546   fRotAngle = new Float_t[4*fNSector];
547   //calculate sin and cosine of rotations angle     
548   //sectors angles numbering from 0
549
550   j=fNInnerSector*2;
551   Float_t angle = fInnerAngleShift; 
552   for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
553     fRotAngle[i]=TMath::Cos(angle);
554     fRotAngle[i+1]=TMath::Sin(angle);
555     fRotAngle[j] =  fRotAngle[i];
556     fRotAngle[j+1] =  fRotAngle[i+1];
557     fRotAngle[i+2] =angle;
558     fRotAngle[j+2] =angle;    
559   }
560   angle = fOuterAngleShift; 
561   j=(fNInnerSector+fNOuterSector/2)*4;
562   for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
563     fRotAngle[i]=TMath::Cos(angle);
564     fRotAngle[i+1]=TMath::Sin(angle);
565     fRotAngle[j] =  fRotAngle[i];
566     fRotAngle[j+1] =  fRotAngle[i+1];
567     fRotAngle[i+2] =angle;
568     fRotAngle[j+2] =angle;    
569   }
570
571   fZWidth = fTSample*fDriftV;  
572   fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
573   fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
574   //wire section 
575   /*  Int_t nwire;
576   Float_t wspace; //available space for wire
577   Float_t dummyspace; //dummyspace for wire
578  
579   wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
580   nwire = Int_t(wspace/fInnerWWPitch);
581   wspace = Float_t(nwire)*fInnerWWPitch;
582   dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;  
583   wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
584   nwire = Int_t(wspace/fOuterWWPitch);
585   wspace = Float_t(nwire)*fOuterWWPitch;
586   dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.; 
587   fROuterFirstWire = fOuterRadiusLow+dummyspace;
588   fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
589   */
590   
591   //
592   //response data
593   //
594   if (fResponseBin) delete [] fResponseBin;
595   if (fResponseWeight) delete [] fResponseWeight;
596   fResponseBin    = new Int_t[3*fNResponseMax];
597   fResponseWeight = new Float_t[fNResponseMax];
598
599   //L1 data
600   fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
601   fbStatus = kTRUE;
602   return kTRUE;
603 }
604
605 void AliTPCParam::CleanGeoMatrices(){
606   //
607   // clean geo matrices
608   //
609
610   if (fTrackingMatrix) {
611     for(Int_t i = 0; i < fNSector; i++)
612       delete fTrackingMatrix[i];
613     delete [] fTrackingMatrix;
614   }
615   
616   if (fClusterMatrix) {
617     for(Int_t i = 0; i < fNSector; i++)
618       delete fClusterMatrix[i];
619     delete [] fClusterMatrix;
620   }
621   
622   if (fGlobalMatrix) {
623     for(Int_t i = 0; i < fNSector; i++)
624       delete fGlobalMatrix[i];
625     delete [] fGlobalMatrix;
626   }
627   
628   return;
629 }
630
631 Bool_t AliTPCParam::ReadGeoMatrices(){
632   //
633   // read geo matrixes
634   //
635   if (!gGeoManager){
636     AliFatal("Geo manager not initialized\n");
637   }
638   AliAlignObjParams o;
639   //
640
641   // clean geo matrices
642   CleanGeoMatrices();
643
644   // create new geo matrices
645   fTrackingMatrix = new TGeoHMatrix*[fNSector];
646   fClusterMatrix = new TGeoHMatrix*[fNSector];
647   fGlobalMatrix = new TGeoHMatrix*[fNSector];
648   for (Int_t isec=0; isec<fNSector; isec++) {
649     fGlobalMatrix[isec] = 0;
650     fClusterMatrix[isec]= 0;
651     fTrackingMatrix[isec]=0;
652   }   
653   //
654   for (Int_t isec=0; isec<fNSector; isec++) {
655     fGlobalMatrix[isec] = 0;
656     fClusterMatrix[isec]= 0;
657     fTrackingMatrix[isec]=0;   
658     AliGeomManager::ELayerID iLayer;
659     Int_t iModule;
660
661     if(isec<fNInnerSector) {
662       iLayer = AliGeomManager::kTPC1;
663       iModule = isec;
664     }
665     else {
666       iLayer = AliGeomManager::kTPC2;
667       iModule = isec - fNInnerSector;
668     }
669
670     UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
671     TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(volid);
672     if(!pne)
673     {
674       AliError(Form("Alignable entry for volume ID %d not in geometry. Exiting!",volid));
675       return kFALSE;
676     }
677     const char *path = pne->GetTitle();
678     if (!gGeoManager->cd(path)) return kFALSE;
679     TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
680     // Since GEANT4 does not allow reflections, in this case the reflection
681     // component if the matrix is embedded by TGeo inside TGeoScaledShape
682     if (gGeoManager->GetCurrentVolume()->GetShape()->IsReflected()) 
683        m->ReflectZ(kFALSE, kTRUE);
684     //
685     TGeoRotation mchange; 
686     mchange.RotateY(90); mchange.RotateX(90);
687     Float_t ROCcenter[3]; 
688     GetChamberCenter(isec,ROCcenter);
689     //
690     // Convert to global coordinate system
691     //
692     fGlobalMatrix[isec] = new TGeoHMatrix(*m);
693     fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
694     TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
695     fGlobalMatrix[isec]->Multiply(&center);
696     //
697     //  cluster correction matrix
698     //
699     fClusterMatrix[isec] = new TGeoHMatrix;
700     Double_t sectorAngle = 20.*(isec%18)+10;
701     TGeoHMatrix  rotMatrix;
702     rotMatrix.RotateZ(sectorAngle);
703     if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
704       //
705       // mirrored system 
706       //
707       TGeoRotation mirrorZ;
708       mirrorZ.SetAngles(90,0,90,90,180,0);
709       fClusterMatrix[isec]->Multiply(&mirrorZ);
710     }
711     TGeoTranslation trans(0,0,GetZLength(isec));
712     fClusterMatrix[isec]->MultiplyLeft(&trans);
713     fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));        
714     fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
715   }
716   return kTRUE;
717 }
718
719 TGeoHMatrix *  AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
720   //
721   // make local to tracking matrix
722   //
723   Double_t sectorAngle = 20.*(sector%18)+10;
724   TGeoHMatrix *newMatrix = new TGeoHMatrix();
725   newMatrix->RotateZ(sectorAngle);
726   newMatrix->MultiplyLeft(&(geoMatrix->Inverse()));
727   return newMatrix;
728 }
729
730
731
732
733 Bool_t AliTPCParam::GetStatus() const
734 {
735   //get information about object consistency
736   return fbStatus;
737 }
738
739 Int_t AliTPCParam::GetNRowLow() const
740 {
741   //get the number of pad rows in low sector
742   return fNRowLow;
743 }
744 Int_t AliTPCParam::GetNRowUp() const
745 {
746   //get the number of pad rows in up sector
747   return fNRowUp;
748 }
749 Int_t AliTPCParam::GetNRowUp1() const
750 {
751   //get the number of pad rows in up1 sector
752   return fNRowUp1;
753 }
754 Int_t AliTPCParam::GetNRowUp2() const
755 {
756   //get the number of pad rows in up2 sector
757   return fNRowUp2;
758 }
759 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
760 {
761   //get the pad row (irow) radii
762   if ( !(irow<0) && (irow<fNRowLow) ) 
763     return  fPadRowLow[irow];
764   else
765     return 0;
766 }
767
768 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
769 {
770   //get the pad row (irow) radii
771  if ( !(irow<0) && (irow<fNRowUp) ) 
772     return  fPadRowUp[irow];
773   else
774     return 0;
775 }
776
777 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
778 {
779   //get the number of pads in row irow
780   if ( !(irow<0) && (irow<fNRowLow) ) 
781     return  fNPadsLow[irow];
782   else
783     return 0;
784 }
785
786
787 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
788 {
789   //get the number of pads in row irow
790   if ( !(irow<0) && (irow<fNRowUp) ) 
791     return  fNPadsUp[irow];
792   else
793     return 0;
794 }
795 Float_t AliTPCParam::GetYInner(Int_t irow) const
796 {
797   return fYInner[irow];
798 }
799
800
801 Float_t AliTPCParam::GetYOuter(Int_t irow) const
802 {
803   return fYOuter[irow];
804 }
805
806 Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
807 {
808   // returns the sector index
809   // takes as input the angle, index of the pad row and z position
810   if(row<0) return -1;
811
812   if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
813   if (angle < 0.            ) angle += 2.*TMath::Pi();
814  
815   Int_t sector;
816   if(row<fNRowLow) {
817     sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
818     if (z<0) sector += (fNInnerSector>>1);
819   }
820   else {
821     sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
822     if (z<0) sector += (fNOuterSector>>1);
823   }    
824   
825   return sector;
826 }
827
828 Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
829 {
830   // returns the default radial position
831   // of the readout chambers
832
833   const Float_t kROCcenterIn = 110.2;
834   const Float_t kROCcenterOut = 188.45;
835
836   if (isec<fNInnerSector){
837     if (center){
838       center[0] = kROCcenterIn;
839       center[1] = 0; 
840       center[2] = -5.51-0.08; 
841     }
842     return kROCcenterIn;
843   }
844   else{
845     if (center){
846       center[0] = kROCcenterOut;
847       center[1] = 0; 
848       center[2] = -5.61-0.08; 
849     }
850     return kROCcenterOut;
851   }
852 }
853