Merge branch 'TPCdev' of https://git.cern.ch/reps/AliRoot into TPCdev
[u/mrichter/AliRoot.git] / TPC / Base / 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
88cb7938 16/* $Id$ */
4c039060 17
8c555625 18///////////////////////////////////////////////////////////////////////
19// Manager and of geomety classes for set: TPC //
20// //
1283eee5 21// !sectors are numbered from 0 //
22// !pad rows are numbered from 0 //
23//
24// 12.6. changed z relative
8c555625 25// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
26// //
27///////////////////////////////////////////////////////////////////////
28
73042f01 29//
8c555625 30
1283eee5 31#include <AliTPCParam.h>
8c555625 32
01473f7b 33#include <TGeoManager.h>
34#include <TGeoPhysicalNode.h>
61c82c27 35#include <TString.h>
01473f7b 36#include "AliAlignObj.h"
90dbf5fb 37#include "AliAlignObjParams.h"
01473f7b 38#include "AliLog.h"
e185e9d8 39#include "TGraphErrors.h"
2505f4c6 40#include "AliTPCcalibDB.h"
0ad1a123 41#include "AliTPCROC.h"
2505f4c6 42#include "AliMathBase.h"
43
44TObjArray *AliTPCParam::fBBParam = 0;
01473f7b 45
73042f01 46ClassImp(AliTPCParam)
8c555625 47
48
49//___________________________________________
50AliTPCParam::AliTPCParam()
179c6296 51 :AliDetectorParam(),
52 fbStatus(kFALSE),
53 fInnerRadiusLow(0.),
54 fInnerRadiusUp(0.),
55 fOuterRadiusUp(0.),
56 fOuterRadiusLow(0.),
57 fInnerAngle(0.),
58 fInnerAngleShift(0.),
59 fOuterAngle(0.),
60 fOuterAngleShift(0.),
61 fInnerFrameSpace(0.),
62 fOuterFrameSpace(0.),
63 fInnerWireMount(0.),
64 fOuterWireMount(0.),
65 fNInnerSector(0),
66 fNOuterSector(0),
67 fNSector(0),
68 fZLength(0),
69 fRotAngle(),
70 fGeometryType(0),
71 fTrackingMatrix(0),
72 fClusterMatrix(0),
73 fGlobalMatrix(0),
74 fNInnerWiresPerPad(0),
75 fInnerWWPitch(0),
76 fInnerDummyWire(0),
77 fInnerOffWire(0.),
78 fRInnerFirstWire(0.),
79 fRInnerLastWire(0.),
80 fLastWireUp1(0.),
81 fNOuter1WiresPerPad(0),
82 fNOuter2WiresPerPad(0),
83 fOuterWWPitch(0.),
84 fOuterDummyWire(0),
85 fOuterOffWire(0.),
86 fROuterFirstWire(0.),
87 fROuterLastWire(0.),
88 fInnerPadPitchLength(0.),
89 fInnerPadPitchWidth(0.),
90 fInnerPadLength(0.),
91 fInnerPadWidth(0.),
92 fOuter1PadPitchLength(0.),
93 fOuter2PadPitchLength(0.),
94 fOuterPadPitchWidth(0.),
95 fOuter1PadLength(0.),
96 fOuter2PadLength(0.),
97 fOuterPadWidth(0.),
98 fBMWPCReadout(kFALSE),
99 fNCrossRows(0),
100 fNRowLow(0),
101 fNRowUp1(0),
102 fNRowUp2(0),
103 fNRowUp(0),
104 fNtRows(0),
105 fDiffT(0.),
106 fDiffL(0.),
107 fGasGain(0.),
108 fDriftV(0.),
109 fOmegaTau(0.),
110 fAttCoef(0.),
111 fOxyCont(0.),
c94bc995 112 fFpot(0.),
113 fNprim(0.),
114 fNtot(0.),
115 fWmean(0.),
116 fExp(0.),
117 fEend(0.),
118 fBetheBloch(0x0),
f3869d7b 119 fGainSlopesHV(0), // graph with the gain slope as function of HV - per chamber
120 fGainSlopesPT(0), // graph with the gain slope as function of P/T - per chamber
179c6296 121 fPadCoupling(0.),
122 fZeroSup(0),
123 fNoise(0.),
124 fChipGain(0.),
125 fChipNorm(0.),
126 fTSample(0.),
127 fZWidth(0.),
128 fTSigma(0.),
129 fMaxTBin(0),
130 fADCSat(0),
131 fADCDynRange(0.),
132 fTotalNormFac(0.),
133 fNoiseNormFac(0.),
661f340b 134 fNominalVoltage(),
135 fMaxVoltageDeviation(40.),
136 fMaxDipVoltage(2.),
137 fMaxHVfractionBad(.4),
138 fVoltageDipScanPeriod(1.),
179c6296 139 fNResponseMax(0),
140 fResponseThreshold(0.),
141 fCurrentMax(0),
142 fResponseBin(0),
143 fResponseWeight(0),
144 fGateDelay(0.),
145 fL1Delay(0.),
146 fNTBinsBeforeL1(0),
147 fNTBinsL1(0.)
8c555625 148{
cc80f89e 149 //
150 //constructor sets the default parameters
151 //
152
7a09f434 153 SetTitle("75x40_100x60_150x60");
8c555625 154 SetDefault();
2505f4c6 155 if (!fBBParam) fBBParam= new TObjArray(1000);
8c555625 156}
157
cc80f89e 158AliTPCParam::~AliTPCParam()
1283eee5 159{
160 //
cc80f89e 161 //destructor deletes some dynamicaly alocated variables
162 //
163
164 if (fResponseBin!=0) delete [] fResponseBin;
165 if (fResponseWeight!=0) delete [] fResponseWeight;
166 if (fRotAngle !=0) delete [] fRotAngle;
753797ce 167
c828a869 168 CleanGeoMatrices();
753797ce 169
1283eee5 170}
171
cc80f89e 172Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const
173{
174 //
175 // calculates sector number (index[1], undefined on input)
176 // xyz intact
177 //
178
179 Float_t angle,x1;
180 Int_t sector;
181 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
182 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
183 else
8c555625 184 {
cc80f89e 185 angle =TMath::ASin(xyz[1]/r);
186 if (xyz[0]<0) angle=TMath::Pi()-angle;
187 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
188 }
3c0f9266 189
e0a1f962 190 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
cc80f89e 191
8c555625 192 Float_t cos,sin;
cc80f89e 193 AdjustCosSin(sector,cos,sin);
194 x1=xyz[0]*cos + xyz[1]*sin;
8c555625 195
cc80f89e 196 if (x1>fOuterRadiusLow)
197 {
e0a1f962 198 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
cc80f89e 199 if (xyz[2]<0) sector+=(fNOuterSector>>1);
200 }
8c555625 201 else
34bcefc7 202 if (xyz[2]<0) sector+=(fNInnerSector>>1);
203 if (sector<0 || sector>=fNSector) AliError(Form("Wrong sector %d",sector));
cc80f89e 204 index[1]=sector; // calculated sector number
205 index[0]=1; // indicates system after transformation
206 return sector;
207}
1283eee5 208
176aff27 209Bool_t AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
cc80f89e 210{
211 //transformation from input coodination system to output coordination system
212 switch (index[0]){
213 case 0:
214 break;
215 };
216
217 return kFALSE;
218
219}
220
221Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const
222{
223 //
224 //calculates pad row of point xyz - transformation to system 8 (digit system)
225 //
226 Int_t system = index[0];
227 if (0==system) {
228 Transform0to1(xyz,index);
229 system=1;
230 }
231 if (1==system) {
232 Transform1to2(xyz,index);
233 system=2;
234 }
235
236 if (fGeometryType==0){ //straight row
237 if (2==system) {
238 Transform2to3(xyz,index);
239 system=3;
240 }
241 if (3==system) {
242 Transform3to4(xyz,index);
243 system=4;
8c555625 244 }
cc80f89e 245 if (4==system) {
246 Transform4to8(xyz,index);
247 system=8;
8c555625 248 }
cc80f89e 249 if (8==system) {
250 index[0]=8;
251 return index[2];
252 }
8c555625 253 }
cc80f89e 254
255 if (fGeometryType==1){ //cylindrical geometry
256 if (2==system) {
257 Transform2to5(xyz,index);
258 system=5;
259 }
260 if (5==system) {
261 Transform2to3(xyz,index);
262 system=6;
263 }
264 if (6==system) {
265 Transform3to4(xyz,index);
266 system=7;
267 }
268 if (8==system) {
269 index[0]=8;
270 return index[2];
271 }
272 }
273 index[0]=system;
274 return -1; //if no reasonable system
8c555625 275}
276
cc80f89e 277void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
278 Float_t outershift)
8c555625 279{
cc80f89e 280 //
281 // set opening angles
176aff27 282 static const Float_t kDegtoRad = 0.01745329251994;
cc80f89e 283 fInnerAngle = innerangle; //opening angle of Inner sector
284 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
285 fOuterAngle = outerangle; //opening angle of outer sector
286 fOuterAngleShift = outershift; //shift of first sector center to the 0
287 fInnerAngle *=kDegtoRad;
288 fInnerAngleShift *=kDegtoRad;
289 fOuterAngle *=kDegtoRad;
290 fOuterAngleShift *=kDegtoRad;
8c555625 291}
cc80f89e 292
293Float_t AliTPCParam::GetInnerAngle() const
8c555625 294{
cc80f89e 295 //return angle
296 return fInnerAngle;
297
8c555625 298}
299
cc80f89e 300Float_t AliTPCParam::GetInnerAngleShift() const
301{
302 //return angle
303 return fInnerAngleShift;
8c555625 304}
cc80f89e 305Float_t AliTPCParam::GetOuterAngle() const
306{
307 //return angle
308 return fOuterAngle;
309}
310Float_t AliTPCParam::GetOuterAngleShift() const
311{
312 //return angle
313
314 return fOuterAngleShift;
315}
316
8c555625 317
8569a2b0 318Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
8c555625 319{
320 //
321 //give index of the given sector and pad row
322 //no control if the sectors and rows are reasonable !!!
323 //
cc80f89e 324 if (sector<fNInnerSector) return sector*fNRowLow+row;
325 return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;
8c555625 326}
327
cc80f89e 328Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
8c555625 329{
330 //
331 //return sector and padrow for given index
cc80f89e 332 //if index is reasonable returns true else return false
8c555625 333 //
334 if ( (index<0) || (index>fNtRows)) return kFALSE;
cc80f89e 335 Int_t outindex = fNInnerSector*fNRowLow;
8c555625 336 if (index<outindex) {
cc80f89e 337 sector = index/fNRowLow;
338 row = index - sector*fNRowLow;
8c555625 339 return kTRUE;
340 }
341 index-= outindex;
cc80f89e 342 sector = index/fNRowUp;
343 row = index - sector*fNRowUp;
344 sector += fNInnerSector;
8c555625 345 return kTRUE;
346}
347
cc80f89e 348void AliTPCParam::SetDefault()
8c555625 349{
350 //
cc80f89e 351 //set default parameters
8c555625 352 //
37831078 353 //const static Int_t kMaxRows=600;
73042f01 354 //
355 //sector default parameters
356 //
c254a4cb 357 static const Float_t kInnerRadiusLow = 83.65;
358 static const Float_t kInnerRadiusUp = 133.3;
359 static const Float_t kOuterRadiusLow = 133.5;
360 static const Float_t kOuterRadiusUp = 247.7;
176aff27 361 static const Float_t kInnerAngle = 20; // 20 degrees
362 static const Float_t kInnerAngleShift = 10;
363 static const Float_t kOuterAngle = 20; // 20 degrees
364 static const Float_t kOuterAngleShift = 10;
365 static const Float_t kInnerFrameSpace = 1.5;
366 static const Float_t kOuterFrameSpace = 1.5;
c254a4cb 367 static const Float_t kInnerWireMount = 1.2;
368 static const Float_t kOuterWireMount = 1.4;
176aff27 369 static const Float_t kZLength =250.;
370 static const Int_t kGeometryType = 0; //straight rows
371 static const Int_t kNRowLow = 63;
372 static const Int_t kNRowUp1 = 64;
373 static const Int_t kNRowUp2 = 32;
374 static const Int_t kNRowUp = 96;
73042f01 375 //
376 //wires default parameters
377 //
176aff27 378 static const Int_t kNInnerWiresPerPad = 3;
379 static const Int_t kInnerDummyWire = 2;
380 static const Float_t kInnerWWPitch = 0.25;
c254a4cb 381 static const Float_t kRInnerFirstWire = 84.475;
382 static const Float_t kRInnerLastWire = 132.475;
176aff27 383 static const Float_t kInnerOffWire = 0.5;
384 static const Int_t kNOuter1WiresPerPad = 4;
385 static const Int_t kNOuter2WiresPerPad = 6;
386 static const Float_t kOuterWWPitch = 0.25;
c254a4cb 387 static const Float_t kROuterFirstWire = 134.225;
388 static const Float_t kROuterLastWire = 246.975;
176aff27 389 static const Int_t kOuterDummyWire = 2;
390 static const Float_t kOuterOffWire = 0.5;
73042f01 391 //
392 //pad default parameters
393 //
176aff27 394 static const Float_t kInnerPadPitchLength = 0.75;
395 static const Float_t kInnerPadPitchWidth = 0.40;
396 static const Float_t kInnerPadLength = 0.75;
397 static const Float_t kInnerPadWidth = 0.40;
398 static const Float_t kOuter1PadPitchLength = 1.0;
399 static const Float_t kOuterPadPitchWidth = 0.6;
400 static const Float_t kOuter1PadLength = 1.0;
401 static const Float_t kOuterPadWidth = 0.6;
402 static const Float_t kOuter2PadPitchLength = 1.5;
403 static const Float_t kOuter2PadLength = 1.5;
404
405 static const Bool_t kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM
406 static const Int_t kNCrossRows = 1; //number of rows to cross-talk
73042f01 407
408 //
409 //gas default parameters
410 //
176aff27 411 static const Float_t kDiffT = 2.2e-2;
412 static const Float_t kDiffL = 2.2e-2;
413 static const Float_t kGasGain = 2.e4;
414 static const Float_t kDriftV =2.83e6;
415 static const Float_t kOmegaTau = 0.145;
416 static const Float_t kAttCoef = 250.;
417 static const Float_t kOxyCont = 5.e-6;
c94bc995 418 static const Float_t kFpot = 22.77e-9;
419 static const Float_t kNprim=14.35;
420 static const Float_t kNtot=42.66;
421 static const Float_t kWmean = 35.97e-9;
422 static const Float_t kExp = 2.2;
423 static const Float_t kEend = 10.e-6;
73042f01 424 //
425 //electronic default parameters
426 //
176aff27 427 static const Float_t kPadCoupling=0.5;
428 static const Int_t kZeroSup=2;
429 static const Float_t kNoise = 1000;
430 static const Float_t kChipGain = 12;
431 static const Float_t kChipNorm = 0.4;
432 static const Float_t kTSample = 2.e-7;
433 static const Float_t kTFWHM = 1.9e-7; //fwhm of charge distribution
434 static const Int_t kMaxTBin =445;
435 static const Int_t kADCSat =1024;
436 static const Float_t kADCDynRange =2000.;
73042f01 437 //
438 //response constants
439 //
176aff27 440 static const Int_t kNResponseMax=100;
441 static const Float_t kResponseThreshold=0.01;
01473f7b 442 //L1 constants
753797ce 443 // static const Float_t kGateDelay=6.1e-6; //In s
444 static const Float_t kGateDelay=0.; //For the moment no gating
445 // static const Float_t kL1Delay=6.5e-6; //In s
446 static const Float_t kL1Delay=0.; //For the moment no delay
447 // static const UShort_t kNTBinsBeforeL1=14;
448 static const UShort_t kNTBinsBeforeL1=0; //For the moment no shift
8c555625 449 fbStatus = kFALSE;
8c555625 450 //
cc80f89e 451 //set sector parameters
452 //
453 SetInnerRadiusLow(kInnerRadiusLow);
454 SetOuterRadiusLow(kOuterRadiusLow);
455 SetInnerRadiusUp(kInnerRadiusUp);
456 SetOuterRadiusUp(kOuterRadiusUp);
457 SetInnerFrameSpace(kInnerFrameSpace);
458 SetOuterFrameSpace(kOuterFrameSpace);
459 SetInnerWireMount(kInnerWireMount);
460 SetOuterWireMount(kOuterWireMount);
461 SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
462 SetZLength(kZLength);
463 SetGeometryType(kGeometryType);
f03e3423 464 SetRowNLow(kNRowLow);
465 SetRowNUp1 (kNRowUp1);
466 SetRowNUp2(kNRowUp2);
467 SetRowNUp(kNRowUp);
cc80f89e 468 //
469 //set wire parameters
470 //
471 SetInnerNWires(kNInnerWiresPerPad);
472 SetInnerDummyWire(kInnerDummyWire);
473 SetInnerOffWire(kInnerOffWire);
f03e3423 474 SetOuter1NWires(kNOuter1WiresPerPad);
475 SetOuter2NWire(kNOuter2WiresPerPad);
cc80f89e 476 SetOuterDummyWire(kOuterDummyWire);
477 SetOuterOffWire(kOuterOffWire);
f03e3423 478 SetInnerWWPitch(kInnerWWPitch);
479 SetRInnerFirstWire(kRInnerFirstWire);
480 SetRInnerLastWire(kRInnerLastWire);
481 SetOuterWWPitch(kOuterWWPitch);
482 SetROuterFirstWire(kROuterFirstWire);
483 SetROuterLastWire(kROuterLastWire);
cc80f89e 484 //
485 //set pad parameter
1283eee5 486 //
cc80f89e 487 SetInnerPadPitchLength(kInnerPadPitchLength);
488 SetInnerPadPitchWidth(kInnerPadPitchWidth);
489 SetInnerPadLength(kInnerPadLength);
490 SetInnerPadWidth(kInnerPadWidth);
f03e3423 491 SetOuter1PadPitchLength(kOuter1PadPitchLength);
492 SetOuter2PadPitchLength(kOuter2PadPitchLength);
cc80f89e 493 SetOuterPadPitchWidth(kOuterPadPitchWidth);
f03e3423 494 SetOuter1PadLength(kOuter1PadLength);
495 SetOuter2PadLength(kOuter2PadLength);
cc80f89e 496 SetOuterPadWidth(kOuterPadWidth);
497 SetMWPCReadout(kBMWPCReadout);
498 SetNCrossRows(kNCrossRows);
1283eee5 499 //
cc80f89e 500 //set gas paremeters
501 //
502 SetDiffT(kDiffT);
503 SetDiffL(kDiffL);
504 SetGasGain(kGasGain);
505 SetDriftV(kDriftV);
506 SetOmegaTau(kOmegaTau);
507 SetAttCoef(kAttCoef);
508 SetOxyCont(kOxyCont);
c94bc995 509 SetFpot(kFpot);
510 SetNprim(kNprim);
511 SetNtot(kNtot);
512 SetWmean(kWmean);
513 SetExp(kExp);
514 SetEend(kEend);
515 //
516 SetComposition(0.9,0.,0.1,0.,0.,0.);// Ne-CO2 90/10
517 //
2505f4c6 518 SetBetheBloch(GetBetheBlochParamAlice());
cc80f89e 519 //
520 //set electronivc parameters
521 //
522 SetPadCoupling(kPadCoupling);
523 SetZeroSup(kZeroSup);
524 SetNoise(kNoise);
525 SetChipGain(kChipGain);
526 SetChipNorm(kChipNorm);
527 SetTSample(kTSample);
528 SetTFWHM(kTFWHM);
529 SetMaxTBin(kMaxTBin);
530 SetADCSat(kADCSat);
531 SetADCDynRange(kADCDynRange);
61c82c27 532 for (UInt_t i=0; i<36; i++)
533 {
534 SetNominalVoltage(1196.0, i);
535 }
536 for (UInt_t i=36; i<72; i++)
537 {
538 SetNominalVoltage(1417.0, i);
539 }
01473f7b 540// //set magnetic field
541// SetBField(kBField);
542// SetNPrimLoss(kNPrimLoss);
543// SetNTotalLoss(kNTotalLoss);
cc80f89e 544 //
545 //set response parameters
546 //
547 SetNResponseMax(kNResponseMax);
bcc5d57d 548 SetResponseThreshold(static_cast<int>(kResponseThreshold));
01473f7b 549 //L1 data
550 SetGateDelay(kGateDelay);
551 SetL1Delay(kL1Delay);
552 SetNTBinsBeforeL1(kNTBinsBeforeL1);
832977ba 553 SetNominalGainSlopes();
8c555625 554}
cc80f89e 555
8c555625 556
557Bool_t AliTPCParam::Update()
558{
1283eee5 559 //
560 // update some calculated parameter which must be updated after changing "base"
561 // parameters
562 // for example we can change size of pads and according this recalculate number
563 // of pad rows, number of of pads in given row ....
564 //
73042f01 565 const Float_t kQel = 1.602e-19; // elementary charge
8c555625 566 fbStatus = kFALSE;
1283eee5 567
568 Int_t i,j; //loop variables because HP
569 //-----------------Sector section------------------------------------------
570 //calclulate number of sectors
cc80f89e 571 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2);
572 // number of inner sectors - factor 0.2 to don't be influnced by inprecision
1283eee5 573 if (fNInnerSector%2) return kFALSE;
574 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
575 if (fNOuterSector%2) return kFALSE;
576 fNSector = fNInnerSector+fNOuterSector;
cc80f89e 577
578 if (fRotAngle!=0) delete [] fRotAngle;
579 fRotAngle = new Float_t[4*fNSector];
1283eee5 580 //calculate sin and cosine of rotations angle
581 //sectors angles numbering from 0
cc80f89e 582
583 j=fNInnerSector*2;
1283eee5 584 Float_t angle = fInnerAngleShift;
cc80f89e 585 for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
1283eee5 586 fRotAngle[i]=TMath::Cos(angle);
587 fRotAngle[i+1]=TMath::Sin(angle);
588 fRotAngle[j] = fRotAngle[i];
589 fRotAngle[j+1] = fRotAngle[i+1];
cc80f89e 590 fRotAngle[i+2] =angle;
591 fRotAngle[j+2] =angle;
1283eee5 592 }
593 angle = fOuterAngleShift;
cc80f89e 594 j=(fNInnerSector+fNOuterSector/2)*4;
595 for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
1283eee5 596 fRotAngle[i]=TMath::Cos(angle);
597 fRotAngle[i+1]=TMath::Sin(angle);
598 fRotAngle[j] = fRotAngle[i];
599 fRotAngle[j+1] = fRotAngle[i+1];
cc80f89e 600 fRotAngle[i+2] =angle;
601 fRotAngle[j+2] =angle;
1283eee5 602 }
01473f7b 603
cc80f89e 604 fZWidth = fTSample*fDriftV;
73042f01 605 fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
606 fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
cc80f89e 607 //wire section
f03e3423 608 /* Int_t nwire;
cc80f89e 609 Float_t wspace; //available space for wire
610 Float_t dummyspace; //dummyspace for wire
f03e3423 611
cc80f89e 612 wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
613 nwire = Int_t(wspace/fInnerWWPitch);
614 wspace = Float_t(nwire)*fInnerWWPitch;
f03e3423 615 dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;
cc80f89e 616 wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
617 nwire = Int_t(wspace/fOuterWWPitch);
618 wspace = Float_t(nwire)*fOuterWWPitch;
619 dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.;
620 fROuterFirstWire = fOuterRadiusLow+dummyspace;
621 fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
f03e3423 622 */
1283eee5 623
8c555625 624 //
cc80f89e 625 //response data
626 //
f103ba87 627 if (fResponseBin) delete [] fResponseBin;
628 if (fResponseWeight) delete [] fResponseWeight;
cc80f89e 629 fResponseBin = new Int_t[3*fNResponseMax];
630 fResponseWeight = new Float_t[fNResponseMax];
01473f7b 631
632 //L1 data
633 fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
8c555625 634 fbStatus = kTRUE;
635 return kTRUE;
636}
637
c828a869 638void AliTPCParam::CleanGeoMatrices(){
639 //
640 // clean geo matrices
641 //
8c555625 642
c828a869 643 if (fTrackingMatrix) {
644 for(Int_t i = 0; i < fNSector; i++)
645 delete fTrackingMatrix[i];
646 delete [] fTrackingMatrix;
647 }
648
649 if (fClusterMatrix) {
650 for(Int_t i = 0; i < fNSector; i++)
651 delete fClusterMatrix[i];
652 delete [] fClusterMatrix;
653 }
654
655 if (fGlobalMatrix) {
656 for(Int_t i = 0; i < fNSector; i++)
657 delete fGlobalMatrix[i];
658 delete [] fGlobalMatrix;
659 }
660
661 return;
662}
8c555625 663
01473f7b 664Bool_t AliTPCParam::ReadGeoMatrices(){
665 //
ac81c411 666 // read geo matrixes
01473f7b 667 //
668 if (!gGeoManager){
669 AliFatal("Geo manager not initialized\n");
670 }
90dbf5fb 671 AliAlignObjParams o;
01473f7b 672 //
c828a869 673
674 // clean geo matrices
675 CleanGeoMatrices();
676
677 // create new geo matrices
74707dd2 678 fTrackingMatrix = new TGeoHMatrix*[fNSector];
74707dd2 679 fClusterMatrix = new TGeoHMatrix*[fNSector];
01473f7b 680 fGlobalMatrix = new TGeoHMatrix*[fNSector];
aa414899 681 for (Int_t isec=0; isec<fNSector; isec++) {
682 fGlobalMatrix[isec] = 0;
683 fClusterMatrix[isec]= 0;
684 fTrackingMatrix[isec]=0;
685 }
01473f7b 686 //
687 for (Int_t isec=0; isec<fNSector; isec++) {
688 fGlobalMatrix[isec] = 0;
74707dd2 689 fClusterMatrix[isec]= 0;
690 fTrackingMatrix[isec]=0;
ae079791 691 AliGeomManager::ELayerID iLayer;
01473f7b 692 Int_t iModule;
693
694 if(isec<fNInnerSector) {
ae079791 695 iLayer = AliGeomManager::kTPC1;
01473f7b 696 iModule = isec;
697 }
698 else {
ae079791 699 iLayer = AliGeomManager::kTPC2;
01473f7b 700 iModule = isec - fNInnerSector;
701 }
702
ae079791 703 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
294cf349 704 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(volid);
705 if(!pne)
706 {
707 AliError(Form("Alignable entry for volume ID %d not in geometry. Exiting!",volid));
708 return kFALSE;
709 }
710 const char *path = pne->GetTitle();
711 if (!gGeoManager->cd(path)) return kFALSE;
ac81c411 712 TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
995d5cc2 713 // Since GEANT4 does not allow reflections, in this case the reflection
714 // component if the matrix is embedded by TGeo inside TGeoScaledShape
715 if (gGeoManager->GetCurrentVolume()->GetShape()->IsReflected())
716 m->ReflectZ(kFALSE, kTRUE);
01473f7b 717 //
718 TGeoRotation mchange;
719 mchange.RotateY(90); mchange.RotateX(90);
74707dd2 720 Float_t ROCcenter[3];
721 GetChamberCenter(isec,ROCcenter);
722 //
01473f7b 723 // Convert to global coordinate system
74707dd2 724 //
01473f7b 725 fGlobalMatrix[isec] = new TGeoHMatrix(*m);
726 fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
74707dd2 727 TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
728 fGlobalMatrix[isec]->Multiply(&center);
729 //
730 // cluster correction matrix
731 //
732 fClusterMatrix[isec] = new TGeoHMatrix;
733 Double_t sectorAngle = 20.*(isec%18)+10;
734 TGeoHMatrix rotMatrix;
735 rotMatrix.RotateZ(sectorAngle);
736 if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
737 //
738 // mirrored system
739 //
740 TGeoRotation mirrorZ;
741 mirrorZ.SetAngles(90,0,90,90,180,0);
742 fClusterMatrix[isec]->Multiply(&mirrorZ);
743 }
a1ec4d07 744 TGeoTranslation trans(0,0,GetZLength(isec));
74707dd2 745 fClusterMatrix[isec]->MultiplyLeft(&trans);
746 fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));
747 fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
01473f7b 748 }
749 return kTRUE;
750}
751
1ac29fc4 752TGeoHMatrix * AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
753 //
754 // make local to tracking matrix
755 //
756 Double_t sectorAngle = 20.*(sector%18)+10;
757 TGeoHMatrix *newMatrix = new TGeoHMatrix();
758 newMatrix->RotateZ(sectorAngle);
759 newMatrix->MultiplyLeft(&(geoMatrix->Inverse()));
760 return newMatrix;
761}
762
763
764
01473f7b 765
bf6adc12 766Bool_t AliTPCParam::GetStatus() const
8c555625 767{
768 //get information about object consistency
769 return fbStatus;
770}
771
772Int_t AliTPCParam::GetNRowLow() const
773{
774 //get the number of pad rows in low sector
cc80f89e 775 return fNRowLow;
8c555625 776}
777Int_t AliTPCParam::GetNRowUp() const
778{
779 //get the number of pad rows in up sector
cc80f89e 780 return fNRowUp;
8c555625 781}
f03e3423 782Int_t AliTPCParam::GetNRowUp1() const
783{
784 //get the number of pad rows in up1 sector
785 return fNRowUp1;
786}
787Int_t AliTPCParam::GetNRowUp2() const
788{
789 //get the number of pad rows in up2 sector
790 return fNRowUp2;
791}
8c555625 792Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
793{
794 //get the pad row (irow) radii
cc80f89e 795 if ( !(irow<0) && (irow<fNRowLow) )
8c555625 796 return fPadRowLow[irow];
797 else
798 return 0;
799}
800
801Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
802{
803 //get the pad row (irow) radii
cc80f89e 804 if ( !(irow<0) && (irow<fNRowUp) )
8c555625 805 return fPadRowUp[irow];
806 else
807 return 0;
808}
809
810Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
811{
812 //get the number of pads in row irow
cc80f89e 813 if ( !(irow<0) && (irow<fNRowLow) )
814 return fNPadsLow[irow];
8c555625 815 else
816 return 0;
817}
818
819
820Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
821{
822 //get the number of pads in row irow
cc80f89e 823 if ( !(irow<0) && (irow<fNRowUp) )
824 return fNPadsUp[irow];
8c555625 825 else
826 return 0;
827}
0ad1a123 828
829Int_t AliTPCParam::GetWireSegment(Int_t sector, Int_t row) const
830{
831 //
832 // Get Anode wire segment index IROC --> 4 segments in [0,3], 7 segments OROC[4,10]
833 //
834 // To be speed-up using caching lookup table
835 //
836 Int_t wireIndex = -1;
837 // check if the given set of sector and row is OK
838 if ( (sector<0 || sector>=72) || (row<0 || row>95) || (sector<36 && row>64) ){
839 AliError("No matching anode wire segment for this set of sector-row \n");
840 return wireIndex;
841 }
842 // find the wire index for given sector-row
843 if ( sector<36 ){ // IROC anode wire segments
844 if (row<16) wireIndex=0;
845 else if (row>=16 && row<32) wireIndex=1;
846 else if (row>=32 && row<48) wireIndex=2;
847 else wireIndex=3;
848 } else { // OROC anode wire segments
849 if (row<16) wireIndex=4;
850 else if ( row>=16 && row<32) wireIndex=5;
851 else if ( row>=32 && row<48) wireIndex=6;
852 else if ( row>=48 && row<64) wireIndex=7;
853 else if ( row>=64 && row<75) wireIndex=8;
854 else if ( row>=75 && row<85) wireIndex=9;
855 else wireIndex=10;
856 }
857 return wireIndex;
858}
859
860Int_t AliTPCParam::GetNPadsPerSegment(Int_t wireSegmentID) const
861{
862 //
863 // Get the number of pads in a given anode wire segment
864 //
865 // check if the given segment index is OK
866 // To be done (if needed) - cache the lookup table
867 //
868 if ( wireSegmentID<0 || wireSegmentID>10 ){
869 AliError("Wrong anode wire segment index. it should be [0,10] \n");
870 return -1;
871 }
872 // get sector type from wireSegmentID
873 Int_t sector = (wireSegmentID<4) ? 0 : 36; // ROC [0,35] --> IROC, ROC [36,71] --> OROC
874 // get the upper and lower row number for the given wireSegmentID
875 Int_t segRowDown = 0;
876 Int_t segRowUp = 0;
877
878 if ( wireSegmentID == 0 || wireSegmentID == 4 ) {
879 segRowDown = 0;
880 segRowUp = 16;
881 } else if ( wireSegmentID == 1 || wireSegmentID == 5 ) {
882 segRowDown = 16;
883 segRowUp = 32;
884 } else if ( wireSegmentID == 2 || wireSegmentID == 6 ) {
885 segRowDown = 32;
886 segRowUp = 48;
887 } else if ( wireSegmentID == 3 || wireSegmentID == 7 ) {
888 segRowDown = 48;
36aef984 889 segRowUp = 63;
0ad1a123 890 } else if ( wireSegmentID == 8 ) {
891 segRowDown = 64;
892 segRowUp = 75;
893 } else if ( wireSegmentID == 9 ) {
894 segRowDown = 75;
895 segRowUp = 85;
896 } else {
897 segRowDown = 85;
898 segRowUp = 95;
899 }
900 // count the number of pads on the given segment
901 AliTPCROC *r=AliTPCROC::Instance();
902 Int_t nPads=0;
903 for (Int_t irow = segRowDown; irow < segRowUp ; irow++){
904 nPads += r->GetNPads(sector,irow);
905 }
906 return nPads;
907}
908
f03e3423 909Float_t AliTPCParam::GetYInner(Int_t irow) const
910{
911 return fYInner[irow];
912}
913
914
915Float_t AliTPCParam::GetYOuter(Int_t irow) const
916{
917 return fYOuter[irow];
918}
919
01473f7b 920Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
921{
922 // returns the sector index
923 // takes as input the angle, index of the pad row and z position
924 if(row<0) return -1;
f03e3423 925
01473f7b 926 if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
927 if (angle < 0. ) angle += 2.*TMath::Pi();
928
929 Int_t sector;
930 if(row<fNRowLow) {
931 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
932 if (z<0) sector += (fNInnerSector>>1);
933 }
934 else {
935 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
936 if (z<0) sector += (fNOuterSector>>1);
937 }
938
939 return sector;
940}
f03e3423 941
74707dd2 942Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
01473f7b 943{
944 // returns the default radial position
945 // of the readout chambers
74707dd2 946
947 const Float_t kROCcenterIn = 110.2;
948 const Float_t kROCcenterOut = 188.45;
949
950 if (isec<fNInnerSector){
951 if (center){
952 center[0] = kROCcenterIn;
953 center[1] = 0;
f0043941 954 center[2] = -5.51-0.08;
74707dd2 955 }
956 return kROCcenterIn;
957 }
958 else{
959 if (center){
960 center[0] = kROCcenterOut;
961 center[1] = 0;
f0043941 962 center[2] = -5.61-0.08;
74707dd2 963 }
964 return kROCcenterOut;
965 }
01473f7b 966}
f03e3423 967
e185e9d8 968void AliTPCParam::SetNominalGainSlopes(){
969 //
970 // Setting the nominal TPC gain slopes
971 // Nominal values were obtained as a mena values foe 2010,2011, and 2012 data
972 // Differntial values can be provided per year
973 //
974 Float_t sector[72]={0};
975 Float_t gainHV[72]={0};
976 Float_t gainPT[72]={0};
977 //
978 for (Int_t isec=0; isec<72; isec++){
979 sector[isec]=isec;
980 gainHV[isec]=0.0115; // change of the Gain dG/G per 1 Volt of voltage change(1/V) - it is roughly the same for IROC and OROC
981 gainPT[isec]=2.2; // change of the Gains dG/G per P/T change ()
982 }
983 fGainSlopesHV = new TGraphErrors(72,sector,gainHV,0,0);
984 fGainSlopesPT = new TGraphErrors(72,sector,gainPT,0,0);
867224d5 985 fGainSlopesHV->SetName("GainSlopesHV");
986 fGainSlopesPT->SetName("GainSlopesPT");
e185e9d8 987}
2505f4c6 988
989
990TVectorD * AliTPCParam::GetBetheBlochParamNa49(){
991 //
992 // Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
993 // Na49 parameters were used as first set of parameters for ALICE simulation
994 // (see TPC TDR for details)
995 TVectorD v(5);
996 v(0)=0.76176e-1;
997 v(1)=10.632;
998 v(2)=0.13279e-4;
999 v(3)=1.8631;
1000 v(4)=1.9479;
1001 return new TVectorD(v);
1002}
1003
1004TVectorD * AliTPCParam::GetBetheBlochParamAlice(){
1005 //
1006 //
1007 // Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
1008 // Na49 parameters were used as first set of parameters for ALICE simulation
1009 // Second set was obtained from ALICE 2009-2013 data taking
1010 // (see TPC TDR for details)
1011 //
1012 TVectorD v(5);
1013 v[0] = 0.0851148;
1014 v[1] = 9.25771;
1015 v[2] = 2.6558e-05;
1016 v[3] = 2.32742;
1017 v[4] = 1.83039;
1018 return new TVectorD(v);
1019}
1020
1021
1022Double_t AliTPCParam::BetheBlochAleph(Double_t bg, Int_t type){
1023 //
1024 // GetBetheBloch retur values for the parametrs regieter at poition type
1025 // Used for visualization and comparison purposes
1026 TVectorD * paramBB =0;
1027 if (type==0) {
1028 AliTPCParam* param = AliTPCcalibDB::Instance()->GetParameters();
1029 if (param) paramBB=param->GetBetheBlochParameters();
1030 }
1031 if (type>0){
1032 paramBB = (TVectorD*)fBBParam->At(type);
1033 }
1034 if (!paramBB) return 0;
1035 //
1036 return AliMathBase::BetheBlochAleph(bg,(*paramBB)(0),(*paramBB)(1),(*paramBB)(2),(*paramBB)(3),(*paramBB)(4));
1037}
1038
1039
1040void AliTPCParam::RegisterBBParam(TVectorD* param, Int_t position){
1041 //
1042 //
1043 //
1044 fBBParam->AddAt(param,position);
1045}