]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCParam.cxx
Updates to avoid generation of unused TClonesArray. Bug fixes.
[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   //
628   for (Int_t isec=0; isec<fNSector; isec++) {
629     fGlobalMatrix[isec] = 0;
630     fClusterMatrix[isec]= 0;
631     fTrackingMatrix[isec]=0;   
632     AliGeomManager::ELayerID iLayer;
633     Int_t iModule;
634
635     if(isec<fNInnerSector) {
636       iLayer = AliGeomManager::kTPC1;
637       iModule = isec;
638     }
639     else {
640       iLayer = AliGeomManager::kTPC2;
641       iModule = isec - fNInnerSector;
642     }
643
644     UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
645     const char *symname = AliGeomManager::SymName(volid);
646     TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
647     const char *path = symname;
648     if(pne) path=pne->GetTitle();
649     if (!gGeoManager->cd(path)) return kFALSE;      
650     TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
651  
652     //
653     TGeoRotation mchange; 
654     mchange.RotateY(90); mchange.RotateX(90);
655     Float_t ROCcenter[3]; 
656     GetChamberCenter(isec,ROCcenter);
657     //
658     // Convert to global coordinate system
659     //
660     fGlobalMatrix[isec] = new TGeoHMatrix(*m);
661     fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
662     TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
663     fGlobalMatrix[isec]->Multiply(&center);
664     //
665     //  cluster correction matrix
666     //
667     fClusterMatrix[isec] = new TGeoHMatrix;
668     Double_t sectorAngle = 20.*(isec%18)+10;
669     TGeoHMatrix  rotMatrix;
670     rotMatrix.RotateZ(sectorAngle);
671     if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
672       //
673       // mirrored system 
674       //
675       TGeoRotation mirrorZ;
676       mirrorZ.SetAngles(90,0,90,90,180,0);
677       fClusterMatrix[isec]->Multiply(&mirrorZ);
678     }
679     TGeoTranslation trans(0,0,GetZLength(isec));
680     fClusterMatrix[isec]->MultiplyLeft(&trans);
681     fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));        
682     fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
683   }
684   return kTRUE;
685 }
686
687 TGeoHMatrix *  AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
688   //
689   // make local to tracking matrix
690   //
691   Double_t sectorAngle = 20.*(sector%18)+10;
692   TGeoHMatrix *newMatrix = new TGeoHMatrix();
693   newMatrix->RotateZ(sectorAngle);
694   newMatrix->MultiplyLeft(&(geoMatrix->Inverse()));
695   return newMatrix;
696 }
697
698
699
700
701 Bool_t AliTPCParam::GetStatus() const
702 {
703   //get information about object consistency
704   return fbStatus;
705 }
706
707 Int_t AliTPCParam::GetNRowLow() const
708 {
709   //get the number of pad rows in low sector
710   return fNRowLow;
711 }
712 Int_t AliTPCParam::GetNRowUp() const
713 {
714   //get the number of pad rows in up sector
715   return fNRowUp;
716 }
717 Int_t AliTPCParam::GetNRowUp1() const
718 {
719   //get the number of pad rows in up1 sector
720   return fNRowUp1;
721 }
722 Int_t AliTPCParam::GetNRowUp2() const
723 {
724   //get the number of pad rows in up2 sector
725   return fNRowUp2;
726 }
727 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
728 {
729   //get the pad row (irow) radii
730   if ( !(irow<0) && (irow<fNRowLow) ) 
731     return  fPadRowLow[irow];
732   else
733     return 0;
734 }
735
736 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
737 {
738   //get the pad row (irow) radii
739  if ( !(irow<0) && (irow<fNRowUp) ) 
740     return  fPadRowUp[irow];
741   else
742     return 0;
743 }
744
745 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
746 {
747   //get the number of pads in row irow
748   if ( !(irow<0) && (irow<fNRowLow) ) 
749     return  fNPadsLow[irow];
750   else
751     return 0;
752 }
753
754
755 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
756 {
757   //get the number of pads in row irow
758   if ( !(irow<0) && (irow<fNRowUp) ) 
759     return  fNPadsUp[irow];
760   else
761     return 0;
762 }
763 Float_t AliTPCParam::GetYInner(Int_t irow) const
764 {
765   return fYInner[irow];
766 }
767
768
769 Float_t AliTPCParam::GetYOuter(Int_t irow) const
770 {
771   return fYOuter[irow];
772 }
773
774 Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
775 {
776   // returns the sector index
777   // takes as input the angle, index of the pad row and z position
778   if(row<0) return -1;
779
780   if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
781   if (angle < 0.            ) angle += 2.*TMath::Pi();
782  
783   Int_t sector;
784   if(row<fNRowLow) {
785     sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
786     if (z<0) sector += (fNInnerSector>>1);
787   }
788   else {
789     sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
790     if (z<0) sector += (fNOuterSector>>1);
791   }    
792   
793   return sector;
794 }
795
796 Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
797 {
798   // returns the default radial position
799   // of the readout chambers
800
801   const Float_t kROCcenterIn = 110.2;
802   const Float_t kROCcenterOut = 188.45;
803
804   if (isec<fNInnerSector){
805     if (center){
806       center[0] = kROCcenterIn;
807       center[1] = 0; 
808       center[2] = -5.51-0.08; 
809     }
810     return kROCcenterIn;
811   }
812   else{
813     if (center){
814       center[0] = kROCcenterOut;
815       center[1] = 0; 
816       center[2] = -5.61-0.08; 
817     }
818     return kROCcenterOut;
819   }
820 }
821
822
823