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