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