Correct GetWire check on even/odd fnWires
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.cxx
CommitLineData
4c039060 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/*
17$Log$
ae4cbe70 18Revision 1.4 1999/09/29 09:24:34 fca
19Introduction of the Copyright and cvs Log
20
4c039060 21*/
22
8c555625 23///////////////////////////////////////////////////////////////////////
24// Manager and of geomety classes for set: TPC //
25// //
1283eee5 26// !sectors are numbered from 0 //
27// !pad rows are numbered from 0 //
28//
29// 12.6. changed z relative
8c555625 30// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
31// //
32///////////////////////////////////////////////////////////////////////
33
8c555625 34
35#include <iostream.h>
36#include <TMath.h>
1283eee5 37#include <TObject.h>
8c555625 38#include "AliTPCSecGeo.h"
1283eee5 39#include <AliTPCParam.h>
8c555625 40
41
42ClassImp(AliTPCParam)
43
1283eee5 44const static Int_t kMaxRows=600;
45
46
8c555625 47// default values
1283eee5 48const static Int_t kMaxTBin =512;
8c555625 49
8c555625 50
1283eee5 51const static Float_t kInnerRadiusLow = 89.45;
52const static Float_t kOuterRadiusLow = 143.725;
53const static Float_t kInnerRadiusUp = 134.55;
54const static Float_t kOuterRadiusUp = 248.275;
8c555625 55
1283eee5 56const static Float_t kInnerAngle = 0.523598775; // 30 degrees
57const static Float_t kInnerAngleShift = 0;
58const static Float_t kOuterAngle = 0.261799387; // 15 degrees
59const static Float_t kOuterAngleShift = 0;
8c555625 60
1283eee5 61const static Float_t kPadPitchLength = 2.05;
62const static Float_t kPadPitchWidth = 0.35;
63const static Float_t kPadLength = 2.05;
64const static Float_t kPadWidth = 0.35;
65
66// Number of wires per pad and wire-wire pitch
67const static Int_t knWires = 5;
68const static Float_t kDiffT = 2.2e-2;
69const static Float_t kDiffL = 2.2e-2;
70const static Float_t kDriftV =2.85e6;
8c555625 71
1283eee5 72const static Float_t kOmegaTau = 0.145;
73const static Float_t kAttCoef = 250.;
74const static Float_t kOxyCont = 5.e-6;
8c555625 75
1283eee5 76
77const static Float_t kChipGain = 24;
78const static Float_t kGasGain = 1e4;
79const static Float_t kTSample = 2.e-7; //TSAMPLE
80const static Float_t kTFWHM = 2.5e-7; //fwhm of charge distribution
8c555625 81
1283eee5 82const static Float_t kNoise = 500; //default noise = 1000 el
83const static Int_t kZeroSup=5;
84const static Float_t kPadCoupling=0.5;
8c555625 85//
1283eee5 86const static Float_t kEdgeSectorSpace = 1.15;
87const static Float_t kDegtoRad = 0.01745329251994;
88const static Float_t kRadtoDeg = 57.29577951309;
8c555625 89
90
91
92
93//___________________________________________
94AliTPCParam::AliTPCParam()
95{
96 //constructor set the default parameters
97 SetDefault();
98}
99
100
1283eee5 101void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
102 Float_t outershift, Bool_t inDegree)
103{
104 //
105 // set opening angles
106 fInnerAngle = innerangle; //opening angle of Inner sector
107 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
108 fOuterAngle = outerangle; //opening angle of outer sector
109 fOuterAngleShift = outershift; //shift of first sector center to the 0
110 if (inDegree==kTRUE){
111 fInnerAngle *=kDegtoRad;
112 fInnerAngleShift *=kDegtoRad;
113 fOuterAngle *=kDegtoRad;
114 fOuterAngleShift *=kDegtoRad;
115 }
116}
117
118
8c555625 119void AliTPCParam::CRXYZtoXYZ(Float_t *xyz,
120 const Int_t &sector, const Int_t & padrow, Int_t option) const
121{
122 //transform relative coordinates to absolute
123 Bool_t rel = ( (option&2)!=0);
124 Float_t row_first;
1283eee5 125 row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0];
126 if (rel==kTRUE) //if the position is relative to pad row
8c555625 127 {
128 xyz[0]+=row_first;
129 xyz[0]+=(Int_t) padrow*fPadPitchLength;
130 }
1283eee5 131
132 xyz[2]=z_end-xyz[2];
3c0f9266 133 if (sector<fNInnerSector) {
1283eee5 134 if ( sector>=(fNInnerSector>>1)) xyz[2]*=-1.;
3c0f9266 135 } else {
136 if ( (sector-fNInnerSector) >= (fNOuterSector>>1) ) xyz[2]*=-1;
137 }
138
8c555625 139 Float_t x1=xyz[0];
140 Float_t y1=xyz[1];
141 Float_t cos,sin;
142 AdjustAngles(sector,cos,sin);
1283eee5 143 xyz[0]= x1*cos - y1*sin;
144 xyz[1]= x1*sin + y1*cos;
8c555625 145}
146
147void AliTPCParam::XYZtoCRXYZ(Float_t *xyz,
148 Int_t &sector, Int_t & padrow, Int_t option)
149{
150 //transform global position to the position relative to the sector padrow
151 //if option=0 X calculate absolute calculate sector
152 //if option=1 X absolute use input sector
153 //if option=2 X relative to pad row calculate sector
154 //if option=3 X relative use input sector
155 //!!!!!!!!! WE start to calculate rows from row = 0
156
157 Bool_t rel = ( (option&2)!=0);
158 //option 0 and 2 means that we don't have information about sector
159 //we calculate sector
160 if ((option&1)==0){
161 Float_t angle;
162 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
163 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0;
164 else
165 {
166 angle =TMath::ASin(xyz[1]/r);
167 if (xyz[0]<0) angle=TMath::Pi()-angle;
168 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
169 }
1283eee5 170 //transform global position to the position relative to the sector padrow
171 //fistly calculate xyz[0] radius for lover sector
172 //bacause in this moment we dont know in which sector we are
173 sector=Int_t((angle-fInnerAngleShift)/fInnerAngle);
8c555625 174 Float_t x1;
175 Float_t y1;
176 //firstly we suppose that we are in inner sector
177 Float_t cos,sin;
178 AdjustAngles(sector,cos,sin);
179
180 x1=xyz[0]*cos + xyz[1]*sin;
181 y1=-xyz[0]*sin + xyz[1]*cos;
182 if (x1>fOuterRadiusLow)
183 {
1283eee5 184 sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
8c555625 185 AdjustAngles(sector,cos,sin);
186 x1=xyz[0]*cos + xyz[1]*sin;
187 y1=-xyz[0]*sin + xyz[1]*cos;
1283eee5 188 if (xyz[2]<0) sector+=(fNOuterSector>>1);
8c555625 189 }
190 else
1283eee5 191 if (xyz[2]<0) sector+=(fNInnerSector>>1);
192
8c555625 193 if (x1<fOuterRadiusLow)
194 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+0.5);
195 else
196 padrow = Int_t( (x1-fPadRowUp[0])/fPadPitchLength+0.5);
197 if (rel==kTRUE)
198 if (x1<fOuterRadiusLow) x1-=padrow*fPadPitchLength+fPadRowLow[0];
199 else
200 x1-=padrow*fPadPitchLength+fPadRowUp[0];
201 xyz[0]=x1;
202 xyz[1]=y1;
1283eee5 203 xyz[2]=z_end-TMath::Abs(xyz[2]);
204 } //endif we don't have information about sector
8c555625 205 else{
206 //if we have information about sector
207 Float_t cos,sin;
208 AdjustAngles(sector,cos,sin);
209 Float_t x1;
210 Float_t y1;
211 //rotate to given sector
212 x1=xyz[0]*cos + xyz[1]*sin;
213 y1=-xyz[0]*sin + xyz[1]*cos;
214 //calculate pad row number
1283eee5 215 if (sector<fNInnerSector) {
8c555625 216 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
8c555625 217 }
218 else {
219 padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
8c555625 220 }
221 //if we store relative position calculate position relative to pad row
222 if (rel==kTRUE){
1283eee5 223 if (sector<fNInnerSector)
8c555625 224 x1-=padrow*fPadPitchLength+fPadRowLow[0];
225 else
226 x1-=padrow*fPadPitchLength+fPadRowUp[0];
227 }
228 xyz[0]=x1;
229 xyz[1]=y1;
1283eee5 230 xyz[2]=z_end-TMath::Abs(xyz[2]);
8c555625 231 }
232}
233
234void AliTPCParam::CRYZtoTimePad(const Float_t &y, const Float_t &z,
235 Float_t &time, Float_t &pad,
236 Int_t sector, Int_t padrow)
237{
238 //transform position in cm to position in time slices and pads
1283eee5 239 Float_t nofpads = GetNPads(sector,padrow);
8c555625 240 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
241 pad = y/(fPadPitchWidth)+padc;
1283eee5 242 time=z/fZWidth;
8c555625 243}
244void AliTPCParam::CRTimePadtoYZ(Float_t &y, Float_t &z,
245 const Float_t &time, const Float_t &pad,
246 Int_t sector, Int_t padrow)
247{
248 //transform position in time slices and pads to cm
1283eee5 249 Float_t nofpads = GetNPads(sector,padrow);
8c555625 250 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
251 y=(pad-padc)*fPadPitchWidth;
1283eee5 252 z=time*fZWidth;
8c555625 253}
254
255Int_t AliTPCParam::GetWire(Float_t & x)
256{
257 //
258 //return wire number of pad for electron at relative position x
259 //to the center of the pad
260 //and adjust x to the wire position
261 //we suppose that if the wire number is even the center wire
262 //is at center of pad
263 //
264 Float_t xrel= x/fWWPitch;
ae4cbe70 265 if ((fnWires&1)==0) xrel+=1;
8c555625 266 else xrel+=0.5;
267 Int_t nw=Int_t(xrel);
268 if (xrel<0) nw-=1;
269
270 x=(nw*fWWPitch);
ae4cbe70 271 if ((fnWires&1)==0) x-=fWWPitch/2.;
8c555625 272 return nw;
273}
274
275Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
276{
277 //
278 //give index of the given sector and pad row
279 //no control if the sectors and rows are reasonable !!!
280 //
1283eee5 281 if (sector<fNInnerSector) return sector*fnRowLow+row;
282 return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;
8c555625 283}
284
285Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row)
286{
287 //
288 //return sector and padrow for given index
289 //if index is reasonable return true else return false
290 //
291 if ( (index<0) || (index>fNtRows)) return kFALSE;
1283eee5 292 Int_t outindex = fNInnerSector*fnRowLow;
8c555625 293 if (index<outindex) {
294 sector = index/fnRowLow;
295 row = index - sector*fnRowLow;
8c555625 296 return kTRUE;
297 }
298 index-= outindex;
299 sector = index/fnRowUp;
300 row = index - sector*fnRowUp;
8c555625 301 return kTRUE;
302}
303
304
305
306Int_t AliTPCParam::GetPadRow(Int_t isec, Float_t &x)
307{
308 //
309 //return the pad row for given x (transformed)
310 //
311 Float_t row_first=GetPadRowRadii(isec,0);
312 Int_t row = Int_t(( x-row_first+1.5*fPadPitchLength)/fPadPitchLength)-1;
313 //Int_t will make from -0.5 0 but we want to make -1 so we add and after substract 1
314 x -=row* fPadPitchLength+row_first;
315 if ( (row<0)||(row>=GetNRow(isec))) return -1;
316 else return row;
317}
318
319void AliTPCParam::SetDefault()
320{
321 //set default TPC param
322 fbStatus = kFALSE;
1283eee5 323 //set sector parameters
8c555625 324 fInnerRadiusLow = kInnerRadiusLow;
325 fOuterRadiusLow = kOuterRadiusLow;
326 fInnerRadiusUp = kInnerRadiusUp;
1283eee5 327 fOuterRadiusUp = kOuterRadiusUp;
328 SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift);
8c555625 329 // set default pad size and shape
330 fPadPitchLength = kPadPitchLength;
331 fPadPitchWidth = kPadPitchWidth;
332 fPadLength = kPadLength;
333 fPadWidth = kPadWidth;
334 //
335 fnWires = knWires;
336 fWWPitch= kPadPitchLength/Float_t(knWires);
337 fDiffT = kDiffT;
338 fDiffL = kDiffL;
339 fOmegaTau = kOmegaTau;
340 fOxyCont = kOxyCont;
341 fAttCoef = kAttCoef;
342 fNoise = kNoise;
343 fChipGain = kChipGain;
344 fGasGain = kGasGain;
345 fZeroSup= kZeroSup;
346 fPadCoupling= kPadCoupling;
347 fTSample =kTSample;
348 fTSigma =kTFWHM/2.35;
1283eee5 349 fDriftV=kDriftV;
350 fMaxTBin = kMaxTBin;
8c555625 351 fbStatus = Update();
352}
353
354void AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
355{
1283eee5 356 //
8c555625 357 //set cosinus and sinus of rotation angles for sector isec
1283eee5 358 //
359 cos=fRotAngle[isec*2];
360 sin=fRotAngle[isec*2+1];
8c555625 361}
362
363Bool_t AliTPCParam::Update()
364{
1283eee5 365 //
366 // update some calculated parameter which must be updated after changing "base"
367 // parameters
368 // for example we can change size of pads and according this recalculate number
369 // of pad rows, number of of pads in given row ....
370 //
8c555625 371 fbStatus = kFALSE;
1283eee5 372
373 Int_t i,j; //loop variables because HP
374 //-----------------Sector section------------------------------------------
375 //calclulate number of sectors
376 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); // number of inner sectors - factor 0.2 to don't
377 //be influnced by inprecision
378 if (fNInnerSector%2) return kFALSE;
379 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
380 if (fNOuterSector%2) return kFALSE;
381 fNSector = fNInnerSector+fNOuterSector;
382 //calculate sin and cosine of rotations angle
383 //sectors angles numbering from 0
384 j=fNInnerSector;
385 Float_t angle = fInnerAngleShift;
386 for (i=0; i<fNInnerSector*2; i+=2, j+=2 , angle +=fInnerAngle){
387 fRotAngle[i]=TMath::Cos(angle);
388 fRotAngle[i+1]=TMath::Sin(angle);
389 fRotAngle[j] = fRotAngle[i];
390 fRotAngle[j+1] = fRotAngle[i+1];
391 }
392 angle = fOuterAngleShift;
393 j=(fNInnerSector+fNOuterSector/2)*2;
394 for (i=fNInnerSector*2; i<fNSector*2; i+=2,j+=2, angle +=fOuterAngle){
395 fRotAngle[i]=TMath::Cos(angle);
396 fRotAngle[i+1]=TMath::Sin(angle);
397 fRotAngle[j] = fRotAngle[i];
398 fRotAngle[j+1] = fRotAngle[i+1];
399 }
400
401
402 //----------------PAD section------------------------------------
8c555625 403 //recalculate and check some geometric parameters
404 if (0.001>fPadPitchLength){
405 cout<<"ERROR !!! Small pad pitch length \n"<<flush;
406 return kFALSE;
407 }
8c555625 408 if (fPadPitchLength<fPadLength) {
409 cout<<"ERROR !!! Pitch length smaller then length of pad \n"<<flush;
410 return kFALSE;
411 }
8c555625 412 fnRowUp = Int_t((0.01+fOuterRadiusUp-fOuterRadiusLow)/fPadPitchLength)+1;
413 if ( kMaxRows<fnRowUp) fnRowUp = kMaxRows;
414 if (1>fnRowUp) return kFALSE;
415
416 fnRowLow = Int_t((0.01+fInnerRadiusUp-fInnerRadiusLow)/fPadPitchLength)+1;
417 if ( kMaxRows<fnRowLow) fnRowUp = kMaxRows;
418 if (1>fnRowLow) return kFALSE;
419 // adjust upper sectors pad row positions and pad numbers
420 for (i = 0;i<fnRowUp;i++)
421 {
422 Float_t x = fOuterRadiusLow +fPadPitchLength*(Float_t)i;
1283eee5 423 //Float_t y = x*2*tan(alpha_up/2)-kEdgeSectorSpace;
424 Float_t y = (x-0.5*fPadPitchLength)*tan(fOuterAngle/2)-kEdgeSectorSpace
425 -fPadPitchWidth/2.;
8c555625 426 fPadRowUp[i] = x;
1283eee5 427 fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
428
8c555625 429 }
430 // adjust lower sectors pad row positions and pad numbers
431 for (i = 0;i<fnRowLow;i++)
432 {
433 Float_t x = fInnerRadiusLow +fPadPitchLength*(Float_t)i;
1283eee5 434 // Float_t y = x*2*tan(alpha_low/2)-kEdgeSectorSpace;
435 Float_t y = (x-0.5*fPadPitchLength)*tan(fInnerAngle/2)-kEdgeSectorSpace
436 -fPadPitchWidth/2.;
8c555625 437 fPadRowLow[i] = x;
1283eee5 438 fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
439
8c555625 440 }
441
442 //that variable are not writen to the file there are calculated
443 //
444 fWWPitch= fPadPitchLength/Float_t(fnWires);
445 fZWidth = fTSample*fDriftV;
1283eee5 446 fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
8c555625 447 fbStatus = kTRUE;
448 return kTRUE;
449}
450
451
452
453Bool_t AliTPCParam::GetStatus()
454{
455 //get information about object consistency
456 return fbStatus;
457}
458
459Int_t AliTPCParam::GetNRowLow() const
460{
461 //get the number of pad rows in low sector
462 return fnRowLow;
463}
464Int_t AliTPCParam::GetNRowUp() const
465{
466 //get the number of pad rows in up sector
467 return fnRowUp;
468}
469Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
470{
471 //get the pad row (irow) radii
472 if ( !(irow<0) && (irow<fnRowLow) )
473 return fPadRowLow[irow];
474 else
475 return 0;
476}
477
478Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
479{
480 //get the pad row (irow) radii
481 if ( !(irow<0) && (irow<fnRowUp) )
482 return fPadRowUp[irow];
483 else
484 return 0;
485}
486
487Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
488{
489 //get the number of pads in row irow
490 if ( !(irow<0) && (irow<fnRowLow) )
491 return fnPadsLow[irow];
492 else
493 return 0;
494}
495
496
497Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
498{
499 //get the number of pads in row irow
500 if ( !(irow<0) && (irow<fnRowUp) )
501 return fnPadsUp[irow];
502 else
503 return 0;
504}
505
506
507void AliTPCParam::Streamer(TBuffer &R__b)
508{
509 // Stream an object of class AliTPC.
510
511 if (R__b.IsReading()) {
512 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
513 TObject::Streamer(R__b);
514 if (R__v < 2) return;
1283eee5 515 //sector parameters
8c555625 516 R__b >> fInnerRadiusLow;
517 R__b >> fInnerRadiusUp;
518 R__b >> fOuterRadiusLow;
519 R__b >> fOuterRadiusUp;
1283eee5 520 R__b >> fInnerAngle;
521 R__b >> fInnerAngleShift;
522 R__b >> fOuterAngle;
523 R__b >> fOuterAngleShift;
524 //pad parameters
8c555625 525 R__b >> fPadPitchLength;
526 R__b >> fPadPitchWidth;
527 R__b >> fPadLength;
528 R__b >> fPadWidth;
529
530 R__b >> fnWires;
1283eee5 531 //gas parameters
8c555625 532 R__b >>fDiffT;
533 R__b >>fDiffL;
534 R__b >>fGasGain;
535 R__b >>fDriftV;
536 R__b >>fOmegaTau;
537 R__b >>fOxyCont;
538 R__b >>fAttCoef;
539
8c555625 540 R__b >>fPadCoupling;
541 R__b >>fZeroSup;
542 R__b >>fNoise;
543 R__b >>fChipGain;
544
545 R__b >>fTSample;
546 R__b >>fTSigma;
547 //
8c555625 548 Update();
549 } else {
550 R__b.WriteVersion(AliTPCParam::IsA());
551 TObject::Streamer(R__b);
552 R__b << fInnerRadiusLow;
553 R__b << fInnerRadiusUp;
554 R__b << fOuterRadiusLow;
555 R__b << fOuterRadiusUp;
1283eee5 556 R__b << fInnerAngle;
557 R__b << fInnerAngleShift;
558 R__b << fOuterAngle;
559 R__b << fOuterAngleShift;
8c555625 560
561 R__b << fPadPitchLength;
562 R__b << fPadPitchWidth;
563 R__b << fPadLength;
564 R__b << fPadWidth;
565
566 R__b << fnWires;
567
568 R__b <<fDiffT;
569 R__b <<fDiffL;
570 R__b <<fGasGain;
571 R__b <<fDriftV;
572 R__b <<fOmegaTau;
573 R__b <<fOxyCont;
574 R__b <<fAttCoef;
575
576
577 R__b <<fPadCoupling;
578 R__b <<fZeroSup;
579 R__b <<fNoise;
580 R__b <<fChipGain;
581
582 R__b <<fTSample;
583 R__b <<fTSigma;
584 }
585}
586