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.17 2002/10/23 07:17:33 alibrary
19 Introducing Riostream.h
21 Revision 1.16 2002/10/14 14:57:42 hristov
22 Merging the VirtualMC branch to the main development branch (HEAD)
24 Revision 1.13.4.1 2002/06/10 15:26:11 hristov
27 Revision 1.15 2002/05/07 17:24:02 kowal2
28 Updated wires positions
30 Revision 1.14 2002/03/29 06:57:45 kowal2
31 Restored backward compatibility to use the hits from Dec. 2000 production.
33 Revision 1.13 2002/03/18 17:59:13 kowal2
34 Chnges in the pad geometry - 3 pad lengths introduced.
36 Revision 1.12 2002/02/05 09:12:26 hristov
37 Small mods for gcc 3.02
39 Revision 1.11 2000/11/02 07:33:48 kowal2
40 Automatic streamer generation.
42 Revision 1.10 2000/07/10 20:57:39 hristov
43 Update of TPC code and macros by M.Kowalski
45 Revision 1.9 2000/06/30 12:07:50 kowal2
46 Updated from the TPC-PreRelease branch
48 Revision 1.8.4.4 2000/06/26 07:39:42 kowal2
49 Changes to obey the coding rules
51 Revision 1.8.4.3 2000/06/25 08:38:41 kowal2
52 Splitted from AliTPCtracking
54 Revision 1.8.4.2 2000/06/14 16:48:24 kowal2
55 Parameter setting improved. Removed compiler warnings
57 Revision 1.8.4.1 2000/06/09 07:12:21 kowal2
61 Revision 1.8 2000/04/17 09:37:33 kowal2
62 removed obsolete AliTPCDigitsDisplay.C
64 Revision 1.7.8.2 2000/04/10 08:44:51 kowal2
66 New transformations added
67 Different pad and pad-rows geometries for different sectors
69 Revision 1.7.8.1 2000/04/10 07:56:53 kowal2
70 Not used anymore - removed
72 Revision 1.7 1999/10/08 13:10:35 fca
73 Values in SetDefault are in radiants
75 Revision 1.6 1999/10/08 06:27:59 fca
78 Revision 1.5 1999/10/05 17:18:27 fca
79 Correct GetWire check on even/odd fnWires
81 Revision 1.4 1999/09/29 09:24:34 fca
82 Introduction of the Copyright and cvs Log
86 ///////////////////////////////////////////////////////////////////////
87 // Manager and of geomety classes for set: TPC //
89 // !sectors are numbered from 0 //
90 // !pad rows are numbered from 0 //
92 // 12.6. changed z relative
93 // Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
95 ///////////////////////////////////////////////////////////////////////
99 #include <Riostream.h>
103 #include <AliTPCParam.h>
108 ClassImp(AliTPCParam)
111 //___________________________________________
112 AliTPCParam::AliTPCParam()
115 //constructor sets the default parameters
121 SetTitle("75x40_100x60_150x60");
125 AliTPCParam::~AliTPCParam()
128 //destructor deletes some dynamicaly alocated variables
131 if (fResponseBin!=0) delete [] fResponseBin;
132 if (fResponseWeight!=0) delete [] fResponseWeight;
133 if (fRotAngle !=0) delete [] fRotAngle;
140 Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const
143 // calculates sector number (index[1], undefined on input)
149 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
150 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
153 angle =TMath::ASin(xyz[1]/r);
154 if (xyz[0]<0) angle=TMath::Pi()-angle;
155 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
158 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
161 AdjustCosSin(sector,cos,sin);
162 x1=xyz[0]*cos + xyz[1]*sin;
164 if (x1>fOuterRadiusLow)
166 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
167 if (xyz[2]<0) sector+=(fNOuterSector>>1);
170 if (xyz[2]<0) sector+=(fNInnerSector>>1);
171 index[1]=sector; // calculated sector number
172 index[0]=1; // indicates system after transformation
176 Bool_t AliTPCParam::Transform(Float_t *xyz, Int_t *index, Int_t* oindex)
178 //transformation from input coodination system to output coordination system
188 Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const
191 //calculates pad row of point xyz - transformation to system 8 (digit system)
193 Int_t system = index[0];
195 Transform0to1(xyz,index);
199 Transform1to2(xyz,index);
203 if (fGeometryType==0){ //straight row
205 Transform2to3(xyz,index);
209 Transform3to4(xyz,index);
213 Transform4to8(xyz,index);
222 if (fGeometryType==1){ //cylindrical geometry
224 Transform2to5(xyz,index);
228 Transform2to3(xyz,index);
232 Transform3to4(xyz,index);
241 return -1; //if no reasonable system
244 void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
248 // set opening angles
249 const static Float_t kDegtoRad = 0.01745329251994;
250 fInnerAngle = innerangle; //opening angle of Inner sector
251 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
252 fOuterAngle = outerangle; //opening angle of outer sector
253 fOuterAngleShift = outershift; //shift of first sector center to the 0
254 fInnerAngle *=kDegtoRad;
255 fInnerAngleShift *=kDegtoRad;
256 fOuterAngle *=kDegtoRad;
257 fOuterAngleShift *=kDegtoRad;
260 Float_t AliTPCParam::GetInnerAngle() const
267 Float_t AliTPCParam::GetInnerAngleShift() const
270 return fInnerAngleShift;
272 Float_t AliTPCParam::GetOuterAngle() const
277 Float_t AliTPCParam::GetOuterAngleShift() const
281 return fOuterAngleShift;
285 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
288 //give index of the given sector and pad row
289 //no control if the sectors and rows are reasonable !!!
291 if (sector<fNInnerSector) return sector*fNRowLow+row;
292 return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;
295 Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
298 //return sector and padrow for given index
299 //if index is reasonable returns true else return false
301 if ( (index<0) || (index>fNtRows)) return kFALSE;
302 Int_t outindex = fNInnerSector*fNRowLow;
303 if (index<outindex) {
304 sector = index/fNRowLow;
305 row = index - sector*fNRowLow;
309 sector = index/fNRowUp;
310 row = index - sector*fNRowUp;
311 sector += fNInnerSector;
315 void AliTPCParam::SetDefault()
318 //set default parameters
320 //const static Int_t kMaxRows=600;
322 //sector default parameters
324 const static Float_t kInnerRadiusLow = 82.97;
325 const static Float_t kInnerRadiusUp = 133.17;
326 const static Float_t kOuterRadiusLow = 133.58;
327 const static Float_t kOuterRadiusUp = 247.78;
328 const static Float_t kInnerAngle = 20; // 20 degrees
329 const static Float_t kInnerAngleShift = 10;
330 const static Float_t kOuterAngle = 20; // 20 degrees
331 const static Float_t kOuterAngleShift = 10;
332 const static Float_t kInnerFrameSpace = 1.5;
333 const static Float_t kOuterFrameSpace = 1.5;
334 const static Float_t kInnerWireMount = 1.370825926;
335 const static Float_t kOuterWireMount = 1.370825926;
336 const static Float_t kZLength =250.;
337 const static Int_t kGeometryType = 0; //straight rows
338 const static Int_t kNRowLow = 63;
339 const static Int_t kNRowUp1 = 64;
340 const static Int_t kNRowUp2 = 32;
341 const static Int_t kNRowUp = 96;
343 //wires default parameters
345 const static Int_t kNInnerWiresPerPad = 3;
346 const static Int_t kInnerDummyWire = 2;
347 const static Float_t kInnerWWPitch = 0.25;
348 const static Float_t kRInnerFirstWire = 84.445;
349 const static Float_t kRInnerLastWire = 132.445;
350 const static Float_t kInnerOffWire = 0.5;
351 const static Int_t kNOuter1WiresPerPad = 4;
352 const static Int_t kNOuter2WiresPerPad = 6;
353 const static Float_t kOuterWWPitch = 0.25;
354 const static Float_t kROuterFirstWire = 134.305;
355 const static Float_t kROuterLastWire = 247.055;
356 const static Int_t kOuterDummyWire = 2;
357 const static Float_t kOuterOffWire = 0.5;
359 //pad default parameters
361 const static Float_t kInnerPadPitchLength = 0.75;
362 const static Float_t kInnerPadPitchWidth = 0.40;
363 const static Float_t kInnerPadLength = 0.75;
364 const static Float_t kInnerPadWidth = 0.40;
365 const static Float_t kOuter1PadPitchLength = 1.0;
366 const static Float_t kOuterPadPitchWidth = 0.6;
367 const static Float_t kOuter1PadLength = 1.0;
368 const static Float_t kOuterPadWidth = 0.6;
369 const static Float_t kOuter2PadPitchLength = 1.5;
370 const static Float_t kOuter2PadLength = 1.5;
372 const static Bool_t kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM
373 const static Int_t kNCrossRows = 1; //number of rows to cross-talk
376 //gas default parameters
378 const static Float_t kDiffT = 2.2e-2;
379 const static Float_t kDiffL = 2.2e-2;
380 const static Float_t kGasGain = 2.e4;
381 const static Float_t kDriftV =2.83e6;
382 const static Float_t kOmegaTau = 0.145;
383 const static Float_t kAttCoef = 250.;
384 const static Float_t kOxyCont = 5.e-6;
386 //electronic default parameters
388 const static Float_t kPadCoupling=0.5;
389 const static Int_t kZeroSup=2;
390 const static Float_t kNoise = 1000;
391 const static Float_t kChipGain = 12;
392 const static Float_t kChipNorm = 0.4;
393 const static Float_t kTSample = 2.e-7;
394 const static Float_t kTFWHM = 1.9e-7; //fwhm of charge distribution
395 const static Int_t kMaxTBin =445;
396 const static Int_t kADCSat =1024;
397 const static Float_t kADCDynRange =2000.;
401 const static Float_t kBField =0.2;
402 const static Float_t kNPrimLoss =10.9;
403 const static Float_t kNTotalLoss =39.9;
407 const static Int_t kNResponseMax=100;
408 const static Float_t kResponseThreshold=0.01;
411 //set sector parameters
413 SetInnerRadiusLow(kInnerRadiusLow);
414 SetOuterRadiusLow(kOuterRadiusLow);
415 SetInnerRadiusUp(kInnerRadiusUp);
416 SetOuterRadiusUp(kOuterRadiusUp);
417 SetInnerFrameSpace(kInnerFrameSpace);
418 SetOuterFrameSpace(kOuterFrameSpace);
419 SetInnerWireMount(kInnerWireMount);
420 SetOuterWireMount(kOuterWireMount);
421 SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
422 SetZLength(kZLength);
423 SetGeometryType(kGeometryType);
424 SetRowNLow(kNRowLow);
425 SetRowNUp1 (kNRowUp1);
426 SetRowNUp2(kNRowUp2);
429 //set wire parameters
431 SetInnerNWires(kNInnerWiresPerPad);
432 SetInnerDummyWire(kInnerDummyWire);
433 SetInnerOffWire(kInnerOffWire);
434 SetOuter1NWires(kNOuter1WiresPerPad);
435 SetOuter2NWire(kNOuter2WiresPerPad);
436 SetOuterDummyWire(kOuterDummyWire);
437 SetOuterOffWire(kOuterOffWire);
438 SetInnerWWPitch(kInnerWWPitch);
439 SetRInnerFirstWire(kRInnerFirstWire);
440 SetRInnerLastWire(kRInnerLastWire);
441 SetOuterWWPitch(kOuterWWPitch);
442 SetROuterFirstWire(kROuterFirstWire);
443 SetROuterLastWire(kROuterLastWire);
447 SetInnerPadPitchLength(kInnerPadPitchLength);
448 SetInnerPadPitchWidth(kInnerPadPitchWidth);
449 SetInnerPadLength(kInnerPadLength);
450 SetInnerPadWidth(kInnerPadWidth);
451 SetOuter1PadPitchLength(kOuter1PadPitchLength);
452 SetOuter2PadPitchLength(kOuter2PadPitchLength);
453 SetOuterPadPitchWidth(kOuterPadPitchWidth);
454 SetOuter1PadLength(kOuter1PadLength);
455 SetOuter2PadLength(kOuter2PadLength);
456 SetOuterPadWidth(kOuterPadWidth);
457 SetMWPCReadout(kBMWPCReadout);
458 SetNCrossRows(kNCrossRows);
464 SetGasGain(kGasGain);
466 SetOmegaTau(kOmegaTau);
467 SetAttCoef(kAttCoef);
468 SetOxyCont(kOxyCont);
470 //set electronivc parameters
472 SetPadCoupling(kPadCoupling);
473 SetZeroSup(kZeroSup);
475 SetChipGain(kChipGain);
476 SetChipNorm(kChipNorm);
477 SetTSample(kTSample);
479 SetMaxTBin(kMaxTBin);
481 SetADCDynRange(kADCDynRange);
484 SetNPrimLoss(kNPrimLoss);
485 SetNTotalLoss(kNTotalLoss);
487 //set response parameters
489 SetNResponseMax(kNResponseMax);
490 SetResponseThreshold(static_cast<int>(kResponseThreshold));
494 Bool_t AliTPCParam::Update()
497 // update some calculated parameter which must be updated after changing "base"
499 // for example we can change size of pads and according this recalculate number
500 // of pad rows, number of of pads in given row ....
502 const Float_t kQel = 1.602e-19; // elementary charge
505 Int_t i,j; //loop variables because HP
506 //-----------------Sector section------------------------------------------
507 //calclulate number of sectors
508 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2);
509 // number of inner sectors - factor 0.2 to don't be influnced by inprecision
510 if (fNInnerSector%2) return kFALSE;
511 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
512 if (fNOuterSector%2) return kFALSE;
513 fNSector = fNInnerSector+fNOuterSector;
515 if (fRotAngle!=0) delete [] fRotAngle;
516 fRotAngle = new Float_t[4*fNSector];
517 //calculate sin and cosine of rotations angle
518 //sectors angles numbering from 0
521 Float_t angle = fInnerAngleShift;
522 for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
523 fRotAngle[i]=TMath::Cos(angle);
524 fRotAngle[i+1]=TMath::Sin(angle);
525 fRotAngle[j] = fRotAngle[i];
526 fRotAngle[j+1] = fRotAngle[i+1];
527 fRotAngle[i+2] =angle;
528 fRotAngle[j+2] =angle;
530 angle = fOuterAngleShift;
531 j=(fNInnerSector+fNOuterSector/2)*4;
532 for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
533 fRotAngle[i]=TMath::Cos(angle);
534 fRotAngle[i+1]=TMath::Sin(angle);
535 fRotAngle[j] = fRotAngle[i];
536 fRotAngle[j+1] = fRotAngle[i+1];
537 fRotAngle[i+2] =angle;
538 fRotAngle[j+2] =angle;
540 fZWidth = fTSample*fDriftV;
541 fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
542 fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
545 Float_t wspace; //available space for wire
546 Float_t dummyspace; //dummyspace for wire
548 wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
549 nwire = Int_t(wspace/fInnerWWPitch);
550 wspace = Float_t(nwire)*fInnerWWPitch;
551 dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;
552 wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
553 nwire = Int_t(wspace/fOuterWWPitch);
554 wspace = Float_t(nwire)*fOuterWWPitch;
555 dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.;
556 fROuterFirstWire = fOuterRadiusLow+dummyspace;
557 fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
563 if (fResponseBin==0) delete [] fResponseBin;
564 if (fResponseWeight==0) delete [] fResponseBin;
565 fResponseBin = new Int_t[3*fNResponseMax];
566 fResponseWeight = new Float_t[fNResponseMax];
574 Bool_t AliTPCParam::GetStatus()
576 //get information about object consistency
580 Int_t AliTPCParam::GetNRowLow() const
582 //get the number of pad rows in low sector
585 Int_t AliTPCParam::GetNRowUp() const
587 //get the number of pad rows in up sector
590 Int_t AliTPCParam::GetNRowUp1() const
592 //get the number of pad rows in up1 sector
595 Int_t AliTPCParam::GetNRowUp2() const
597 //get the number of pad rows in up2 sector
600 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
602 //get the pad row (irow) radii
603 if ( !(irow<0) && (irow<fNRowLow) )
604 return fPadRowLow[irow];
609 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
611 //get the pad row (irow) radii
612 if ( !(irow<0) && (irow<fNRowUp) )
613 return fPadRowUp[irow];
618 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
620 //get the number of pads in row irow
621 if ( !(irow<0) && (irow<fNRowLow) )
622 return fNPadsLow[irow];
628 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
630 //get the number of pads in row irow
631 if ( !(irow<0) && (irow<fNRowUp) )
632 return fNPadsUp[irow];
636 Float_t AliTPCParam::GetYInner(Int_t irow) const
638 return fYInner[irow];
642 Float_t AliTPCParam::GetYOuter(Int_t irow) const
644 return fYOuter[irow];