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