1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.5 1999/10/05 17:18:27 fca
19 Correct GetWire check on even/odd fnWires
21 Revision 1.4 1999/09/29 09:24:34 fca
22 Introduction of the Copyright and cvs Log
26 ///////////////////////////////////////////////////////////////////////
27 // Manager and of geomety classes for set: TPC //
29 // !sectors are numbered from 0 //
30 // !pad rows are numbered from 0 //
32 // 12.6. changed z relative
33 // Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
35 ///////////////////////////////////////////////////////////////////////
41 #include "AliTPCSecGeo.h"
42 #include <AliTPCParam.h>
47 const static Int_t kMaxRows=600;
51 const static Int_t kMaxTBin =512;
54 const static Float_t kInnerRadiusLow = 83.9;
55 const static Float_t kOuterRadiusLow = 146.9;
56 const static Float_t kInnerRadiusUp = 141.3;
57 const static Float_t kOuterRadiusUp = 249.4;
59 const static Float_t kInnerAngle = 0.34906585; // 20 degrees
60 const static Float_t kInnerAngleShift = 0;
61 const static Float_t kOuterAngle = 0.34906585; // 20 degrees
62 const static Float_t kOuterAngleShift = 0;
64 const static Float_t kPadPitchLength = 2.05;
65 const static Float_t kPadPitchWidth = 0.35;
66 const static Float_t kPadLength = 2.05;
67 const static Float_t kPadWidth = 0.35;
69 // Number of wires per pad and wire-wire pitch
70 const static Int_t knWires = 5;
71 const static Float_t kDiffT = 2.2e-2;
72 const static Float_t kDiffL = 2.2e-2;
73 const static Float_t kDriftV =2.85e6;
75 const static Float_t kOmegaTau = 0.145;
76 const static Float_t kAttCoef = 250.;
77 const static Float_t kOxyCont = 5.e-6;
80 const static Float_t kChipGain = 12;
81 const static Float_t kGasGain = 2e4;
82 const static Float_t kTSample = 2.e-7; //TSAMPLE
83 const static Float_t kTFWHM = 2.5e-7; //fwhm of charge distribution
85 const static Float_t kNoise = 1000; //default noise = 1000 el
86 const static Int_t kZeroSup=5;
87 const static Float_t kPadCoupling=0.5;
89 const static Float_t kEdgeSectorSpace = 1.15;
90 const static Float_t kDegtoRad = 0.01745329251994;
91 const static Float_t kRadtoDeg = 57.29577951309;
96 //___________________________________________
97 AliTPCParam::AliTPCParam()
99 //constructor set the default parameters
104 void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
105 Float_t outershift, Bool_t inDegree)
108 // set opening angles
109 fInnerAngle = innerangle; //opening angle of Inner sector
110 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
111 fOuterAngle = outerangle; //opening angle of outer sector
112 fOuterAngleShift = outershift; //shift of first sector center to the 0
113 if (inDegree==kTRUE){
114 fInnerAngle *=kDegtoRad;
115 fInnerAngleShift *=kDegtoRad;
116 fOuterAngle *=kDegtoRad;
117 fOuterAngleShift *=kDegtoRad;
122 void AliTPCParam::CRXYZtoXYZ(Float_t *xyz,
123 const Int_t §or, const Int_t & padrow, Int_t option) const
125 //transform relative coordinates to absolute
126 Bool_t rel = ( (option&2)!=0);
128 row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0];
129 if (rel==kTRUE) //if the position is relative to pad row
132 xyz[0]+=(Int_t) padrow*fPadPitchLength;
136 if (sector<fNInnerSector) {
137 if ( sector>=(fNInnerSector>>1)) xyz[2]*=-1.;
139 if ( (sector-fNInnerSector) >= (fNOuterSector>>1) ) xyz[2]*=-1;
145 AdjustAngles(sector,cos,sin);
146 xyz[0]= x1*cos - y1*sin;
147 xyz[1]= x1*sin + y1*cos;
150 void AliTPCParam::XYZtoCRXYZ(Float_t *xyz,
151 Int_t §or, Int_t & padrow, Int_t option)
153 //transform global position to the position relative to the sector padrow
154 //if option=0 X calculate absolute calculate sector
155 //if option=1 X absolute use input sector
156 //if option=2 X relative to pad row calculate sector
157 //if option=3 X relative use input sector
158 //!!!!!!!!! WE start to calculate rows from row = 0
160 Bool_t rel = ( (option&2)!=0);
161 //option 0 and 2 means that we don't have information about sector
162 //we calculate sector
165 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
166 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0;
169 angle =TMath::ASin(xyz[1]/r);
170 if (xyz[0]<0) angle=TMath::Pi()-angle;
171 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
173 //transform global position to the position relative to the sector padrow
174 //fistly calculate xyz[0] radius for lover sector
175 //bacause in this moment we dont know in which sector we are
176 sector=Int_t((angle-fInnerAngleShift)/fInnerAngle);
179 //firstly we suppose that we are in inner sector
181 AdjustAngles(sector,cos,sin);
183 x1=xyz[0]*cos + xyz[1]*sin;
184 y1=-xyz[0]*sin + xyz[1]*cos;
185 if (x1>fOuterRadiusLow)
187 sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
188 AdjustAngles(sector,cos,sin);
189 x1=xyz[0]*cos + xyz[1]*sin;
190 y1=-xyz[0]*sin + xyz[1]*cos;
191 if (xyz[2]<0) sector+=(fNOuterSector>>1);
194 if (xyz[2]<0) sector+=(fNInnerSector>>1);
196 if (x1<fOuterRadiusLow)
197 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+0.5);
199 padrow = Int_t( (x1-fPadRowUp[0])/fPadPitchLength+0.5);
201 if (x1<fOuterRadiusLow) x1-=padrow*fPadPitchLength+fPadRowLow[0];
203 x1-=padrow*fPadPitchLength+fPadRowUp[0];
206 xyz[2]=z_end-TMath::Abs(xyz[2]);
207 } //endif we don't have information about sector
209 //if we have information about sector
211 AdjustAngles(sector,cos,sin);
214 //rotate to given sector
215 x1=xyz[0]*cos + xyz[1]*sin;
216 y1=-xyz[0]*sin + xyz[1]*cos;
217 //calculate pad row number
218 if (sector<fNInnerSector) {
219 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
222 padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
224 //if we store relative position calculate position relative to pad row
226 if (sector<fNInnerSector)
227 x1-=padrow*fPadPitchLength+fPadRowLow[0];
229 x1-=padrow*fPadPitchLength+fPadRowUp[0];
233 xyz[2]=z_end-TMath::Abs(xyz[2]);
237 void AliTPCParam::CRYZtoTimePad(const Float_t &y, const Float_t &z,
238 Float_t &time, Float_t &pad,
239 Int_t sector, Int_t padrow)
241 //transform position in cm to position in time slices and pads
242 Float_t nofpads = GetNPads(sector,padrow);
243 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
244 pad = y/(fPadPitchWidth)+padc;
247 void AliTPCParam::CRTimePadtoYZ(Float_t &y, Float_t &z,
248 const Float_t &time, const Float_t &pad,
249 Int_t sector, Int_t padrow)
251 //transform position in time slices and pads to cm
252 Float_t nofpads = GetNPads(sector,padrow);
253 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
254 y=(pad-padc)*fPadPitchWidth;
258 Int_t AliTPCParam::GetWire(Float_t & x)
261 //return wire number of pad for electron at relative position x
262 //to the center of the pad
263 //and adjust x to the wire position
264 //we suppose that if the wire number is even the center wire
265 //is at center of pad
267 Float_t xrel= x/fWWPitch;
268 if ((fnWires&1)==0) xrel+=1;
270 Int_t nw=Int_t(xrel);
274 if ((fnWires&1)==0) x-=fWWPitch/2.;
278 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
281 //give index of the given sector and pad row
282 //no control if the sectors and rows are reasonable !!!
284 if (sector<fNInnerSector) return sector*fnRowLow+row;
285 return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;
288 Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row)
291 //return sector and padrow for given index
292 //if index is reasonable return true else return false
294 if ( (index<0) || (index>fNtRows)) return kFALSE;
295 Int_t outindex = fNInnerSector*fnRowLow;
296 if (index<outindex) {
297 sector = index/fnRowLow;
298 row = index - sector*fnRowLow;
302 sector = index/fnRowUp;
303 row = index - sector*fnRowUp;
309 Int_t AliTPCParam::GetPadRow(Int_t isec, Float_t &x)
312 //return the pad row for given x (transformed)
314 Float_t row_first=GetPadRowRadii(isec,0);
315 Int_t row = Int_t(( x-row_first+1.5*fPadPitchLength)/fPadPitchLength)-1;
316 //Int_t will make from -0.5 0 but we want to make -1 so we add and after substract 1
317 x -=row* fPadPitchLength+row_first;
318 if ( (row<0)||(row>=GetNRow(isec))) return -1;
322 void AliTPCParam::SetDefault()
324 //set default TPC param
326 //set sector parameters
327 fInnerRadiusLow = kInnerRadiusLow;
328 fOuterRadiusLow = kOuterRadiusLow;
329 fInnerRadiusUp = kInnerRadiusUp;
330 fOuterRadiusUp = kOuterRadiusUp;
331 SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift);
332 // set default pad size and shape
333 fPadPitchLength = kPadPitchLength;
334 fPadPitchWidth = kPadPitchWidth;
335 fPadLength = kPadLength;
336 fPadWidth = kPadWidth;
339 fWWPitch= kPadPitchLength/Float_t(knWires);
342 fOmegaTau = kOmegaTau;
346 fChipGain = kChipGain;
349 fPadCoupling= kPadCoupling;
351 fTSigma =kTFWHM/2.35;
357 void AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
360 //set cosinus and sinus of rotation angles for sector isec
362 cos=fRotAngle[isec*2];
363 sin=fRotAngle[isec*2+1];
366 Bool_t AliTPCParam::Update()
369 // update some calculated parameter which must be updated after changing "base"
371 // for example we can change size of pads and according this recalculate number
372 // of pad rows, number of of pads in given row ....
376 Int_t i,j; //loop variables because HP
377 //-----------------Sector section------------------------------------------
378 //calclulate number of sectors
379 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); // number of inner sectors - factor 0.2 to don't
380 //be influnced by inprecision
381 if (fNInnerSector%2) return kFALSE;
382 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
383 if (fNOuterSector%2) return kFALSE;
384 fNSector = fNInnerSector+fNOuterSector;
385 //calculate sin and cosine of rotations angle
386 //sectors angles numbering from 0
388 Float_t angle = fInnerAngleShift;
389 for (i=0; i<fNInnerSector*2; i+=2, j+=2 , angle +=fInnerAngle){
390 fRotAngle[i]=TMath::Cos(angle);
391 fRotAngle[i+1]=TMath::Sin(angle);
392 fRotAngle[j] = fRotAngle[i];
393 fRotAngle[j+1] = fRotAngle[i+1];
395 angle = fOuterAngleShift;
396 j=(fNInnerSector+fNOuterSector/2)*2;
397 for (i=fNInnerSector*2; i<fNSector*2; i+=2,j+=2, angle +=fOuterAngle){
398 fRotAngle[i]=TMath::Cos(angle);
399 fRotAngle[i+1]=TMath::Sin(angle);
400 fRotAngle[j] = fRotAngle[i];
401 fRotAngle[j+1] = fRotAngle[i+1];
405 //----------------PAD section------------------------------------
406 //recalculate and check some geometric parameters
407 if (0.001>fPadPitchLength){
408 cout<<"ERROR !!! Small pad pitch length \n"<<flush;
411 if (fPadPitchLength<fPadLength) {
412 cout<<"ERROR !!! Pitch length smaller then length of pad \n"<<flush;
415 fnRowUp = Int_t((0.01+fOuterRadiusUp-fOuterRadiusLow)/fPadPitchLength)+1;
416 if ( kMaxRows<fnRowUp) fnRowUp = kMaxRows;
417 if (1>fnRowUp) return kFALSE;
419 fnRowLow = Int_t((0.01+fInnerRadiusUp-fInnerRadiusLow)/fPadPitchLength)+1;
420 if ( kMaxRows<fnRowLow) fnRowUp = kMaxRows;
421 if (1>fnRowLow) return kFALSE;
422 // adjust upper sectors pad row positions and pad numbers
423 for (i = 0;i<fnRowUp;i++)
425 Float_t x = fOuterRadiusLow +fPadPitchLength*(Float_t)i;
426 //Float_t y = x*2*tan(alpha_up/2)-kEdgeSectorSpace;
427 Float_t y = (x-0.5*fPadPitchLength)*tan(fOuterAngle/2)-kEdgeSectorSpace
430 fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
433 // adjust lower sectors pad row positions and pad numbers
434 for (i = 0;i<fnRowLow;i++)
436 Float_t x = fInnerRadiusLow +fPadPitchLength*(Float_t)i;
437 // Float_t y = x*2*tan(alpha_low/2)-kEdgeSectorSpace;
438 Float_t y = (x-0.5*fPadPitchLength)*tan(fInnerAngle/2)-kEdgeSectorSpace
441 fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
445 //that variable are not writen to the file there are calculated
447 fWWPitch= fPadPitchLength/Float_t(fnWires);
448 fZWidth = fTSample*fDriftV;
449 fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
456 Bool_t AliTPCParam::GetStatus()
458 //get information about object consistency
462 Int_t AliTPCParam::GetNRowLow() const
464 //get the number of pad rows in low sector
467 Int_t AliTPCParam::GetNRowUp() const
469 //get the number of pad rows in up sector
472 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
474 //get the pad row (irow) radii
475 if ( !(irow<0) && (irow<fnRowLow) )
476 return fPadRowLow[irow];
481 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
483 //get the pad row (irow) radii
484 if ( !(irow<0) && (irow<fnRowUp) )
485 return fPadRowUp[irow];
490 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
492 //get the number of pads in row irow
493 if ( !(irow<0) && (irow<fnRowLow) )
494 return fnPadsLow[irow];
500 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
502 //get the number of pads in row irow
503 if ( !(irow<0) && (irow<fnRowUp) )
504 return fnPadsUp[irow];
510 void AliTPCParam::Streamer(TBuffer &R__b)
512 // Stream an object of class AliTPC.
514 if (R__b.IsReading()) {
515 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
516 TObject::Streamer(R__b);
517 if (R__v < 2) return;
519 R__b >> fInnerRadiusLow;
520 R__b >> fInnerRadiusUp;
521 R__b >> fOuterRadiusLow;
522 R__b >> fOuterRadiusUp;
524 R__b >> fInnerAngleShift;
526 R__b >> fOuterAngleShift;
528 R__b >> fPadPitchLength;
529 R__b >> fPadPitchWidth;
553 R__b.WriteVersion(AliTPCParam::IsA());
554 TObject::Streamer(R__b);
555 R__b << fInnerRadiusLow;
556 R__b << fInnerRadiusUp;
557 R__b << fOuterRadiusLow;
558 R__b << fOuterRadiusUp;
560 R__b << fInnerAngleShift;
562 R__b << fOuterAngleShift;
564 R__b << fPadPitchLength;
565 R__b << fPadPitchWidth;