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 ///////////////////////////////////////////////////////////////////////
19 // Manager and of geomety classes for set: TPC //
21 // !sectors are numbered from 0 //
22 // !pad rows are numbered from 0 //
24 // 12.6. changed z relative
25 // Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
27 ///////////////////////////////////////////////////////////////////////
31 #include <AliTPCParam.h>
33 #include <TGeoManager.h>
34 #include <TGeoPhysicalNode.h>
35 #include "AliAlignObj.h"
36 #include "AliAlignObjAngles.h"
42 //___________________________________________
43 AliTPCParam::AliTPCParam()
46 //constructor sets the default parameters
52 // fChamberPos = fChamberRot = 0;
53 fTrackingMatrix = fClusterMatrix = fGlobalMatrix = 0;
54 SetTitle("75x40_100x60_150x60");
58 AliTPCParam::~AliTPCParam()
61 //destructor deletes some dynamicaly alocated variables
64 if (fResponseBin!=0) delete [] fResponseBin;
65 if (fResponseWeight!=0) delete [] fResponseWeight;
66 if (fRotAngle !=0) delete [] fRotAngle;
67 // if (fChamberPos !=0) delete [] fChamberPos;
68 // if (fChamberRot !=0) delete [] fChamberRot;
70 // if (fTrackingMatrix!=0) {
71 // for(Int_t i=0;i<fNSector;i++)
72 // delete fTrackingMatrix[i];
73 // delete [] fTrackingMatrix;
75 // if (fClusterMatrix!=0) {
76 // for(Int_t i=0;i<fNSector;i++)
77 // delete fClusterMatrix[i];
78 // delete [] fClusterMatrix;
80 // if (fGlobalMatrix!=0) {
81 // for(Int_t i=0;i<fNSector;i++)
82 // delete fGlobalMatrix[i];
83 // delete [] fGlobalMatrix;
90 Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const
93 // calculates sector number (index[1], undefined on input)
99 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
100 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
103 angle =TMath::ASin(xyz[1]/r);
104 if (xyz[0]<0) angle=TMath::Pi()-angle;
105 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
108 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
111 AdjustCosSin(sector,cos,sin);
112 x1=xyz[0]*cos + xyz[1]*sin;
114 if (x1>fOuterRadiusLow)
116 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
117 if (xyz[2]<0) sector+=(fNOuterSector>>1);
120 if (xyz[2]<0) sector+=(fNInnerSector>>1);
121 index[1]=sector; // calculated sector number
122 index[0]=1; // indicates system after transformation
126 Bool_t AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
128 //transformation from input coodination system to output coordination system
138 Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const
141 //calculates pad row of point xyz - transformation to system 8 (digit system)
143 Int_t system = index[0];
145 Transform0to1(xyz,index);
149 Transform1to2(xyz,index);
153 if (fGeometryType==0){ //straight row
155 Transform2to3(xyz,index);
159 Transform3to4(xyz,index);
163 Transform4to8(xyz,index);
172 if (fGeometryType==1){ //cylindrical geometry
174 Transform2to5(xyz,index);
178 Transform2to3(xyz,index);
182 Transform3to4(xyz,index);
191 return -1; //if no reasonable system
194 void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
198 // set opening angles
199 static const Float_t kDegtoRad = 0.01745329251994;
200 fInnerAngle = innerangle; //opening angle of Inner sector
201 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
202 fOuterAngle = outerangle; //opening angle of outer sector
203 fOuterAngleShift = outershift; //shift of first sector center to the 0
204 fInnerAngle *=kDegtoRad;
205 fInnerAngleShift *=kDegtoRad;
206 fOuterAngle *=kDegtoRad;
207 fOuterAngleShift *=kDegtoRad;
210 Float_t AliTPCParam::GetInnerAngle() const
217 Float_t AliTPCParam::GetInnerAngleShift() const
220 return fInnerAngleShift;
222 Float_t AliTPCParam::GetOuterAngle() const
227 Float_t AliTPCParam::GetOuterAngleShift() const
231 return fOuterAngleShift;
235 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
238 //give index of the given sector and pad row
239 //no control if the sectors and rows are reasonable !!!
241 if (sector<fNInnerSector) return sector*fNRowLow+row;
242 return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;
245 Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
248 //return sector and padrow for given index
249 //if index is reasonable returns true else return false
251 if ( (index<0) || (index>fNtRows)) return kFALSE;
252 Int_t outindex = fNInnerSector*fNRowLow;
253 if (index<outindex) {
254 sector = index/fNRowLow;
255 row = index - sector*fNRowLow;
259 sector = index/fNRowUp;
260 row = index - sector*fNRowUp;
261 sector += fNInnerSector;
265 void AliTPCParam::SetDefault()
268 //set default parameters
270 //const static Int_t kMaxRows=600;
272 //sector default parameters
274 static const Float_t kInnerRadiusLow = 83.65;
275 static const Float_t kInnerRadiusUp = 133.3;
276 static const Float_t kOuterRadiusLow = 133.5;
277 static const Float_t kOuterRadiusUp = 247.7;
278 static const Float_t kInnerAngle = 20; // 20 degrees
279 static const Float_t kInnerAngleShift = 10;
280 static const Float_t kOuterAngle = 20; // 20 degrees
281 static const Float_t kOuterAngleShift = 10;
282 static const Float_t kInnerFrameSpace = 1.5;
283 static const Float_t kOuterFrameSpace = 1.5;
284 static const Float_t kInnerWireMount = 1.2;
285 static const Float_t kOuterWireMount = 1.4;
286 static const Float_t kZLength =250.;
287 static const Int_t kGeometryType = 0; //straight rows
288 static const Int_t kNRowLow = 63;
289 static const Int_t kNRowUp1 = 64;
290 static const Int_t kNRowUp2 = 32;
291 static const Int_t kNRowUp = 96;
293 //wires default parameters
295 static const Int_t kNInnerWiresPerPad = 3;
296 static const Int_t kInnerDummyWire = 2;
297 static const Float_t kInnerWWPitch = 0.25;
298 static const Float_t kRInnerFirstWire = 84.475;
299 static const Float_t kRInnerLastWire = 132.475;
300 static const Float_t kInnerOffWire = 0.5;
301 static const Int_t kNOuter1WiresPerPad = 4;
302 static const Int_t kNOuter2WiresPerPad = 6;
303 static const Float_t kOuterWWPitch = 0.25;
304 static const Float_t kROuterFirstWire = 134.225;
305 static const Float_t kROuterLastWire = 246.975;
306 static const Int_t kOuterDummyWire = 2;
307 static const Float_t kOuterOffWire = 0.5;
309 //pad default parameters
311 static const Float_t kInnerPadPitchLength = 0.75;
312 static const Float_t kInnerPadPitchWidth = 0.40;
313 static const Float_t kInnerPadLength = 0.75;
314 static const Float_t kInnerPadWidth = 0.40;
315 static const Float_t kOuter1PadPitchLength = 1.0;
316 static const Float_t kOuterPadPitchWidth = 0.6;
317 static const Float_t kOuter1PadLength = 1.0;
318 static const Float_t kOuterPadWidth = 0.6;
319 static const Float_t kOuter2PadPitchLength = 1.5;
320 static const Float_t kOuter2PadLength = 1.5;
322 static const Bool_t kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM
323 static const Int_t kNCrossRows = 1; //number of rows to cross-talk
326 //gas default parameters
328 static const Float_t kDiffT = 2.2e-2;
329 static const Float_t kDiffL = 2.2e-2;
330 static const Float_t kGasGain = 2.e4;
331 static const Float_t kDriftV =2.83e6;
332 static const Float_t kOmegaTau = 0.145;
333 static const Float_t kAttCoef = 250.;
334 static const Float_t kOxyCont = 5.e-6;
336 //electronic default parameters
338 static const Float_t kPadCoupling=0.5;
339 static const Int_t kZeroSup=2;
340 static const Float_t kNoise = 1000;
341 static const Float_t kChipGain = 12;
342 static const Float_t kChipNorm = 0.4;
343 static const Float_t kTSample = 2.e-7;
344 static const Float_t kTFWHM = 1.9e-7; //fwhm of charge distribution
345 static const Int_t kMaxTBin =445;
346 static const Int_t kADCSat =1024;
347 static const Float_t kADCDynRange =2000.;
351 static const Int_t kNResponseMax=100;
352 static const Float_t kResponseThreshold=0.01;
354 static const Float_t kGateDelay=6.1e-6; //In s
355 static const Float_t kL1Delay=6.5e-6; //In s
356 static const UShort_t kNTBinsBeforeL1=14;
359 //set sector parameters
361 SetInnerRadiusLow(kInnerRadiusLow);
362 SetOuterRadiusLow(kOuterRadiusLow);
363 SetInnerRadiusUp(kInnerRadiusUp);
364 SetOuterRadiusUp(kOuterRadiusUp);
365 SetInnerFrameSpace(kInnerFrameSpace);
366 SetOuterFrameSpace(kOuterFrameSpace);
367 SetInnerWireMount(kInnerWireMount);
368 SetOuterWireMount(kOuterWireMount);
369 SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
370 SetZLength(kZLength);
371 SetGeometryType(kGeometryType);
372 SetRowNLow(kNRowLow);
373 SetRowNUp1 (kNRowUp1);
374 SetRowNUp2(kNRowUp2);
377 //set wire parameters
379 SetInnerNWires(kNInnerWiresPerPad);
380 SetInnerDummyWire(kInnerDummyWire);
381 SetInnerOffWire(kInnerOffWire);
382 SetOuter1NWires(kNOuter1WiresPerPad);
383 SetOuter2NWire(kNOuter2WiresPerPad);
384 SetOuterDummyWire(kOuterDummyWire);
385 SetOuterOffWire(kOuterOffWire);
386 SetInnerWWPitch(kInnerWWPitch);
387 SetRInnerFirstWire(kRInnerFirstWire);
388 SetRInnerLastWire(kRInnerLastWire);
389 SetOuterWWPitch(kOuterWWPitch);
390 SetROuterFirstWire(kROuterFirstWire);
391 SetROuterLastWire(kROuterLastWire);
395 SetInnerPadPitchLength(kInnerPadPitchLength);
396 SetInnerPadPitchWidth(kInnerPadPitchWidth);
397 SetInnerPadLength(kInnerPadLength);
398 SetInnerPadWidth(kInnerPadWidth);
399 SetOuter1PadPitchLength(kOuter1PadPitchLength);
400 SetOuter2PadPitchLength(kOuter2PadPitchLength);
401 SetOuterPadPitchWidth(kOuterPadPitchWidth);
402 SetOuter1PadLength(kOuter1PadLength);
403 SetOuter2PadLength(kOuter2PadLength);
404 SetOuterPadWidth(kOuterPadWidth);
405 SetMWPCReadout(kBMWPCReadout);
406 SetNCrossRows(kNCrossRows);
412 SetGasGain(kGasGain);
414 SetOmegaTau(kOmegaTau);
415 SetAttCoef(kAttCoef);
416 SetOxyCont(kOxyCont);
418 //set electronivc parameters
420 SetPadCoupling(kPadCoupling);
421 SetZeroSup(kZeroSup);
423 SetChipGain(kChipGain);
424 SetChipNorm(kChipNorm);
425 SetTSample(kTSample);
427 SetMaxTBin(kMaxTBin);
429 SetADCDynRange(kADCDynRange);
430 // //set magnetic field
431 // SetBField(kBField);
432 // SetNPrimLoss(kNPrimLoss);
433 // SetNTotalLoss(kNTotalLoss);
435 //set response parameters
437 SetNResponseMax(kNResponseMax);
438 SetResponseThreshold(static_cast<int>(kResponseThreshold));
440 SetGateDelay(kGateDelay);
441 SetL1Delay(kL1Delay);
442 SetNTBinsBeforeL1(kNTBinsBeforeL1);
446 Bool_t AliTPCParam::Update()
449 // update some calculated parameter which must be updated after changing "base"
451 // for example we can change size of pads and according this recalculate number
452 // of pad rows, number of of pads in given row ....
454 const Float_t kQel = 1.602e-19; // elementary charge
457 Int_t i,j; //loop variables because HP
458 //-----------------Sector section------------------------------------------
459 //calclulate number of sectors
460 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2);
461 // number of inner sectors - factor 0.2 to don't be influnced by inprecision
462 if (fNInnerSector%2) return kFALSE;
463 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
464 if (fNOuterSector%2) return kFALSE;
465 fNSector = fNInnerSector+fNOuterSector;
467 if (fRotAngle!=0) delete [] fRotAngle;
468 fRotAngle = new Float_t[4*fNSector];
469 //calculate sin and cosine of rotations angle
470 //sectors angles numbering from 0
473 Float_t angle = fInnerAngleShift;
474 for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
475 fRotAngle[i]=TMath::Cos(angle);
476 fRotAngle[i+1]=TMath::Sin(angle);
477 fRotAngle[j] = fRotAngle[i];
478 fRotAngle[j+1] = fRotAngle[i+1];
479 fRotAngle[i+2] =angle;
480 fRotAngle[j+2] =angle;
482 angle = fOuterAngleShift;
483 j=(fNInnerSector+fNOuterSector/2)*4;
484 for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
485 fRotAngle[i]=TMath::Cos(angle);
486 fRotAngle[i+1]=TMath::Sin(angle);
487 fRotAngle[j] = fRotAngle[i];
488 fRotAngle[j+1] = fRotAngle[i+1];
489 fRotAngle[i+2] =angle;
490 fRotAngle[j+2] =angle;
493 fZWidth = fTSample*fDriftV;
494 fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
495 fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
498 Float_t wspace; //available space for wire
499 Float_t dummyspace; //dummyspace for wire
501 wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
502 nwire = Int_t(wspace/fInnerWWPitch);
503 wspace = Float_t(nwire)*fInnerWWPitch;
504 dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;
505 wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
506 nwire = Int_t(wspace/fOuterWWPitch);
507 wspace = Float_t(nwire)*fOuterWWPitch;
508 dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.;
509 fROuterFirstWire = fOuterRadiusLow+dummyspace;
510 fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
516 if (fResponseBin==0) delete [] fResponseBin;
517 if (fResponseWeight==0) delete [] fResponseBin;
518 fResponseBin = new Int_t[3*fNResponseMax];
519 fResponseWeight = new Float_t[fNResponseMax];
522 fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
529 Bool_t AliTPCParam::ReadGeoMatrices(){
534 AliFatal("Geo manager not initialized\n");
538 if (fTrackingMatrix) delete [] fTrackingMatrix;
539 fTrackingMatrix = new TGeoHMatrix*[fNSector];
540 if (fClusterMatrix) delete [] fClusterMatrix;
541 fClusterMatrix = new TGeoHMatrix*[fNSector];
542 if (fGlobalMatrix) delete [] fGlobalMatrix;
543 fGlobalMatrix = new TGeoHMatrix*[fNSector];
545 for (Int_t isec=0; isec<fNSector; isec++) {
546 fGlobalMatrix[isec] = 0;
547 AliAlignObj::ELayerID iLayer;
550 if(isec<fNInnerSector) {
551 iLayer = AliAlignObj::kTPC1;
555 iLayer = AliAlignObj::kTPC2;
556 iModule = isec - fNInnerSector;
559 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
560 const char *path = AliAlignObj::GetVolPath(volid);
561 gGeoManager->cd(path);
562 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
564 TGeoRotation mchange;
565 mchange.RotateY(90); mchange.RotateX(90);
566 Float_t x0 = GetChamberCenter(isec);
567 TGeoTranslation center("center",-x0,0,0);
568 // Convert to global coordinate system
569 //m->Multiply(¢er);
570 fGlobalMatrix[isec] = new TGeoHMatrix(*m);
571 fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
577 Bool_t AliTPCParam::GetStatus() const
579 //get information about object consistency
583 Int_t AliTPCParam::GetNRowLow() const
585 //get the number of pad rows in low sector
588 Int_t AliTPCParam::GetNRowUp() const
590 //get the number of pad rows in up sector
593 Int_t AliTPCParam::GetNRowUp1() const
595 //get the number of pad rows in up1 sector
598 Int_t AliTPCParam::GetNRowUp2() const
600 //get the number of pad rows in up2 sector
603 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
605 //get the pad row (irow) radii
606 if ( !(irow<0) && (irow<fNRowLow) )
607 return fPadRowLow[irow];
612 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
614 //get the pad row (irow) radii
615 if ( !(irow<0) && (irow<fNRowUp) )
616 return fPadRowUp[irow];
621 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
623 //get the number of pads in row irow
624 if ( !(irow<0) && (irow<fNRowLow) )
625 return fNPadsLow[irow];
631 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
633 //get the number of pads in row irow
634 if ( !(irow<0) && (irow<fNRowUp) )
635 return fNPadsUp[irow];
639 Float_t AliTPCParam::GetYInner(Int_t irow) const
641 return fYInner[irow];
645 Float_t AliTPCParam::GetYOuter(Int_t irow) const
647 return fYOuter[irow];
650 Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
652 // returns the sector index
653 // takes as input the angle, index of the pad row and z position
656 if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
657 if (angle < 0. ) angle += 2.*TMath::Pi();
661 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
662 if (z<0) sector += (fNInnerSector>>1);
665 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
666 if (z<0) sector += (fNOuterSector>>1);
672 Float_t AliTPCParam::GetChamberCenter(Int_t isec) const
674 // returns the default radial position
675 // of the readout chambers
676 if (isec<fNInnerSector)
677 return (fInnerRadiusLow+fInnerRadiusUp)/2.;
679 return (fOuterRadiusLow+fOuterRadiusUp)/2.;