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