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