]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPC.cxx
add centrality and event plane histos per analysis
[u/mrichter/AliRoot.git] / TPC / AliTPC.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
fe4da5cc 18///////////////////////////////////////////////////////////////////////////////
19// //
20// Time Projection Chamber //
21// This class contains the basic functions for the Time Projection Chamber //
22// detector. Functions specific to one particular geometry are //
23// contained in the derived classes //
24// //
25//Begin_Html
26/*
1439f98e 27<img src="picts/AliTPCClass.gif">
fe4da5cc 28*/
29//End_Html
30// //
8c555625 31// //
fe4da5cc 32///////////////////////////////////////////////////////////////////////////////
33
73042f01 34//
35
88cb7938 36#include <Riostream.h>
37#include <stdlib.h>
38
f7a1cc68 39#include <TF2.h>
88cb7938 40#include <TFile.h>
f7a1cc68 41#include <TGeoGlobalMagField.h>
88cb7938 42#include <TInterpreter.h>
fe4da5cc 43#include <TMath.h>
e8d02863 44#include <TMatrixF.h>
fe4da5cc 45#include <TObjectTable.h>
88cb7938 46#include <TParticle.h>
afc42102 47#include <TROOT.h>
88cb7938 48#include <TRandom.h>
f7a1cc68 49#include <TStopwatch.h>
50#include <TString.h>
afc42102 51#include <TSystem.h>
88cb7938 52#include <TTree.h>
f7a1cc68 53#include <TVector.h>
88cb7938 54#include <TVirtualMC.h>
f546a4b4 55#include <TParameter.h>
cc80f89e 56
cc80f89e 57#include "AliDigits.h"
88cb7938 58#include "AliMagF.h"
88cb7938 59#include "AliRun.h"
60#include "AliRunLoader.h"
cc80f89e 61#include "AliSimDigits.h"
88cb7938 62#include "AliTPC.h"
63#include "AliTPC.h"
88cb7938 64#include "AliTPCDigitsArray.h"
65#include "AliTPCLoader.h"
66#include "AliTPCPRF2D.h"
67#include "AliTPCParamSR.h"
68#include "AliTPCRF1D.h"
792bb11c 69#include "AliTPCTrackHitsV2.h"
88cb7938 70#include "AliTrackReference.h"
5d12ce38 71#include "AliMC.h"
5bf6eb16 72#include "AliStack.h"
85a5290f 73#include "AliTPCDigitizer.h"
0421c3d1 74#include "AliTPCBuffer.h"
75#include "AliTPCDDLRawData.h"
8c2b3fd7 76#include "AliLog.h"
79fa3dc8 77#include "AliTPCcalibDB.h"
78#include "AliTPCCalPad.h"
79#include "AliTPCCalROC.h"
80#include "AliTPCExB.h"
bc807150 81#include "AliRawReader.h"
dbfbf54e 82#include "AliTPCRawStreamV3.h"
23effa8e 83#include "TTreeStream.h"
39c8eb58 84
fe4da5cc 85ClassImp(AliTPC)
fe4da5cc 86//_____________________________________________________________________________
179c6296 87 AliTPC::AliTPC():AliDetector(),
88 fDefaults(0),
89 fSens(0),
90 fNsectors(0),
91 fDigitsArray(0),
92 fTPCParam(0),
93 fTrackHits(0),
94 fHitType(0),
95 fDigitsSwitch(0),
96 fSide(0),
b97617a6 97 fPrimaryIonisation(0),
179c6296 98 fNoiseDepth(0),
99 fNoiseTable(0),
100 fCurrentNoise(0),
8261c673 101 fActiveSectors(0),
23effa8e 102 fGainFactor(1.),
f546a4b4 103 fDebugStreamer(0),
a120cd1d 104 fLHCclockPhaseSw(0),
105 fIsGEM(0)
179c6296 106
fe4da5cc 107{
108 //
109 // Default constructor
110 //
111 fIshunt = 0;
712976a6 112 for(Int_t i=0;i<4;i++) fCurrentIndex[i]=0;
179c6296 113
be5ffbfe 114 // fTrackHitsOld = 0;
8c2b3fd7 115#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
116 fHitType = 4; // ROOT containers
117#else
118 fHitType = 2; //default CONTAINERS - based on ROOT structure
119#endif
fe4da5cc 120}
121
122//_____________________________________________________________________________
123AliTPC::AliTPC(const char *name, const char *title)
179c6296 124 : AliDetector(name,title),
125 fDefaults(0),
126 fSens(0),
127 fNsectors(0),
128 fDigitsArray(0),
129 fTPCParam(0),
130 fTrackHits(0),
131 fHitType(0),
132 fDigitsSwitch(0),
133 fSide(0),
b97617a6 134 fPrimaryIonisation(0),
179c6296 135 fNoiseDepth(0),
136 fNoiseTable(0),
137 fCurrentNoise(0),
8261c673 138 fActiveSectors(0),
f546a4b4 139 fGainFactor(1.),
140 fDebugStreamer(0),
a120cd1d 141 fLHCclockPhaseSw(0),
142 fIsGEM(0)
b97617a6 143
fe4da5cc 144{
145 //
146 // Standard constructor
147 //
148
149 //
150 // Initialise arrays of hits and digits
151 fHits = new TClonesArray("AliTPChit", 176);
5d12ce38 152 gAlice->GetMCApp()->AddHitList(fHits);
fe4da5cc 153 //
792bb11c 154 fTrackHits = new AliTPCTrackHitsV2;
39c8eb58 155 fTrackHits->SetHitPrecision(0.002);
156 fTrackHits->SetStepPrecision(0.003);
792bb11c 157 fTrackHits->SetMaxDistance(100);
158
be5ffbfe 159 //fTrackHitsOld = new AliTPCTrackHits; //MI - 13.09.2000
160 //fTrackHitsOld->SetHitPrecision(0.002);
161 //fTrackHitsOld->SetStepPrecision(0.003);
162 //fTrackHitsOld->SetMaxDistance(100);
792bb11c 163
39c8eb58 164
8c2b3fd7 165#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
166 fHitType = 4; // ROOT containers
167#else
da33556f 168 fHitType = 2;
8c2b3fd7 169#endif
179c6296 170
712976a6 171 for(Int_t i=0;i<4;i++) fCurrentIndex[i]=0;
cc80f89e 172
fe4da5cc 173 //
174 fIshunt = 0;
175 //
176 // Initialise color attributes
e939a978 177 //PH SetMarkerColor(kYellow);
73042f01 178
179 //
180 // Set TPC parameters
181 //
182
afc42102 183
a964d561 184 if (!strcmp(title,"Ne-CO2") || !strcmp(title,"Ne-CO2-N") || !strcmp(title,"Default") ) {
185 fTPCParam = AliTPCcalibDB::Instance()->GetParameters();
73042f01 186 } else {
a964d561 187
8c2b3fd7 188 AliWarning("In Config.C you must set non-default parameters.");
a964d561 189 fTPCParam=0;
73042f01 190 }
23effa8e 191
fe4da5cc 192}
0f2ff24c 193void AliTPC::CreateDebugStremer(){
194 //
195 // Create Debug streamer to check simulation
196 //
197 fDebugStreamer = new TTreeSRedirector("TPCSimdebug.root");
198}
fe4da5cc 199//_____________________________________________________________________________
200AliTPC::~AliTPC()
201{
202 //
203 // TPC destructor
204 //
73042f01 205
fe4da5cc 206 fIshunt = 0;
207 delete fHits;
208 delete fDigits;
db2fdcfb 209 //delete fTPCParam;
39c8eb58 210 delete fTrackHits; //MI 15.09.2000
be5ffbfe 211 // delete fTrackHitsOld; //MI 10.12.2001
9ff4af81 212
213 fDigitsArray = 0x0;
214 delete [] fNoiseTable;
215 delete [] fActiveSectors;
23effa8e 216 if (fDebugStreamer) delete fDebugStreamer;
fe4da5cc 217}
218
fe4da5cc 219//_____________________________________________________________________________
220void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
221{
222 //
223 // Add a hit to the list
224 //
39c8eb58 225 if (fHitType&1){
226 TClonesArray &lhits = *fHits;
227 new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
228 }
792bb11c 229 if (fHitType>1)
8c2b3fd7 230 AddHit2(track,vol,hits);
fe4da5cc 231}
88cb7938 232
fe4da5cc 233//_____________________________________________________________________________
234void AliTPC::CreateMaterials()
235{
8c555625 236 //-----------------------------------------------
37831078 237 // Create Materials for for TPC simulations
8c555625 238 //-----------------------------------------------
239
240 //-----------------------------------------------------------------
241 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
242 //-----------------------------------------------------------------
1283eee5 243
f7a1cc68 244 Int_t iSXFLD=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
245 Float_t sXMGMX=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
1283eee5 246
247 Float_t amat[5]; // atomic numbers
248 Float_t zmat[5]; // z
249 Float_t wmat[5]; // proportions
250
251 Float_t density;
37831078 252
1283eee5 253
1283eee5 254
c1637e41 255 //***************** Gases *************************
1283eee5 256
37831078 257
1283eee5 258 //--------------------------------------------------------------
c1637e41 259 // gases - air and CO2
1283eee5 260 //--------------------------------------------------------------
261
37831078 262 // CO2
1283eee5 263
264 amat[0]=12.011;
265 amat[1]=15.9994;
266
267 zmat[0]=6.;
268 zmat[1]=8.;
269
c1637e41 270 wmat[0]=0.2729;
271 wmat[1]=0.7271;
1283eee5 272
2556fc5b 273 density=0.001754609;
1283eee5 274
1283eee5 275
c1637e41 276 AliMixture(10,"CO2",amat,zmat,density,2,wmat);
277 //
278 // Air
279 //
280 amat[0]=15.9994;
281 amat[1]=14.007;
282 //
283 zmat[0]=8.;
284 zmat[1]=7.;
285 //
286 wmat[0]=0.233;
287 wmat[1]=0.767;
288 //
289 density=0.001205;
1283eee5 290
c1637e41 291 AliMixture(11,"Air",amat,zmat,density,2,wmat);
292
1283eee5 293 //----------------------------------------------------------------
c1637e41 294 // drift gases
1283eee5 295 //----------------------------------------------------------------
37831078 296
4f1c6f0b 297 //
a964d561 298 // Drift gases 1 - nonsensitive, 2 - sensitive, 3 - for Kr
299 // Composition by % of volume, values at 20deg and 1 atm.
300 //
301 // get the geometry title - defined in Config.C
302 //
e4e763b9 303
a964d561 304 TString title(GetTitle());
305
306 //
e4e763b9 307 amat[0]= 20.18;
308 amat[1]=12.011;
309 amat[2]=15.9994;
a964d561 310
e4e763b9 311
312 zmat[0]= 10.;
313 zmat[1]=6.;
314 zmat[2]=8.;
e4e763b9 315
70077293 316 if(title == TString("Ne-CO2") || title == TString("Default")){
a964d561 317 wmat[0]=0.8038965;
318 wmat[1]= 0.053519;
319 wmat[2]= 0.1425743;
320 density=0.0009393;
321 //
322 AliMixture(12,"Ne-CO2-1",amat,zmat,density,3,wmat);
323 AliMixture(13,"Ne-CO2-2",amat,zmat,density,3,wmat);
324 AliMixture(35,"Ne-CO2-3",amat,zmat,density,3,wmat);
325 }
326 else if (title == TString("Ne-CO2-N")){
327 amat[3]=14.007;
328 zmat[3]=7.;
329 wmat[0]=0.756992632;
330 wmat[1]=0.056235789;
331 wmat[2]=0.128469474;
332 wmat[3]=0.058395789;
333 density=0.000904929;
334 //
335 AliMixture(12,"Ne-CO2-N-1",amat,zmat,density,4,wmat);
336 AliMixture(13,"Ne-CO2-N-2",amat,zmat,density,4,wmat);
337 AliMixture(30,"Ne-CO2-N-3",amat,zmat,density,4,wmat);
338
339 }
340
341
342
1283eee5 343 //----------------------------------------------------------------------
344 // solid materials
345 //----------------------------------------------------------------------
346
1283eee5 347
37831078 348 // Kevlar C14H22O2N2
1283eee5 349
37831078 350 amat[0] = 12.011;
351 amat[1] = 1.;
352 amat[2] = 15.999;
353 amat[3] = 14.006;
1283eee5 354
37831078 355 zmat[0] = 6.;
356 zmat[1] = 1.;
357 zmat[2] = 8.;
358 zmat[3] = 7.;
359
360 wmat[0] = 14.;
361 wmat[1] = 22.;
362 wmat[2] = 2.;
363 wmat[3] = 2.;
364
365 density = 1.45;
366
c1637e41 367 AliMixture(14,"Kevlar",amat,zmat,density,-4,wmat);
37831078 368
369 // NOMEX
1283eee5 370
37831078 371 amat[0] = 12.011;
372 amat[1] = 1.;
373 amat[2] = 15.999;
374 amat[3] = 14.006;
375
376 zmat[0] = 6.;
377 zmat[1] = 1.;
378 zmat[2] = 8.;
379 zmat[3] = 7.;
380
381 wmat[0] = 14.;
382 wmat[1] = 22.;
383 wmat[2] = 2.;
384 wmat[3] = 2.;
385
c1637e41 386 density = 0.029;
387
388 AliMixture(15,"NOMEX",amat,zmat,density,-4,wmat);
37831078 389
390 // Makrolon C16H18O3
391
392 amat[0] = 12.011;
393 amat[1] = 1.;
394 amat[2] = 15.999;
1283eee5 395
37831078 396 zmat[0] = 6.;
397 zmat[1] = 1.;
398 zmat[2] = 8.;
399
400 wmat[0] = 16.;
401 wmat[1] = 18.;
402 wmat[2] = 3.;
403
404 density = 1.2;
405
c1637e41 406 AliMixture(16,"Makrolon",amat,zmat,density,-3,wmat);
407
408 // Tedlar C2H3F
409
410 amat[0] = 12.011;
411 amat[1] = 1.;
412 amat[2] = 18.998;
413
414 zmat[0] = 6.;
415 zmat[1] = 1.;
416 zmat[2] = 9.;
417
418 wmat[0] = 2.;
419 wmat[1] = 3.;
420 wmat[2] = 1.;
421
422 density = 1.71;
423
424 AliMixture(17, "Tedlar",amat,zmat,density,-3,wmat);
37831078 425
1283eee5 426 // Mylar C5H4O2
427
428 amat[0]=12.011;
429 amat[1]=1.;
430 amat[2]=15.9994;
431
432 zmat[0]=6.;
433 zmat[1]=1.;
434 zmat[2]=8.;
435
436 wmat[0]=5.;
437 wmat[1]=4.;
438 wmat[2]=2.;
439
440 density = 1.39;
fe4da5cc 441
c1637e41 442 AliMixture(18, "Mylar",amat,zmat,density,-3,wmat);
443 // material for "prepregs"
444 // Epoxy - C14 H20 O3
445 // Quartz SiO2
446 // Carbon C
447 // prepreg1 60% C-fiber, 40% epoxy (vol)
448 amat[0]=12.011;
449 amat[1]=1.;
450 amat[2]=15.994;
1283eee5 451
c1637e41 452 zmat[0]=6.;
453 zmat[1]=1.;
454 zmat[2]=8.;
1283eee5 455
c1637e41 456 wmat[0]=0.923;
457 wmat[1]=0.023;
458 wmat[2]=0.054;
1283eee5 459
c1637e41 460 density=1.859;
1283eee5 461
c1637e41 462 AliMixture(19, "Prepreg1",amat,zmat,density,3,wmat);
1283eee5 463
c1637e41 464 //prepreg2 60% glass-fiber, 40% epoxy
1283eee5 465
c1637e41 466 amat[0]=12.01;
467 amat[1]=1.;
468 amat[2]=15.994;
469 amat[3]=28.086;
470
471 zmat[0]=6.;
472 zmat[1]=1.;
473 zmat[2]=8.;
474 zmat[3]=14.;
475
476 wmat[0]=0.194;
477 wmat[1]=0.023;
478 wmat[2]=0.443;
efbf94c5 479 wmat[3]=0.34;
c1637e41 480
481 density=1.82;
482
483 AliMixture(20, "Prepreg2",amat,zmat,density,4,wmat);
484
485 //prepreg3 50% glass-fiber, 50% epoxy
486
487 amat[0]=12.01;
488 amat[1]=1.;
489 amat[2]=15.994;
490 amat[3]=28.086;
491
492 zmat[0]=6.;
493 zmat[1]=1.;
494 zmat[2]=8.;
495 zmat[3]=14.;
1283eee5 496
efbf94c5 497 wmat[0]=0.257;
c1637e41 498 wmat[1]=0.03;
efbf94c5 499 wmat[2]=0.412;
c1637e41 500 wmat[3]=0.3;
501
0f788f87 502 density=1.725;
c1637e41 503
504 AliMixture(21, "Prepreg3",amat,zmat,density,4,wmat);
505
506 // G10 60% SiO2 40% epoxy
507
508 amat[0]=12.01;
509 amat[1]=1.;
510 amat[2]=15.994;
511 amat[3]=28.086;
512
513 zmat[0]=6.;
514 zmat[1]=1.;
515 zmat[2]=8.;
516 zmat[3]=14.;
517
518 wmat[0]=0.194;
519 wmat[1]=0.023;
520 wmat[2]=0.443;
521 wmat[3]=0.340;
522
523 density=1.7;
524
525 AliMixture(22, "G10",amat,zmat,density,4,wmat);
526
37831078 527 // Al
1283eee5 528
37831078 529 amat[0] = 26.98;
530 zmat[0] = 13.;
1283eee5 531
37831078 532 density = 2.7;
1283eee5 533
c1637e41 534 AliMaterial(23,"Al",amat[0],zmat[0],density,999.,999.);
1283eee5 535
c1637e41 536 // Si (for electronics
1283eee5 537
37831078 538 amat[0] = 28.086;
9a3667bd 539 zmat[0] = 14.;
1283eee5 540
37831078 541 density = 2.33;
1283eee5 542
c1637e41 543 AliMaterial(24,"Si",amat[0],zmat[0],density,999.,999.);
1283eee5 544
37831078 545 // Cu
1283eee5 546
37831078 547 amat[0] = 63.546;
548 zmat[0] = 29.;
1283eee5 549
37831078 550 density = 8.96;
1283eee5 551
c1637e41 552 AliMaterial(25,"Cu",amat[0],zmat[0],density,999.,999.);
1283eee5 553
0f788f87 554 // brass
555
556 amat[0] = 63.546;
557 zmat[0] = 29.;
558 //
559 amat[1]= 65.409;
560 zmat[1]= 30.;
561 //
562 wmat[0]= 0.6;
563 wmat[1]= 0.4;
564
565 //
566 density = 8.23;
567
568
569 //
570 AliMixture(33,"Brass",amat,zmat,density,2,wmat);
571
c1637e41 572 // Epoxy - C14 H20 O3
573
37831078 574 amat[0]=12.011;
575 amat[1]=1.;
576 amat[2]=15.9994;
1283eee5 577
37831078 578 zmat[0]=6.;
579 zmat[1]=1.;
580 zmat[2]=8.;
1283eee5 581
c1637e41 582 wmat[0]=14.;
583 wmat[1]=20.;
584 wmat[2]=3.;
1283eee5 585
c1637e41 586 density=1.25;
1283eee5 587
c1637e41 588 AliMixture(26,"Epoxy",amat,zmat,density,-3,wmat);
efbf94c5 589 //
6c0ba48f 590 density *= 1.1;
591 AliMixture(35,"Epoxy1",amat,zmat,density,-3,wmat);
592 //
efbf94c5 593 // epoxy film - 90% epoxy, 10% glass fiber
594 //
595 amat[0]=12.01;
596 amat[1]=1.;
597 amat[2]=15.994;
598 amat[3]=28.086;
599
600 zmat[0]=6.;
601 zmat[1]=1.;
602 zmat[2]=8.;
603 zmat[3]=14.;
604
605 wmat[0]=0.596;
606 wmat[1]=0.071;
607 wmat[2]=0.257;
608 wmat[3]=0.076;
609
610
611 density=1.345;
612
613 AliMixture(34, "Epoxy-film",amat,zmat,density,4,wmat);
1283eee5 614
c1637e41 615 // Plexiglas C5H8O2
1283eee5 616
5a28a08f 617 amat[0]=12.011;
618 amat[1]=1.;
619 amat[2]=15.9994;
620
621 zmat[0]=6.;
622 zmat[1]=1.;
623 zmat[2]=8.;
624
c1637e41 625 wmat[0]=5.;
626 wmat[1]=8.;
627 wmat[2]=2.;
5a28a08f 628
c1637e41 629 density=1.18;
5a28a08f 630
c1637e41 631 AliMixture(27,"Plexiglas",amat,zmat,density,-3,wmat);
37831078 632
ba1d05f9 633 // Carbon
634
635 amat[0]=12.011;
636 zmat[0]=6.;
637 density= 2.265;
638
c1637e41 639 AliMaterial(28,"C",amat[0],zmat[0],density,999.,999.);
ba1d05f9 640
c1637e41 641 // Fe (steel for the inner heat screen)
e4e763b9 642
c1637e41 643 amat[0]=55.845;
e4e763b9 644
c1637e41 645 zmat[0]=26.;
e4e763b9 646
c1637e41 647 density=7.87;
ba1d05f9 648
c1637e41 649 AliMaterial(29,"Fe",amat[0],zmat[0],density,999.,999.);
f4441b15 650 //
651 // Peek - (C6H4-O-OC6H4-O-C6H4-CO)n
652 amat[0]=12.011;
653 amat[1]=1.;
654 amat[2]=15.9994;
655
656 zmat[0]=6.;
657 zmat[1]=1.;
658 zmat[2]=8.;
659
660 wmat[0]=19.;
661 wmat[1]=12.;
662 wmat[2]=3.;
663 //
664 density=1.3;
665 //
666 AliMixture(30,"Peek",amat,zmat,density,-3,wmat);
667 //
668 // Ceramics - Al2O3
669 //
670 amat[0] = 26.98;
671 amat[1]= 15.9994;
672
673 zmat[0] = 13.;
674 zmat[1]=8.;
675
676 wmat[0]=2.;
677 wmat[1]=3.;
678
679 density = 3.97;
680
681 AliMixture(31,"Alumina",amat,zmat,density,-2,wmat);
682
683 //
684 // liquids
685 //
686
687 // water
688
689 amat[0]=1.;
690 amat[1]=15.9994;
691
692 zmat[0]=1.;
693 zmat[1]=8.;
694
695 wmat[0]=2.;
696 wmat[1]=1.;
697
698 density=1.;
699
700 AliMixture(32,"Water",amat,zmat,density,-2,wmat);
efbf94c5 701
ba1d05f9 702
37831078 703 //----------------------------------------------------------
704 // tracking media for gases
705 //----------------------------------------------------------
706
c1637e41 707 AliMedium(0, "Air", 11, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
a964d561 708 AliMedium(1, "DriftGas1", 12, 0, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
709 AliMedium(2, "DriftGas2", 13, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
37831078 710 AliMedium(3,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
a964d561 711 AliMedium(20, "DriftGas3", 35, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
37831078 712 //-----------------------------------------------------------
713 // tracking media for solids
714 //-----------------------------------------------------------
715
c1637e41 716 AliMedium(4,"Al",23,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
717 AliMedium(5,"Kevlar",14,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
718 AliMedium(6,"Nomex",15,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
719 AliMedium(7,"Makrolon",16,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
720 AliMedium(8,"Mylar",18,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
721 AliMedium(9,"Tedlar",17,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
722 //
723 AliMedium(10,"Prepreg1",19,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
724 AliMedium(11,"Prepreg2",20,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
725 AliMedium(12,"Prepreg3",21,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
726 AliMedium(13,"Epoxy",26,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
727
728 AliMedium(14,"Cu",25,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
729 AliMedium(15,"Si",24,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
730 AliMedium(16,"G10",22,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
731 AliMedium(17,"Plexiglas",27,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
732 AliMedium(18,"Steel",29,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
f4441b15 733 AliMedium(19,"Peek",30,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
734 AliMedium(21,"Alumina",31,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
0f788f87 735 AliMedium(22,"Water",32,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
efbf94c5 736 AliMedium(23,"Brass",33,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
6c0ba48f 737 AliMedium(24,"Epoxyfm",34,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
738 AliMedium(25,"Epoxy1",35,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
fe4da5cc 739}
740
407ff276 741void AliTPC::GenerNoise(Int_t tablesize)
742{
743 //
744 //Generate table with noise
745 //
746 if (fTPCParam==0) {
747 // error message
748 fNoiseDepth=0;
749 return;
750 }
751 if (fNoiseTable) delete[] fNoiseTable;
752 fNoiseTable = new Float_t[tablesize];
753 fNoiseDepth = tablesize;
754 fCurrentNoise =0; //!index of the noise in the noise table
755
756 Float_t norm = fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac();
757 for (Int_t i=0;i<tablesize;i++) fNoiseTable[i]= gRandom->Gaus(0,norm);
758}
759
760Float_t AliTPC::GetNoise()
761{
762 // get noise from table
763 // if ((fCurrentNoise%10)==0)
764 // fCurrentNoise= gRandom->Rndm()*fNoiseDepth;
765 if (fCurrentNoise>=fNoiseDepth) fCurrentNoise=0;
766 return fNoiseTable[fCurrentNoise++];
767 //gRandom->Gaus(0, fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac());
768}
769
770
9bdd974b 771Bool_t AliTPC::IsSectorActive(Int_t sec) const
792bb11c 772{
773 //
774 // check if the sector is active
775 if (!fActiveSectors) return kTRUE;
776 else return fActiveSectors[sec];
777}
778
779void AliTPC::SetActiveSectors(Int_t * sectors, Int_t n)
780{
781 // activate interesting sectors
88cb7938 782 SetTreeAddress();//just for security
7ed5ec98 783 if (!fActiveSectors) fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
792bb11c 784 for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kFALSE;
785 for (Int_t i=0;i<n;i++)
786 if ((sectors[i]>=0) && sectors[i]<fTPCParam->GetNSector()) fActiveSectors[sectors[i]]=kTRUE;
787
788}
789
12d8d654 790void AliTPC::SetActiveSectors(Int_t flag)
792bb11c 791{
792 //
793 // activate sectors which were hitted by tracks
794 //loop over tracks
88cb7938 795 SetTreeAddress();//just for security
792bb11c 796 if (fHitType==0) return; // if Clones hit - not short volume ID information
7ed5ec98 797 if (!fActiveSectors) fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
12d8d654 798 if (flag) {
799 for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kTRUE;
800 return;
801 }
792bb11c 802 for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kFALSE;
097d753a 803 //TBranch * branch=0;
cb5b8b21 804 if (fLoader->TreeH() == 0x0)
88cb7938 805 {
8c2b3fd7 806 AliFatal("Can not find TreeH in folder");
88cb7938 807 return;
808 }
097d753a 809 //if (fHitType>1) branch = fLoader->TreeH()->GetBranch("TPC2");
810 if (fHitType>1) fLoader->TreeH()->GetBranch("TPC2");
811 //else branch = fLoader->TreeH()->GetBranch("TPC");
812 else fLoader->TreeH()->GetBranch("TPC");
cb5b8b21 813 Stat_t ntracks = fLoader->TreeH()->GetEntries();
792bb11c 814 // loop over all hits
7d85e147 815 AliDebug(1,Form("Got %d tracks", (Int_t) ntracks));
88cb7938 816
8c2b3fd7 817 for(Int_t track=0;track<ntracks;track++) {
792bb11c 818 ResetHits();
819 //
820 if (fTrackHits && fHitType&4) {
cb5b8b21 821 TBranch * br1 = fLoader->TreeH()->GetBranch("fVolumes");
822 TBranch * br2 = fLoader->TreeH()->GetBranch("fNVolumes");
792bb11c 823 br1->GetEvent(track);
824 br2->GetEvent(track);
825 Int_t *volumes = fTrackHits->GetVolumes();
7ed5ec98 826 for (Int_t j=0;j<fTrackHits->GetNVolumes(); j++) {
e8631c7d 827 if (volumes[j]>-1 && volumes[j]<fTPCParam->GetNSector()) {
7ed5ec98 828 fActiveSectors[volumes[j]]=kTRUE;
829 }
830 else {
831 AliError(Form("Volume %d -> sector number %d is outside (0..%d)",
832 j,
833 volumes[j],
834 fTPCParam->GetNSector()));
835 }
836 }
792bb11c 837 }
838
839 //
be5ffbfe 840// if (fTrackHitsOld && fHitType&2) {
cb5b8b21 841// TBranch * br = fLoader->TreeH()->GetBranch("fTrackHitsInfo");
be5ffbfe 842// br->GetEvent(track);
843// AliObjectArray * ar = fTrackHitsOld->fTrackHitsInfo;
844// for (UInt_t j=0;j<ar->GetSize();j++){
845// fActiveSectors[((AliTrackHitsInfo*)ar->At(j))->fVolumeID] =kTRUE;
846// }
847// }
792bb11c 848 }
792bb11c 849}
850
851
852
fe4da5cc 853
0421c3d1 854//_____________________________________________________________________________
855void AliTPC::Digits2Raw()
856{
857// convert digits of the current event to raw data
858
859 static const Int_t kThreshold = 0;
0421c3d1 860
861 fLoader->LoadDigits();
862 TTree* digits = fLoader->TreeD();
863 if (!digits) {
8c2b3fd7 864 AliError("No digits tree");
0421c3d1 865 return;
866 }
867
19bbb61d 868 //
0421c3d1 869 AliSimDigits digarr;
870 AliSimDigits* digrow = &digarr;
871 digits->GetBranch("Segment")->SetAddress(&digrow);
872
873 const char* fileName = "AliTPCDDL.dat";
874 AliTPCBuffer* buffer = new AliTPCBuffer(fileName);
875 //Verbose level
876 // 0: Silent
877 // 1: cout messages
878 // 2: txt files with digits
879 //BE CAREFUL, verbose level 2 MUST be used only for debugging and
880 //it is highly suggested to use this mode only for debugging digits files
881 //reasonably small, because otherwise the size of the txt files can reach
882 //quickly several MB wasting time and disk space.
883 buffer->SetVerbose(0);
884
885 Int_t nEntries = Int_t(digits->GetEntries());
886 Int_t previousSector = -1;
887 Int_t subSector = 0;
888 for (Int_t i = 0; i < nEntries; i++) {
889 digits->GetEntry(i);
890 Int_t sector, row;
891 fTPCParam->AdjustSectorRow(digarr.GetID(), sector, row);
892 if(previousSector != sector) {
893 subSector = 0;
894 previousSector = sector;
895 }
896
897 if (sector < 36) { //inner sector [0;35]
898 if (row != 30) {
899 //the whole row is written into the output file
900 buffer->WriteRowBinary(kThreshold, digrow, 0, 0, 0,
901 sector, subSector, row);
902 } else {
903 //only the pads in the range [37;48] are written into the output file
904 buffer->WriteRowBinary(kThreshold, digrow, 37, 48, 1,
905 sector, subSector, row);
906 subSector = 1;
907 //only the pads outside the range [37;48] are written into the output file
908 buffer->WriteRowBinary(kThreshold, digrow, 37, 48, 2,
909 sector, subSector, row);
910 }//end else
911
912 } else { //outer sector [36;71]
913 if (row == 54) subSector = 2;
914 if ((row != 27) && (row != 76)) {
915 buffer->WriteRowBinary(kThreshold, digrow, 0, 0, 0,
916 sector, subSector, row);
917 } else if (row == 27) {
8c2b3fd7 918 //only the pads outside the range [43;46] are written into the output file
919 buffer->WriteRowBinary(kThreshold, digrow, 43, 46, 2,
0421c3d1 920 sector, subSector, row);
8c2b3fd7 921 subSector = 1;
922 //only the pads in the range [43;46] are written into the output file
923 buffer->WriteRowBinary(kThreshold, digrow, 43, 46, 1,
0421c3d1 924 sector, subSector, row);
925 } else if (row == 76) {
8c2b3fd7 926 //only the pads outside the range [33;88] are written into the output file
927 buffer->WriteRowBinary(kThreshold, digrow, 33, 88, 2,
928 sector, subSector, row);
929 subSector = 3;
930 //only the pads in the range [33;88] are written into the output file
931 buffer->WriteRowBinary(kThreshold, digrow, 33, 88, 1,
0421c3d1 932 sector, subSector, row);
933 }
934 }//end else
935 }//end for
936
937 delete buffer;
938 fLoader->UnloadDigits();
939
940 AliTPCDDLRawData rawWriter;
941 rawWriter.SetVerbose(0);
942
943 rawWriter.RawData(fileName);
944 gSystem->Unlink(fileName);
945
0421c3d1 946}
947
948
bc807150 949//_____________________________________________________________________________
950Bool_t AliTPC::Raw2SDigits(AliRawReader* rawReader){
951 // Converts the TPC raw data into summable digits
952 // The method is used for merging simulated and
953 // real data events
954 if (fLoader->TreeS() == 0x0 ) {
955 fLoader->MakeTree("S");
956 }
957
958 if(fDefaults == 0) SetDefaults(); // check if the parameters are set
959
960 //setup TPCDigitsArray
961 if(GetDigitsArray()) delete GetDigitsArray();
962
963 AliTPCDigitsArray *arr = new AliTPCDigitsArray;
964 arr->SetClass("AliSimDigits");
965 arr->Setup(fTPCParam);
966 arr->MakeTree(fLoader->TreeS());
967
968 SetDigitsArray(arr);
969
970 // set zero suppression to "0"
971 fTPCParam->SetZeroSup(0);
972
973 // Loop over sectors
d899e254 974 const Int_t kmaxTime = fTPCParam->GetMaxTBin();
bc807150 975 const Int_t kNIS = fTPCParam->GetNInnerSector();
976 const Int_t kNOS = fTPCParam->GetNOuterSector();
977 const Int_t kNS = kNIS + kNOS;
978
dbfbf54e 979 // Setup storage
980 AliTPCROC * roc = AliTPCROC::Instance();
981 Int_t nRowsMax = roc->GetNRows(roc->GetNSector()-1);
982 Int_t nPadsMax = roc->GetNPads(roc->GetNSector()-1,nRowsMax-1);
983 Short_t** allBins = new Short_t*[nRowsMax];
984 for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
985 Int_t maxBin = kmaxTime*nPadsMax;
986 allBins[iRow] = new Short_t[maxBin];
987 memset(allBins[iRow],0,sizeof(Short_t)*maxBin);
988 }
989
bc807150 990 for(Int_t iSector = 0; iSector < kNS; iSector++) {
991
992 Int_t nRows = fTPCParam->GetNRow(iSector);
993 Int_t nDDLs = 0, indexDDL = 0;
994 if (iSector < kNIS) {
995 nDDLs = 2;
996 indexDDL = iSector * 2;
997 }
998 else {
999 nDDLs = 4;
1000 indexDDL = (iSector-kNIS) * 4 + kNIS * 2;
1001 }
1002
dbfbf54e 1003 // Load the raw data for corresponding DDLs
bc807150 1004 rawReader->Reset();
dbfbf54e 1005
1006 AliTPCAltroMapping** mapping =AliTPCcalibDB::Instance()->GetMapping();
1007 AliTPCRawStreamV3 input(rawReader,(AliAltroMapping**)mapping);
bc807150 1008 rawReader->Select("TPC",indexDDL,indexDDL+nDDLs-1);
1009
dbfbf54e 1010 // Clean storage
1011 for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
1012 Int_t maxBin = kmaxTime*nPadsMax;
bc807150 1013 memset(allBins[iRow],0,sizeof(Short_t)*maxBin);
1014 }
1015
1016 // Begin loop over altro data
dbfbf54e 1017 while (input.NextDDL()) {
bc807150 1018
1019 if (input.GetSector() != iSector)
1020 AliFatal(Form("Sector index mismatch ! Expected (%d), but got (%d) !",iSector,input.GetSector()));
1021
dbfbf54e 1022 //loop over pads
1023 while ( input.NextChannel() ) {
1024
1025 Int_t iRow = input.GetRow();
1026 if (iRow < 0 || iRow >= nRows)
1027 AliFatal(Form("Pad-row index (%d) outside the range (%d -> %d) !",
1028 iRow, 0, nRows -1));
1029 Int_t iPad = input.GetPad();
1030
1031 Int_t maxPad = fTPCParam->GetNPads(iSector,iRow);
1032
1033 if (iPad < 0 || iPad >= maxPad)
1034 AliFatal(Form("Pad index (%d) outside the range (%d -> %d) !",
1035 iPad, 0, maxPad -1));
1036
1037 //loop over bunches
1038 while ( input.NextBunch() ){
1039 Int_t startTbin = (Int_t)input.GetStartTimeBin();
1040 Int_t bunchlength = (Int_t)input.GetBunchLength();
1041 const UShort_t *sig = input.GetSignals();
1042 for (Int_t iTime = 0; iTime<bunchlength; iTime++){
1043 Int_t iTimeBin=startTbin-iTime;
1044 if ( iTimeBin < 0 || iTimeBin >= kmaxTime) {
1045 continue;
1046 //AliFatal(Form("Timebin index (%d) outside the range (%d -> %d) !",
1047 // iTimeBin, 0, kmaxTime -1));
1048 }
1049
1050 Int_t maxBin = kmaxTime*maxPad;
1051 if (((iPad*kmaxTime+iTimeBin) >= maxBin) ||
1052 ((iPad*kmaxTime+iTimeBin) < 0))
1053 AliFatal(Form("Index outside the allowed range"
1054 " Sector=%d Row=%d Pad=%d Timebin=%d"
1055 " (Max.index=%d)",iSector,iRow,iPad,iTimeBin,maxBin));
1056 allBins[iRow][iPad*kmaxTime+iTimeBin] = sig[iTime];
1057 }
1058 }
1059 } // End loop over altro data
1060 }
bc807150 1061
bc807150 1062 // Now fill the digits array
1063 if (fDigitsArray->GetTree()==0) {
1064 AliFatal("Tree not set in fDigitsArray");
1065 }
1066
1067 for (Int_t iRow = 0; iRow < nRows; iRow++) {
1068 AliDigits * dig = fDigitsArray->CreateRow(iSector,iRow);
bc807150 1069 Int_t maxPad = fTPCParam->GetNPads(iSector,iRow);
1070 for(Int_t iPad = 0; iPad < maxPad; iPad++) {
d899e254 1071 for(Int_t iTimeBin = 0; iTimeBin < kmaxTime; iTimeBin++) {
1072 Short_t q = allBins[iRow][iPad*kmaxTime + iTimeBin];
bc807150 1073 if (q <= 0) continue;
1074 q *= 16;
1075 dig->SetDigitFast((Short_t)q,iTimeBin,iPad);
abe79c04 1076 ((AliSimDigits*)dig)->SetTrackIDFast( 3141593, iTimeBin,iPad,0);
bc807150 1077 }
1078 }
1079 fDigitsArray->StoreRow(iSector,iRow);
1080 Int_t ndig = dig->GetDigitSize();
1081
1082 AliDebug(10,
1083 Form("*** Sector, row, compressed digits %d %d %d ***\n",
1084 iSector,iRow,ndig));
1085
1086 fDigitsArray->ClearRow(iSector,iRow);
1087
1088 } // end of the sector digitization
bc807150 1089 }
19bbb61d 1090 // get LHC clock phase from the digits tree
13627b46 1091
19bbb61d 1092 TParameter<float> *ph;
13627b46 1093 Float_t phase;
1094 TTree *digtree = fLoader->TreeD();
1095 //
1096 if(digtree){ // if TreeD exists
1097 ph = (TParameter<float>*)digtree->GetUserInfo()->FindObject("lhcphase0");
1098 phase = ph->GetVal();
1099 }
1100 else{ //TreeD does not exist
1101 phase = 0.;
1102 }
19bbb61d 1103 //
1104 // store lhc clock phase in S-digits tree
1105 //
13627b46 1106 fLoader->TreeS()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",phase));
19bbb61d 1107 //
1108 fLoader->WriteSDigits("OVERWRITE");
bc807150 1109
1110 if(GetDigitsArray()) delete GetDigitsArray();
1111 SetDigitsArray(0x0);
1112
dbfbf54e 1113 // cleanup storage
1114 for (Int_t iRow = 0; iRow < nRowsMax; iRow++)
1115 delete [] allBins[iRow];
1116 delete [] allBins;
1117
bc807150 1118 return kTRUE;
1119}
0a61bf9d 1120
85a5290f 1121//______________________________________________________________________
f21fc003 1122AliDigitizer* AliTPC::CreateDigitizer(AliDigitizationInput* digInput) const
85a5290f 1123{
f21fc003 1124 return new AliTPCDigitizer(digInput);
85a5290f 1125}
0a61bf9d 1126//__
176aff27 1127void AliTPC::SDigits2Digits2(Int_t /*eventnumber*/)
0a61bf9d 1128{
1129 //create digits from summable digits
407ff276 1130 GenerNoise(500000); //create teble with noise
0a61bf9d 1131
1132 //conect tree with sSDigits
88cb7938 1133 TTree *t = fLoader->TreeS();
1134
8c2b3fd7 1135 if (t == 0x0) {
1136 fLoader->LoadSDigits("READ");
1137 t = fLoader->TreeS();
1138 if (t == 0x0) {
1139 AliError("Can not get input TreeS");
1140 return;
1141 }
1142 }
88cb7938 1143
1144 if (fLoader->TreeD() == 0x0) fLoader->MakeTree("D");
1145
0a61bf9d 1146 AliSimDigits digarr, *dummy=&digarr;
88cb7938 1147 TBranch* sdb = t->GetBranch("Segment");
8c2b3fd7 1148 if (sdb == 0x0) {
1149 AliError("Can not find branch with segments in TreeS.");
1150 return;
1151 }
88cb7938 1152
1153 sdb->SetAddress(&dummy);
1154
0a61bf9d 1155 Stat_t nentries = t->GetEntries();
1156
5f16d237 1157 // set zero suppression
1158
1159 fTPCParam->SetZeroSup(2);
1160
1161 // get zero suppression
1162
1163 Int_t zerosup = fTPCParam->GetZeroSup();
1164
1165 //make tree with digits
1166
0a61bf9d 1167 AliTPCDigitsArray *arr = new AliTPCDigitsArray;
1168 arr->SetClass("AliSimDigits");
1169 arr->Setup(fTPCParam);
88cb7938 1170 arr->MakeTree(fLoader->TreeD());
0a61bf9d 1171
88cb7938 1172 AliTPCParam * par = fTPCParam;
5f16d237 1173
0a61bf9d 1174 //Loop over segments of the TPC
5f16d237 1175
0a61bf9d 1176 for (Int_t n=0; n<nentries; n++) {
1177 t->GetEvent(n);
1178 Int_t sec, row;
1179 if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) {
8c2b3fd7 1180 AliWarning(Form("Invalid segment ID ! %d",digarr.GetID()));
0a61bf9d 1181 continue;
1182 }
8c2b3fd7 1183 if (!IsSectorActive(sec)) continue;
1184
0a61bf9d 1185 AliSimDigits * digrow =(AliSimDigits*) arr->CreateRow(sec,row);
1186 Int_t nrows = digrow->GetNRows();
1187 Int_t ncols = digrow->GetNCols();
1188
1189 digrow->ExpandBuffer();
1190 digarr.ExpandBuffer();
1191 digrow->ExpandTrackBuffer();
1192 digarr.ExpandTrackBuffer();
1193
5f16d237 1194
407ff276 1195 Short_t * pamp0 = digarr.GetDigits();
1196 Int_t * ptracks0 = digarr.GetTracks();
1197 Short_t * pamp1 = digrow->GetDigits();
1198 Int_t * ptracks1 = digrow->GetTracks();
1199 Int_t nelems =nrows*ncols;
e93a083a 1200 Int_t saturation = fTPCParam->GetADCSat() - 1;
407ff276 1201 //use internal structure of the AliDigits - for speed reason
1202 //if you cahnge implementation
1203 //of the Alidigits - it must be rewriten -
1204 for (Int_t i= 0; i<nelems; i++){
407ff276 1205 Float_t q = TMath::Nint(Float_t(*pamp0)/16.+GetNoise());
1206 if (q>zerosup){
1207 if (q>saturation) q=saturation;
1208 *pamp1=(Short_t)q;
8c2b3fd7 1209
407ff276 1210 ptracks1[0]=ptracks0[0];
1211 ptracks1[nelems]=ptracks0[nelems];
1212 ptracks1[2*nelems]=ptracks0[2*nelems];
1213 }
1214 pamp0++;
1215 pamp1++;
1216 ptracks0++;
1217 ptracks1++;
1218 }
5f16d237 1219
5f16d237 1220 arr->StoreRow(sec,row);
1221 arr->ClearRow(sec,row);
5f16d237 1222 }
0a61bf9d 1223
0a61bf9d 1224
5f16d237 1225 //write results
88cb7938 1226 fLoader->WriteDigits("OVERWRITE");
5f16d237 1227
88cb7938 1228 delete arr;
afc42102 1229}
1230//__________________________________________________________________
1231void AliTPC::SetDefaults(){
9bdd974b 1232 //
1233 // setting the defaults
1234 //
afc42102 1235
afc42102 1236 // Set response functions
1237
88cb7938 1238 //
024a7e64 1239 AliRunLoader* rl = (AliRunLoader*)fLoader->GetEventFolder()->FindObject(AliRunLoader::GetRunLoaderName());
88cb7938 1240 rl->CdGAFile();
097d753a 1241 //AliTPCParamSR *param=(AliTPCParamSR*)gDirectory->Get("75x40_100x60");
d5981cf4 1242 //gDirectory->Get("75x40_100x60");
097d753a 1243 AliTPCParamSR *param = (AliTPCParamSR*)AliTPCcalibDB::Instance()->GetParameters();
de0e19ab 1244 if(!param){
1245 AliFatal("No TPC parameters found");
d5981cf4 1246 return;
de0e19ab 1247 }
db2fdcfb 1248 if (!param->IsGeoRead()){
1249 //
1250 // read transformation matrices for gGeoManager
1251 //
1252 param->ReadGeoMatrices();
1253 }
de0e19ab 1254
7a09f434 1255
1256
2ab0c725 1257 AliTPCPRF2D * prfinner = new AliTPCPRF2D;
f03e3423 1258 AliTPCPRF2D * prfouter1 = new AliTPCPRF2D;
1259 AliTPCPRF2D * prfouter2 = new AliTPCPRF2D;
bfb1cfbd 1260
afc42102 1261
bfb1cfbd 1262 //AliTPCRF1D * rf = new AliTPCRF1D(kTRUE);
1263 //rf->SetGauss(param->GetZSigma(),param->GetZWidth(),1.);
1264 //rf->SetOffset(3*param->GetZSigma());
1265 //rf->Update();
1266 //
1267 // Use gamma 4
1268 //
1269 char strgamma4[1000];
94e6c6f4 1270 //sprintf(strgamma4,"AliTPCRF1D::Gamma4((x-0.135+%f)*%f,55,160)",3*param->GetZSigma(), 1000000000*param->GetTSample()/param->GetZWidth());
bfb1cfbd 1271
94e6c6f4 1272 snprintf(strgamma4,1000,"AliTPCRF1D::Gamma4((x-0.135+%f)*%f,55,160)",3*param->GetZSigma(), 1000000000*param->GetTSample()/param->GetZWidth());
bfb1cfbd 1273 TF1 * fgamma4 = new TF1("fgamma4",strgamma4, -1,1);
1274 AliTPCRF1D * rf = new AliTPCRF1D(kTRUE,1000);
1275 rf->SetParam(fgamma4,param->GetZWidth(), 1,0.2);
1276 rf->SetOffset(3*param->GetZSigma());
1277 rf->Update();
afc42102 1278 TDirectory *savedir=gDirectory;
a120cd1d 1279
1280 if (fIsGEM==0){
1281 printf ("TPC MWPC readout\n");
1282 TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
1283 if (!f->IsOpen())
1284 AliFatal("Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !");
1285
1286 TString s;
1287 prfinner->Read("prf_07504_Gati_056068_d02");
1288 //PH Set different names
1289 s=prfinner->GetGRF()->GetName();
1290 s+="in";
1291 prfinner->GetGRF()->SetName(s.Data());
1292
1293 prfouter1->Read("prf_10006_Gati_047051_d03");
1294 s=prfouter1->GetGRF()->GetName();
1295 s+="out1";
1296 prfouter1->GetGRF()->SetName(s.Data());
1297
1298 prfouter2->Read("prf_15006_Gati_047051_d03");
1299 s=prfouter2->GetGRF()->GetName();
1300 s+="out2";
1301 prfouter2->GetGRF()->SetName(s.Data());
1302 f->Close();
1303 }
1304
1305 if (fIsGEM==1){
1306 printf ("TPC GEM readout\n");
1307 TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2dGEM.root");
1308 if (!f->IsOpen())
1309 AliFatal("Can't open $ALICE_ROOT/TPC/AliTPCprf2dGEM.root !");
1310
1311 TString s;
1312 prfinner->Read("prf0");
1313 //PH Set different names
1314 s=prfinner->GetGRF()->GetName();
1315 s+="in";
1316 prfinner->GetGRF()->SetName(s.Data());
1317
1318 prfouter1->Read("prf1");
1319 s=prfouter1->GetGRF()->GetName();
1320 s+="out1";
1321 prfouter1->GetGRF()->SetName(s.Data());
1322
1323 prfouter2->Read("prf2");
1324 s=prfouter2->GetGRF()->GetName();
1325 s+="out2";
1326 prfouter2->GetGRF()->SetName(s.Data());
1327 f->Close();
1328 }
afc42102 1329 savedir->cd();
1330
2ab0c725 1331 param->SetInnerPRF(prfinner);
f03e3423 1332 param->SetOuter1PRF(prfouter1);
1333 param->SetOuter2PRF(prfouter2);
2ab0c725 1334 param->SetTimeRF(rf);
1335
afc42102 1336 // set fTPCParam
1337
2ab0c725 1338 SetParam(param);
1339
afc42102 1340
1341 fDefaults = 1;
1342
1343}
1344//__________________________________________________________________
85a5290f 1345void AliTPC::Hits2Digits()
1346{
9bdd974b 1347 //
1348 // creates digits from hits
1349 //
506e60a6 1350 if (!fTPCParam->IsGeoRead()){
1351 //
1352 // read transformation matrices for gGeoManager
1353 //
1354 fTPCParam->ReadGeoMatrices();
1355 }
9bdd974b 1356
85a5290f 1357 fLoader->LoadHits("read");
1358 fLoader->LoadDigits("recreate");
1359 AliRunLoader* runLoader = fLoader->GetRunLoader();
1360
1361 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
7ed5ec98 1362 //PH runLoader->GetEvent(iEvent);
85a5290f 1363 Hits2Digits(iEvent);
1364 }
1365
1366 fLoader->UnloadHits();
1367 fLoader->UnloadDigits();
1368}
1369//__________________________________________________________________
afc42102 1370void AliTPC::Hits2Digits(Int_t eventnumber)
1371{
1372 //----------------------------------------------------
1373 // Loop over all sectors for a single event
1374 //----------------------------------------------------
024a7e64 1375 AliRunLoader* rl = (AliRunLoader*)fLoader->GetEventFolder()->FindObject(AliRunLoader::GetRunLoaderName());
88cb7938 1376 rl->GetEvent(eventnumber);
6db60b71 1377 SetActiveSectors();
8c2b3fd7 1378 if (fLoader->TreeH() == 0x0) {
1379 if(fLoader->LoadHits()) {
1380 AliError("Can not load hits.");
1381 }
1382 }
88cb7938 1383 SetTreeAddress();
1384
8c2b3fd7 1385 if (fLoader->TreeD() == 0x0 ) {
1386 fLoader->MakeTree("D");
1387 if (fLoader->TreeD() == 0x0 ) {
1388 AliError("Can not get TreeD");
1389 return;
1390 }
1391 }
afc42102 1392
1393 if(fDefaults == 0) SetDefaults(); // check if the parameters are set
407ff276 1394 GenerNoise(500000); //create teble with noise
2ab0c725 1395
1396 //setup TPCDigitsArray
afc42102 1397
1398 if(GetDigitsArray()) delete GetDigitsArray();
8c2b3fd7 1399
2ab0c725 1400 AliTPCDigitsArray *arr = new AliTPCDigitsArray;
1401 arr->SetClass("AliSimDigits");
afc42102 1402 arr->Setup(fTPCParam);
88cb7938 1403
1404 arr->MakeTree(fLoader->TreeD());
2ab0c725 1405 SetDigitsArray(arr);
1406
afc42102 1407 fDigitsSwitch=0; // standard digits
f546a4b4 1408 // here LHC clock phase
1409 Float_t lhcph = 0.;
1410 switch (fLHCclockPhaseSw){
1411 case 0:
1412 // no phase
1413 lhcph=0.;
1414 break;
1415 case 1:
1416 // random phase
1417 lhcph = (Int_t)(gRandom->Rndm()/0.25);
1418 break;
1419 case 2:
1420 lhcph=0.;
1421 // not implemented yet
1422 break;
1423 }
1424 // adding phase to the TreeD user info
1425 fLoader->TreeD()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",lhcph));
1426 //
8c2b3fd7 1427 for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++)
1428 if (IsSectorActive(isec)) {
7d85e147 1429 AliDebug(1,Form("Hits2Digits: Sector %d is active.",isec));
8c2b3fd7 1430 Hits2DigitsSector(isec);
1431 }
1432 else {
7d85e147 1433 AliDebug(1,Form("Hits2Digits: Sector %d is NOT active.",isec));
8c2b3fd7 1434 }
1435
88cb7938 1436 fLoader->WriteDigits("OVERWRITE");
f2a509af 1437
1438//this line prevents the crash in the similar one
1439//on the beginning of this method
1440//destructor attempts to reset the tree, which is deleted by the loader
1441//need to be redesign
8c2b3fd7 1442 if(GetDigitsArray()) delete GetDigitsArray();
1443 SetDigitsArray(0x0);
f2a509af 1444
8c555625 1445}
1446
f8cf550c 1447//__________________________________________________________________
0a61bf9d 1448void AliTPC::Hits2SDigits2(Int_t eventnumber)
f8cf550c 1449{
1450
1451 //-----------------------------------------------------------
1452 // summable digits - 16 bit "ADC", no noise, no saturation
1453 //-----------------------------------------------------------
1454
8c2b3fd7 1455 //----------------------------------------------------
1456 // Loop over all sectors for a single event
1457 //----------------------------------------------------
88cb7938 1458
1459 AliRunLoader* rl = fLoader->GetRunLoader();
1460
1461 rl->GetEvent(eventnumber);
8c2b3fd7 1462 if (fLoader->TreeH() == 0x0) {
1463 if(fLoader->LoadHits()) {
1464 AliError("Can not load hits.");
1465 return;
1466 }
1467 }
88cb7938 1468 SetTreeAddress();
f8cf550c 1469
afc42102 1470
8c2b3fd7 1471 if (fLoader->TreeS() == 0x0 ) {
1472 fLoader->MakeTree("S");
1473 }
88cb7938 1474
afc42102 1475 if(fDefaults == 0) SetDefaults();
88cb7938 1476
407ff276 1477 GenerNoise(500000); //create table with noise
afc42102 1478 //setup TPCDigitsArray
1479
1480 if(GetDigitsArray()) delete GetDigitsArray();
1481
88cb7938 1482
afc42102 1483 AliTPCDigitsArray *arr = new AliTPCDigitsArray;
1484 arr->SetClass("AliSimDigits");
1485 arr->Setup(fTPCParam);
88cb7938 1486 arr->MakeTree(fLoader->TreeS());
1487
afc42102 1488 SetDigitsArray(arr);
1489
afc42102 1490 fDigitsSwitch=1; // summable digits
5f16d237 1491
1492 // set zero suppression to "0"
f546a4b4 1493 // here LHC clock phase
1494 Float_t lhcph = 0.;
1495 switch (fLHCclockPhaseSw){
1496 case 0:
1497 // no phase
1498 lhcph=0.;
1499 break;
1500 case 1:
1501 // random phase
1502 lhcph = (Int_t)(gRandom->Rndm()/0.25);
1503 break;
1504 case 2:
1505 lhcph=0.;
1506 // not implemented yet
1507 break;
1508 }
1509 // adding phase to the TreeS user info
1510
1511 fLoader->TreeS()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",lhcph));
5f16d237 1512
1513 fTPCParam->SetZeroSup(0);
f8cf550c 1514
8c2b3fd7 1515 for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++)
1516 if (IsSectorActive(isec)) {
1517 Hits2DigitsSector(isec);
1518 }
88cb7938 1519
8c2b3fd7 1520 fLoader->WriteSDigits("OVERWRITE");
88cb7938 1521
1522//this line prevents the crash in the similar one
1523//on the beginning of this method
1524//destructor attempts to reset the tree, which is deleted by the loader
1525//need to be redesign
8c2b3fd7 1526 if(GetDigitsArray()) delete GetDigitsArray();
1527 SetDigitsArray(0x0);
f8cf550c 1528}
0a61bf9d 1529//__________________________________________________________________
88cb7938 1530
0a61bf9d 1531void AliTPC::Hits2SDigits()
1532{
1533
1534 //-----------------------------------------------------------
1535 // summable digits - 16 bit "ADC", no noise, no saturation
1536 //-----------------------------------------------------------
1537
506e60a6 1538 if (!fTPCParam->IsGeoRead()){
1539 //
1540 // read transformation matrices for gGeoManager
1541 //
1542 fTPCParam->ReadGeoMatrices();
1543 }
1544
85a5290f 1545 fLoader->LoadHits("read");
1546 fLoader->LoadSDigits("recreate");
1547 AliRunLoader* runLoader = fLoader->GetRunLoader();
0a61bf9d 1548
85a5290f 1549 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1550 runLoader->GetEvent(iEvent);
1551 SetTreeAddress();
1552 SetActiveSectors();
1553 Hits2SDigits2(iEvent);
1554 }
f546a4b4 1555
85a5290f 1556 fLoader->UnloadHits();
1557 fLoader->UnloadSDigits();
23effa8e 1558 if (fDebugStreamer) {
1559 delete fDebugStreamer;
1560 fDebugStreamer=0;
1561 }
0a61bf9d 1562}
fe4da5cc 1563//_____________________________________________________________________________
88cb7938 1564
8c555625 1565void AliTPC::Hits2DigitsSector(Int_t isec)
fe4da5cc 1566{
8c555625 1567 //-------------------------------------------------------------------
fe4da5cc 1568 // TPC conversion from hits to digits.
8c555625 1569 //-------------------------------------------------------------------
1570
1571 //-----------------------------------------------------------------
1572 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1573 //-----------------------------------------------------------------
1574
fe4da5cc 1575 //-------------------------------------------------------
8c555625 1576 // Get the access to the track hits
fe4da5cc 1577 //-------------------------------------------------------
8c555625 1578
afc42102 1579 // check if the parameters are set - important if one calls this method
1580 // directly, not from the Hits2Digits
1581
1582 if(fDefaults == 0) SetDefaults();
cc80f89e 1583
cb5b8b21 1584 TTree *tH = fLoader->TreeH(); // pointer to the hits tree
8c2b3fd7 1585 if (tH == 0x0) {
1586 AliFatal("Can not find TreeH in folder");
1587 return;
1588 }
88cb7938 1589
73042f01 1590 Stat_t ntracks = tH->GetEntries();
8c555625 1591
8c2b3fd7 1592 Int_t nrows =fTPCParam->GetNRow(isec);
8c555625 1593
606d6545 1594 TObjArray **row=new TObjArray* [nrows+2]; // 2 extra rows for cross talk
1595 for(Int_t j=0;j<nrows+2;j++) row[j]=0;
fe4da5cc 1596
8c2b3fd7 1597 MakeSector(isec,nrows,tH,ntracks,row);
8c555625 1598
8c2b3fd7 1599 //--------------------------------------------------------
1600 // Digitize this sector, row by row
1601 // row[i] is the pointer to the TObjArray of TVectors,
1602 // each one containing electrons accepted on this
1603 // row, assigned into tracks
1604 //--------------------------------------------------------
8c555625 1605
8c2b3fd7 1606 Int_t i;
8c555625 1607
8c2b3fd7 1608 if (fDigitsArray->GetTree()==0) {
1609 AliFatal("Tree not set in fDigitsArray");
1610 }
8c555625 1611
8c2b3fd7 1612 for (i=0;i<nrows;i++){
1613
1614 AliDigits * dig = fDigitsArray->CreateRow(isec,i);
8c555625 1615
8c2b3fd7 1616 DigitizeRow(i,isec,row);
8c555625 1617
8c2b3fd7 1618 fDigitsArray->StoreRow(isec,i);
8c555625 1619
8c2b3fd7 1620 Int_t ndig = dig->GetDigitSize();
88cb7938 1621
8c2b3fd7 1622 AliDebug(10,
1623 Form("*** Sector, row, compressed digits %d %d %d ***\n",
1624 isec,i,ndig));
792bb11c 1625
8c2b3fd7 1626 fDigitsArray->ClearRow(isec,i);
8c555625 1627
cc80f89e 1628
8c2b3fd7 1629 } // end of the sector digitization
8c555625 1630
8c2b3fd7 1631 for(i=0;i<nrows+2;i++){
1632 row[i]->Delete();
1633 delete row[i];
1634 }
cc80f89e 1635
8c2b3fd7 1636 delete [] row; // delete the array of pointers to TObjArray-s
8c555625 1637
8c555625 1638
cc80f89e 1639} // end of Hits2DigitsSector
8c555625 1640
8c555625 1641
8c555625 1642//_____________________________________________________________________________
cc80f89e 1643void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows)
8c555625 1644{
1645 //-----------------------------------------------------------
1646 // Single row digitization, coupling from the neighbouring
1647 // rows taken into account
1648 //-----------------------------------------------------------
1649
1650 //-----------------------------------------------------------------
1651 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
cc80f89e 1652 // Modified: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
8c555625 1653 //-----------------------------------------------------------------
1654
8c555625 1655 Float_t zerosup = fTPCParam->GetZeroSup();
28c55807 1656 AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetDedxGainFactor();
1657 AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
1658 AliTPCCalROC * gainROC = gainTPC->GetCalROC(isec); // pad gains per given sector
1659 AliTPCCalROC * noiseROC = noiseTPC->GetCalROC(isec); // noise per given sector
1660
8c2b3fd7 1661
cc80f89e 1662 fCurrentIndex[1]= isec;
8c555625 1663
8c555625 1664
73042f01 1665 Int_t nofPads = fTPCParam->GetNPads(isec,irow);
1666 Int_t nofTbins = fTPCParam->GetMaxTBin();
1667 Int_t indexRange[4];
8c555625 1668 //
1669 // Integrated signal for this row
1670 // and a single track signal
cc80f89e 1671 //
de61d5d5 1672
e8d02863 1673 TMatrixF *m1 = new TMatrixF(0,nofPads,0,nofTbins); // integrated
1674 TMatrixF *m2 = new TMatrixF(0,nofPads,0,nofTbins); // single
8c555625 1675 //
e8d02863 1676 TMatrixF &total = *m1;
8c555625 1677
1678 // Array of pointers to the label-signal list
1679
73042f01 1680 Int_t nofDigits = nofPads*nofTbins; // number of digits for this row
1681 Float_t **pList = new Float_t* [nofDigits];
8c555625 1682
1683 Int_t lp;
cc80f89e 1684 Int_t i1;
73042f01 1685 for(lp=0;lp<nofDigits;lp++)pList[lp]=0; // set all pointers to NULL
8c555625 1686 //
cc80f89e 1687 //calculate signal
1688 //
b584c7dd 1689 Int_t row1=irow;
1690 Int_t row2=irow+2;
cc80f89e 1691 for (Int_t row= row1;row<=row2;row++){
1692 Int_t nTracks= rows[row]->GetEntries();
1693 for (i1=0;i1<nTracks;i1++){
1694 fCurrentIndex[2]= row;
b584c7dd 1695 fCurrentIndex[3]=irow+1;
1696 if (row==irow+1){
cc80f89e 1697 m2->Zero(); // clear single track signal matrix
73042f01 1698 Float_t trackLabel = GetSignal(rows[row],i1,m2,m1,indexRange);
1699 GetList(trackLabel,nofPads,m2,indexRange,pList);
cc80f89e 1700 }
73042f01 1701 else GetSignal(rows[row],i1,0,m1,indexRange);
cc80f89e 1702 }
8c555625 1703 }
cc80f89e 1704
8c555625 1705 Int_t tracks[3];
8c555625 1706
cc80f89e 1707 AliDigits *dig = fDigitsArray->GetRow(isec,irow);
de61d5d5 1708 Int_t gi=-1;
1709 Float_t fzerosup = zerosup+0.5;
1710 for(Int_t it=0;it<nofTbins;it++){
de61d5d5 1711 for(Int_t ip=0;ip<nofPads;ip++){
1712 gi++;
8c2b3fd7 1713 Float_t q=total(ip,it);
28c55807 1714 if(fDigitsSwitch == 0){
1715 Float_t gain = gainROC->GetValue(irow,ip); // get gain for given - pad-row pad
1716 Float_t noisePad = noiseROC->GetValue(irow,ip);
1717 //
1718 q*=gain;
1719 q+=GetNoise()*noisePad;
de61d5d5 1720 if(q <=fzerosup) continue; // do not fill zeros
68771f83 1721 q = TMath::Nint(q);
e93a083a 1722 if(q >= fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat() - 1; // saturation
cc80f89e 1723
f8cf550c 1724 }
1725
1726 else {
8c2b3fd7 1727 if(q <= 0.) continue; // do not fill zeros
1728 if(q>2000.) q=2000.;
1729 q *= 16.;
1730 q = TMath::Nint(q);
f8cf550c 1731 }
8c555625 1732
1733 //
1734 // "real" signal or electronic noise (list = -1)?
1735 //
1736
1737 for(Int_t j1=0;j1<3;j1++){
407ff276 1738 tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -2;
8c555625 1739 }
1740
cc80f89e 1741//Begin_Html
1742/*
1743 <A NAME="AliDigits"></A>
1744 using of AliDigits object
1745*/
1746//End_Html
1747 dig->SetDigitFast((Short_t)q,it,ip);
8c2b3fd7 1748 if (fDigitsArray->IsSimulated()) {
1749 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[0],it,ip,0);
1750 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[1],it,ip,1);
1751 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[2],it,ip,2);
1752 }
8c555625 1753
1754 } // end of loop over time buckets
1755 } // end of lop over pads
58c45a5e 1756 //
1757 // test
1758 //
1759 //
8c555625 1760
58c45a5e 1761 // glitch filters if normal simulated digits
1762 //
1763 if(!fDigitsSwitch) ((AliSimDigits*)dig)->GlitchFilter();
8c555625 1764 //
1765 // This row has been digitized, delete nonused stuff
1766 //
1767
73042f01 1768 for(lp=0;lp<nofDigits;lp++){
8c555625 1769 if(pList[lp]) delete [] pList[lp];
1770 }
1771
1772 delete [] pList;
1773
1774 delete m1;
1775 delete m2;
8c555625 1776
1777} // end of DigitizeRow
cc80f89e 1778
8c555625 1779//_____________________________________________________________________________
cc80f89e 1780
de61d5d5 1781Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr,
e8d02863 1782 TMatrixF *m1, TMatrixF *m2,Int_t *indexRange)
8c555625 1783{
1784
1785 //---------------------------------------------------------------
1786 // Calculates 2-D signal (pad,time) for a single track,
1787 // returns a pointer to the signal matrix and the track label
1788 // No digitization is performed at this level!!!
1789 //---------------------------------------------------------------
1790
1791 //-----------------------------------------------------------------
1792 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
cc80f89e 1793 // Modified: Marian Ivanov
8c555625 1794 //-----------------------------------------------------------------
1795
8c2b3fd7 1796 TVector *tv;
de61d5d5 1797
8c2b3fd7 1798 tv = (TVector*)p1->At(ntr); // pointer to a track
1799 TVector &v = *tv;
8c555625 1800
1801 Float_t label = v(0);
506e60a6 1802 Int_t centralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3]-1))/2;
8c555625 1803
e61fd20d 1804 Int_t nElectrons = (tv->GetNrows()-1)/5;
73042f01 1805 indexRange[0]=9999; // min pad
1806 indexRange[1]=-1; // max pad
1807 indexRange[2]=9999; //min time
1808 indexRange[3]=-1; // max time
8c555625 1809
e8d02863 1810 TMatrixF &signal = *m1;
1811 TMatrixF &total = *m2;
8c555625 1812 //
f546a4b4 1813 // Get LHC clock phase
1814 //
1815 TParameter<float> *ph;
1816 if(fDigitsSwitch){// s-digits
1817 ph = (TParameter<float>*)fLoader->TreeS()->GetUserInfo()->FindObject("lhcphase0");
1818 }
1819 else{ // normal digits
1820 ph = (TParameter<float>*)fLoader->TreeD()->GetUserInfo()->FindObject("lhcphase0");
1821 }
8c555625 1822 // Loop over all electrons
1823 //
8c555625 1824 for(Int_t nel=0; nel<nElectrons; nel++){
e61fd20d 1825 Int_t idx=nel*5;
cc80f89e 1826 Float_t aval = v(idx+4);
1827 Float_t eltoadcfac=aval*fTPCParam->GetTotalNormFac();
e61fd20d 1828 Float_t xyz[4]={v(idx+1),v(idx+2),v(idx+3),v(idx+5)};
f546a4b4 1829 Int_t n = ((AliTPCParamSR*)fTPCParam)->CalcResponseFast(xyz,fCurrentIndex,
1830 fCurrentIndex[3],ph->GetVal());
de61d5d5 1831
1832 Int_t *index = fTPCParam->GetResBin(0);
1833 Float_t *weight = & (fTPCParam->GetResWeight(0));
1834
1835 if (n>0) for (Int_t i =0; i<n; i++){
e30e6a9c 1836 Int_t pad=index[1]+centralPad; //in digit coordinates central pad has coordinate 0
8c2b3fd7 1837
1838 if (pad>=0){
1839 Int_t time=index[2];
1840 Float_t qweight = *(weight)*eltoadcfac;
1841
1842 if (m1!=0) signal(pad,time)+=qweight;
1843 total(pad,time)+=qweight;
1844 if (indexRange[0]>pad) indexRange[0]=pad;
1845 if (indexRange[1]<pad) indexRange[1]=pad;
1846 if (indexRange[2]>time) indexRange[2]=time;
1847 if (indexRange[3]<time) indexRange[3]=time;
1848
1849 index+=3;
1850 weight++;
1851
1852 }
cc80f89e 1853 }
8c555625 1854 } // end of loop over electrons
cc80f89e 1855
8c555625 1856 return label; // returns track label when finished
1857}
1858
1859//_____________________________________________________________________________
e8d02863 1860void AliTPC::GetList(Float_t label,Int_t np,TMatrixF *m,
de61d5d5 1861 Int_t *indexRange, Float_t **pList)
8c555625 1862{
1863 //----------------------------------------------------------------------
1864 // Updates the list of tracks contributing to digits for a given row
1865 //----------------------------------------------------------------------
1866
1867 //-----------------------------------------------------------------
1868 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1869 //-----------------------------------------------------------------
1870
e8d02863 1871 TMatrixF &signal = *m;
8c555625 1872
1873 // lop over nonzero digits
1874
73042f01 1875 for(Int_t it=indexRange[2];it<indexRange[3]+1;it++){
1876 for(Int_t ip=indexRange[0];ip<indexRange[1]+1;ip++){
8c555625 1877
1878
8c2b3fd7 1879 // accept only the contribution larger than 500 electrons (1/2 s_noise)
921bf71a 1880
8c2b3fd7 1881 if(signal(ip,it)<0.5) continue;
921bf71a 1882
8c2b3fd7 1883 Int_t globalIndex = it*np+ip; // globalIndex starts from 0!
8c555625 1884
8c2b3fd7 1885 if(!pList[globalIndex]){
8c555625 1886
8c2b3fd7 1887 //
1888 // Create new list (6 elements - 3 signals and 3 labels),
1889 //
8c555625 1890
8c2b3fd7 1891 pList[globalIndex] = new Float_t [6];
8c555625 1892
8c2b3fd7 1893 // set list to -1
1894
1895 *pList[globalIndex] = -1.;
1896 *(pList[globalIndex]+1) = -1.;
1897 *(pList[globalIndex]+2) = -1.;
1898 *(pList[globalIndex]+3) = -1.;
1899 *(pList[globalIndex]+4) = -1.;
1900 *(pList[globalIndex]+5) = -1.;
1901
1902 *pList[globalIndex] = label;
1903 *(pList[globalIndex]+3) = signal(ip,it);
1904 }
1905 else {
8c555625 1906
8c2b3fd7 1907 // check the signal magnitude
8c555625 1908
8c2b3fd7 1909 Float_t highest = *(pList[globalIndex]+3);
1910 Float_t middle = *(pList[globalIndex]+4);
1911 Float_t lowest = *(pList[globalIndex]+5);
1912
1913 //
1914 // compare the new signal with already existing list
1915 //
1916
1917 if(signal(ip,it)<lowest) continue; // neglect this track
8c555625 1918
8c2b3fd7 1919 //
8c555625 1920
8c2b3fd7 1921 if (signal(ip,it)>highest){
1922 *(pList[globalIndex]+5) = middle;
1923 *(pList[globalIndex]+4) = highest;
1924 *(pList[globalIndex]+3) = signal(ip,it);
1925
1926 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
1927 *(pList[globalIndex]+1) = *pList[globalIndex];
1928 *pList[globalIndex] = label;
1929 }
1930 else if (signal(ip,it)>middle){
1931 *(pList[globalIndex]+5) = middle;
1932 *(pList[globalIndex]+4) = signal(ip,it);
1933
1934 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
1935 *(pList[globalIndex]+1) = label;
1936 }
1937 else{
1938 *(pList[globalIndex]+5) = signal(ip,it);
1939 *(pList[globalIndex]+2) = label;
1940 }
1941 }
1942
8c555625 1943 } // end of loop over pads
1944 } // end of loop over time bins
1945
8c555625 1946}//end of GetList
1947//___________________________________________________________________
1948void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
1949 Stat_t ntracks,TObjArray **row)
1950{
1951
1952 //-----------------------------------------------------------------
1953 // Prepares the sector digitization, creates the vectors of
1954 // tracks for each row of this sector. The track vector
1955 // contains the track label and the position of electrons.
1956 //-----------------------------------------------------------------
1957
79fa3dc8 1958 //
1959 // The trasport of the electrons through TPC drift volume
1960 // Drift (drift velocity + velocity map(not yet implemented)))
1961 // Application of the random processes (diffusion, gas gain)
1962 // Systematic effects (ExB effect in drift volume + ROCs)
1963 //
1964 // Algorithm:
1965 // Loop over primary electrons:
1966 // Creation of the secondary electrons
1967 // Loop over electrons (primary+ secondaries)
1968 // Global coordinate frame:
1969 // 1. Skip electrons if attached
1970 // 2. ExB effect in drift volume
1971 // a.) Simulation calib->GetExB()->CorrectInverse(dxyz0,dxyz1);
1972 // b.) Reconstruction - calib->GetExB()->CorrectInverse(dxyz0,dxyz1);
1973 // 3. Generation of gas gain (Random - Exponential distribution)
1974 // 4. TransportElectron function (diffusion)
1975 //
1976 // 5. Conversion to the local coordinate frame pad-row, pad, timebin
1977 // 6. Apply Time0 shift - AliTPCCalPad class
1978 // a.) Plus sign in simulation
1979 // b.) Minus sign in reconstruction
1980 // end of loop
1981 //
8c555625 1982 //-----------------------------------------------------------------
1983 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
79fa3dc8 1984 // Origin: Marian Ivanov, marian.ivanov@cern.ch
8c555625 1985 //-----------------------------------------------------------------
79fa3dc8 1986 AliTPCcalibDB* const calib=AliTPCcalibDB::Instance();
7bab76cf 1987 if (gAlice){ // Set correctly the magnetic field in the ExB calculation
9ac65c7c 1988 if (!calib->GetExB()){
1989 AliMagF * field = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField());
1990 if (field) {
1991 calib->SetExBField(field);
1992 }
7bab76cf 1993 }
1994 }
8c555625 1995
cc80f89e 1996 Float_t gasgain = fTPCParam->GetGasGain();
8261c673 1997 gasgain = gasgain/fGainFactor;
8c555625 1998 Int_t i;
e61fd20d 1999 Float_t xyz[5];
8c555625 2000
2001 AliTPChit *tpcHit; // pointer to a sigle TPC hit
39c8eb58 2002 //MI change
2003 TBranch * branch=0;
792bb11c 2004 if (fHitType>1) branch = TH->GetBranch("TPC2");
39c8eb58 2005 else branch = TH->GetBranch("TPC");
2006
8c555625 2007
2008 //----------------------------------------------
2009 // Create TObjArray-s, one for each row,
8c2b3fd7 2010 // each TObjArray will store the TVectors
2011 // of electrons, one TVectors per each track.
8c555625 2012 //----------------------------------------------
2013
b584c7dd 2014 Int_t *nofElectrons = new Int_t [nrows+2]; // electron counter for each row
8c2b3fd7 2015 TVector **tracks = new TVector* [nrows+2]; //pointers to the track vectors
de61d5d5 2016
b584c7dd 2017 for(i=0; i<nrows+2; i++){
8c555625 2018 row[i] = new TObjArray;
f74bb6f5 2019 nofElectrons[i]=0;
2020 tracks[i]=0;
8c555625 2021 }
8c555625 2022
37831078 2023
2024
8c555625 2025 //--------------------------------------------------------------------
2026 // Loop over tracks, the "track" contains the full history
2027 //--------------------------------------------------------------------
8c2b3fd7 2028
8c555625 2029 Int_t previousTrack,currentTrack;
2030 previousTrack = -1; // nothing to store so far!
2031
2032 for(Int_t track=0;track<ntracks;track++){
39c8eb58 2033 Bool_t isInSector=kTRUE;
8c555625 2034 ResetHits();
792bb11c 2035 isInSector = TrackInVolume(isec,track);
39c8eb58 2036 if (!isInSector) continue;
2037 //MI change
2038 branch->GetEntry(track); // get next track
8c2b3fd7 2039
39c8eb58 2040 //M.I. changes
8c555625 2041
39c8eb58 2042 tpcHit = (AliTPChit*)FirstHit(-1);
8c555625 2043
2044 //--------------------------------------------------------------
2045 // Loop over hits
2046 //--------------------------------------------------------------
2047
8c555625 2048
39c8eb58 2049 while(tpcHit){
8c555625 2050
2051 Int_t sector=tpcHit->fSector; // sector number
39c8eb58 2052 if(sector != isec){
2053 tpcHit = (AliTPChit*) NextHit();
2054 continue;
2055 }
8c555625 2056
daf14717 2057 // Remove hits which arrive before the TPC opening gate signal
a1ec4d07 2058 if(((fTPCParam->GetZLength(isec)-TMath::Abs(tpcHit->Z()))
daf14717 2059 /fTPCParam->GetDriftV()+tpcHit->Time())<fTPCParam->GetGateDelay()) {
2060 tpcHit = (AliTPChit*) NextHit();
2061 continue;
2062 }
2063
8c2b3fd7 2064 currentTrack = tpcHit->Track(); // track number
39c8eb58 2065
8c2b3fd7 2066 if(currentTrack != previousTrack){
8c555625 2067
8c2b3fd7 2068 // store already filled fTrack
8c555625 2069
8c2b3fd7 2070 for(i=0;i<nrows+2;i++){
2071 if(previousTrack != -1){
2072 if(nofElectrons[i]>0){
2073 TVector &v = *tracks[i];
2074 v(0) = previousTrack;
e61fd20d 2075 tracks[i]->ResizeTo(5*nofElectrons[i]+1); // shrink if necessary
8c2b3fd7 2076 row[i]->Add(tracks[i]);
2077 }
2078 else {
2079 delete tracks[i]; // delete empty TVector
2080 tracks[i]=0;
2081 }
2082 }
2083
2084 nofElectrons[i]=0;
e61fd20d 2085 tracks[i] = new TVector(601); // TVectors for the next fTrack
8c2b3fd7 2086
2087 } // end of loop over rows
8c555625 2088
8c2b3fd7 2089 previousTrack=currentTrack; // update track label
2090 }
8c555625 2091
8c2b3fd7 2092 Int_t qI = (Int_t) (tpcHit->fQ); // energy loss (number of electrons)
8c555625 2093
8c2b3fd7 2094 //---------------------------------------------------
2095 // Calculate the electron attachment probability
2096 //---------------------------------------------------
8c555625 2097
cc80f89e 2098
a1ec4d07 2099 Float_t time = 1.e6*(fTPCParam->GetZLength(isec)-TMath::Abs(tpcHit->Z()))
8c2b3fd7 2100 /fTPCParam->GetDriftV();
2101 // in microseconds!
2102 Float_t attProb = fTPCParam->GetAttCoef()*
2103 fTPCParam->GetOxyCont()*time; // fraction!
8c555625 2104
8c2b3fd7 2105 //-----------------------------------------------
2106 // Loop over electrons
2107 //-----------------------------------------------
2108 Int_t index[3];
2109 index[1]=isec;
2110 for(Int_t nel=0;nel<qI;nel++){
2111 // skip if electron lost due to the attachment
2112 if((gRandom->Rndm(0)) < attProb) continue; // electron lost!
79fa3dc8 2113
2114 //
2115 // ExB effect
2116 //
2117 Double_t dxyz0[3],dxyz1[3];
2118 dxyz0[0]=tpcHit->X();
2119 dxyz0[1]=tpcHit->Y();
2120 dxyz0[2]=tpcHit->Z();
2121 if (calib->GetExB()){
2122 calib->GetExB()->CorrectInverse(dxyz0,dxyz1);
2123 }else{
2124 AliError("Not valid ExB calibration");
2125 dxyz1[0]=tpcHit->X();
2126 dxyz1[1]=tpcHit->Y();
2127 dxyz1[2]=tpcHit->Z();
2128 }
2129 xyz[0]=dxyz1[0];
2130 xyz[1]=dxyz1[1];
2131 xyz[2]=dxyz1[2];
2132 //
2133 //
8c2b3fd7 2134 //
2135 // protection for the nonphysical avalanche size (10**6 maximum)
2136 //
2137 Double_t rn=TMath::Max(gRandom->Rndm(0),1.93e-22);
2138 xyz[3]= (Float_t) (-gasgain*TMath::Log(rn));
2139 index[0]=1;
79fa3dc8 2140
8c2b3fd7 2141 TransportElectron(xyz,index);
2142 Int_t rowNumber;
23effa8e 2143 Int_t padrow = fTPCParam->GetPadRow(xyz,index);
79fa3dc8 2144 //
2145 // Add Time0 correction due unisochronity
2146 // xyz[0] - pad row coordinate
2147 // xyz[1] - pad coordinate
2148 // xyz[2] - is in now time bin coordinate system
2149 Float_t correction =0;
2150 if (calib->GetPadTime0()){
23effa8e 2151 if (!calib->GetPadTime0()->GetCalROC(isec)) continue;
2152 Int_t npads = fTPCParam->GetNPads(isec,padrow);
17807087 2153 // Int_t pad = TMath::Nint(xyz[1]+fTPCParam->GetNPads(isec,TMath::Nint(xyz[0]))*0.5);
23effa8e 2154 // pad numbering from -npads/2 .. npads/2-1
2155 Int_t pad = TMath::Nint(xyz[1]+npads/2);
17807087 2156 if (pad<0) pad=0;
2157 if (pad>=npads) pad=npads-1;
23effa8e 2158 correction = calib->GetPadTime0()->GetCalROC(isec)->GetValue(padrow,pad);
2159 // printf("%d\t%d\t%d\t%f\n",isec,padrow,pad,correction);
2160 if (fDebugStreamer){
2161 (*fDebugStreamer)<<"Time0"<<
2162 "isec="<<isec<<
2163 "padrow="<<padrow<<
2164 "pad="<<pad<<
2165 "x0="<<xyz[0]<<
2166 "x1="<<xyz[1]<<
2167 "x2="<<xyz[2]<<
2168 "hit.="<<tpcHit<<
2169 "cor="<<correction<<
2170 "\n";
2171 }
79fa3dc8 2172 }
2173 xyz[2]+=correction;
c2940e77 2174 xyz[2]+=fTPCParam->GetNTBinsL1(); // adding Level 1 time bin offset
79fa3dc8 2175 //
e61fd20d 2176 // Electron track time (for pileup simulation)
c2940e77 2177 xyz[2]+=tpcHit->Time()/fTPCParam->GetTSample(); // adding time of flight
2178 xyz[4] =0;
2179
2180 //
8c2b3fd7 2181 // row 0 - cross talk from the innermost row
2182 // row fNRow+1 cross talk from the outermost row
2183 rowNumber = index[2]+1;
2184 //transform position to local digit coordinates
2185 //relative to nearest pad row
2186 if ((rowNumber<0)||rowNumber>fTPCParam->GetNRow(isec)+1) continue;
4555e0d2 2187 /* Float_t x1,y1;
8c2b3fd7 2188 if (isec <fTPCParam->GetNInnerSector()) {
2189 x1 = xyz[1]*fTPCParam->GetInnerPadPitchWidth();
2190 y1 = fTPCParam->GetYInner(rowNumber);
2191 }
2192 else{
2193 x1=xyz[1]*fTPCParam->GetOuterPadPitchWidth();
2194 y1 = fTPCParam->GetYOuter(rowNumber);
2195 }
2196 // gain inefficiency at the wires edges - linear
2197 x1=TMath::Abs(x1);
2198 y1-=1.;
4555e0d2 2199 if(x1>y1) xyz[3]*=TMath::Max(1.e-6,(y1-x1+1.)); */
8c2b3fd7 2200
2201 nofElectrons[rowNumber]++;
2202 //----------------------------------
2203 // Expand vector if necessary
2204 //----------------------------------
2205 if(nofElectrons[rowNumber]>120){
2206 Int_t range = tracks[rowNumber]->GetNrows();
e61fd20d 2207 if((nofElectrons[rowNumber])>(range-1)/5){
8c2b3fd7 2208
e61fd20d 2209 tracks[rowNumber]->ResizeTo(range+500); // Add 100 electrons
fe4da5cc 2210 }
8c2b3fd7 2211 }
2212
2213 TVector &v = *tracks[rowNumber];
e61fd20d 2214 Int_t idx = 5*nofElectrons[rowNumber]-4;
8c2b3fd7 2215 Real_t * position = &(((TVector&)v)(idx)); //make code faster
e61fd20d 2216 memcpy(position,xyz,5*sizeof(Float_t));
8c2b3fd7 2217
2218 } // end of loop over electrons
39c8eb58 2219
8c2b3fd7 2220 tpcHit = (AliTPChit*)NextHit();
2221
2222 } // end of loop over hits
2223 } // end of loop over tracks
8c555625 2224
2225 //
2226 // store remaining track (the last one) if not empty
2227 //
8c2b3fd7 2228
2229 for(i=0;i<nrows+2;i++){
2230 if(nofElectrons[i]>0){
2231 TVector &v = *tracks[i];
2232 v(0) = previousTrack;
e61fd20d 2233 tracks[i]->ResizeTo(5*nofElectrons[i]+1); // shrink if necessary
8c2b3fd7 2234 row[i]->Add(tracks[i]);
2235 }
2236 else{
2237 delete tracks[i];
2238 tracks[i]=0;
2239 }
2240 }
2241
2242 delete [] tracks;
2243 delete [] nofElectrons;
8c555625 2244
cc80f89e 2245} // end of MakeSector
8c555625 2246
fe4da5cc 2247
2248//_____________________________________________________________________________
2249void AliTPC::Init()
2250{
2251 //
2252 // Initialise TPC detector after definition of geometry
2253 //
8c2b3fd7 2254 AliDebug(1,"*********************************************");
fe4da5cc 2255}
2256
fe4da5cc 2257//_____________________________________________________________________________
2258void AliTPC::ResetDigits()
2259{
2260 //
2261 // Reset number of digits and the digits array for this detector
fe4da5cc 2262 //
2263 fNdigits = 0;
cc80f89e 2264 if (fDigits) fDigits->Clear();
fe4da5cc 2265}
2266
fe4da5cc 2267
fe4da5cc 2268
2269//_____________________________________________________________________________
2270void AliTPC::SetSens(Int_t sens)
2271{
8c555625 2272
2273 //-------------------------------------------------------------
2274 // Activates/deactivates the sensitive strips at the center of
2275 // the pad row -- this is for the space-point resolution calculations
2276 //-------------------------------------------------------------
2277
2278 //-----------------------------------------------------------------
2279 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
2280 //-----------------------------------------------------------------
2281
fe4da5cc 2282 fSens = sens;
2283}
2b06d5c3 2284
4b0fdcad 2285
73042f01 2286void AliTPC::SetSide(Float_t side=0.)
4b0fdcad 2287{
73042f01 2288 // choice of the TPC side
2289
4b0fdcad 2290 fSide = side;
2291
2292}
cc80f89e 2293//_____________________________________________________________________________
2294
2295void AliTPC::TransportElectron(Float_t *xyz, Int_t *index)
2296{
2297 //
2298 // electron transport taking into account:
2299 // 1. diffusion,
2300 // 2.ExB at the wires
2301 // 3. nonisochronity
2302 //
2303 // xyz and index must be already transformed to system 1
2304 //
2305
23effa8e 2306 fTPCParam->Transform1to2(xyz,index); // mis-alignment applied in this step
cc80f89e 2307
2308 //add diffusion
2309 Float_t driftl=xyz[2];
2310 if(driftl<0.01) driftl=0.01;
2311 driftl=TMath::Sqrt(driftl);
73042f01 2312 Float_t sigT = driftl*(fTPCParam->GetDiffT());
2313 Float_t sigL = driftl*(fTPCParam->GetDiffL());
2314 xyz[0]=gRandom->Gaus(xyz[0],sigT);
2315 xyz[1]=gRandom->Gaus(xyz[1],sigT);
2316 xyz[2]=gRandom->Gaus(xyz[2],sigL);
cc80f89e 2317
2318 // ExB
2319
2320 if (fTPCParam->GetMWPCReadout()==kTRUE){
b584c7dd 2321 Float_t dx = fTPCParam->Transform2to2NearestWire(xyz,index);
cc80f89e 2322 xyz[1]+=dx*(fTPCParam->GetOmegaTau());
2323 }
79fa3dc8 2324 //add nonisochronity (not implemented yet)
2325
2326
1283eee5 2327}
fe4da5cc 2328
fe4da5cc 2329ClassImp(AliTPChit)
179c6296 2330 //______________________________________________________________________
2331 AliTPChit::AliTPChit()
2332 :AliHit(),
2333 fSector(0),
2334 fPadRow(0),
2335 fQ(0),
2336 fTime(0)
2337{
2338 //
2339 // default
2340 //
2341
2342}
fe4da5cc 2343//_____________________________________________________________________________
179c6296 2344AliTPChit::AliTPChit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits)
2345 :AliHit(shunt,track),
2346 fSector(0),
2347 fPadRow(0),
2348 fQ(0),
2349 fTime(0)
fe4da5cc 2350{
2351 //
2352 // Creates a TPC hit object
2353 //
2354 fSector = vol[0];
2355 fPadRow = vol[1];
2356 fX = hits[0];
2357 fY = hits[1];
2358 fZ = hits[2];
2359 fQ = hits[3];
e61fd20d 2360 fTime = hits[4];
fe4da5cc 2361}
2362
39c8eb58 2363//________________________________________________________________________
792bb11c 2364// Additional code because of the AliTPCTrackHitsV2
39c8eb58 2365
a6005888 2366void AliTPC::MakeBranch(Option_t *option)
39c8eb58 2367{
2368 //
2369 // Create a new branch in the current Root Tree
2370 // The branch of fHits is automatically split
2371 // MI change 14.09.2000
8c2b3fd7 2372 AliDebug(1,"");
792bb11c 2373 if (fHitType<2) return;
39c8eb58 2374 char branchname[10];
94e6c6f4 2375 //sprintf(branchname,"%s2",GetName());
2376 snprintf(branchname,10,"%s2",GetName());
39c8eb58 2377 //
2378 // Get the pointer to the header
5cf7bbad 2379 const char *cH = strstr(option,"H");
39c8eb58 2380 //
cb5b8b21 2381 if (fTrackHits && fLoader->TreeH() && cH && fHitType&4) {
8c2b3fd7 2382 AliDebug(1,"Making branch for Type 4 Hits");
cb5b8b21 2383 fLoader->TreeH()->Branch(branchname,"AliTPCTrackHitsV2",&fTrackHits,fBufferSize,99);
8c2b3fd7 2384 }
792bb11c 2385
cb5b8b21 2386// if (fTrackHitsOld && fLoader->TreeH() && cH && fHitType&2) {
be5ffbfe 2387// AliDebug(1,"Making branch for Type 2 Hits");
2388// AliObjectBranch * branch = new AliObjectBranch(branchname,"AliTPCTrackHits",&fTrackHitsOld,
cb5b8b21 2389// fLoader->TreeH(),fBufferSize,99);
2390// fLoader->TreeH()->GetListOfBranches()->Add(branch);
be5ffbfe 2391// }
39c8eb58 2392}
2393
2394void AliTPC::SetTreeAddress()
2395{
8c2b3fd7 2396 //Sets tree address for hits
2397 if (fHitType<=1) {
2398 if (fHits == 0x0 ) fHits = new TClonesArray("AliTPChit", 176);//skowron 20.06.03
2399 AliDetector::SetTreeAddress();
2400 }
792bb11c 2401 if (fHitType>1) SetTreeAddress2();
39c8eb58 2402}
2403
2404void AliTPC::SetTreeAddress2()
2405{
2406 //
2407 // Set branch address for the TrackHits Tree
2408 //
8c2b3fd7 2409 AliDebug(1,"");
88cb7938 2410
39c8eb58 2411 TBranch *branch;
2412 char branchname[20];
94e6c6f4 2413 //sprintf(branchname,"%s2",GetName());
2414 snprintf(branchname,20,"%s2",GetName());
39c8eb58 2415 //
2416 // Branch address for hit tree
cb5b8b21 2417 TTree *treeH = fLoader->TreeH();
792bb11c 2418 if ((treeH)&&(fHitType&4)) {
39c8eb58 2419 branch = treeH->GetBranch(branchname);
8c2b3fd7 2420 if (branch) {
2421 branch->SetAddress(&fTrackHits);
2422 AliDebug(1,"fHitType&4 Setting");
2423 }
f2a509af 2424 else
8c2b3fd7 2425 AliDebug(1,"fHitType&4 Failed (can not find branch)");
f2a509af 2426
39c8eb58 2427 }
be5ffbfe 2428 // if ((treeH)&&(fHitType&2)) {
2429// branch = treeH->GetBranch(branchname);
2430// if (branch) {
2431// branch->SetAddress(&fTrackHitsOld);
2432// AliDebug(1,"fHitType&2 Setting");
2433// }
2434// else
2435// AliDebug(1,"fHitType&2 Failed (can not find branch)");
2436// }
39c8eb58 2437}
2438
2439void AliTPC::FinishPrimary()
2440{
792bb11c 2441 if (fTrackHits &&fHitType&4) fTrackHits->FlushHitStack();
be5ffbfe 2442 // if (fTrackHitsOld && fHitType&2) fTrackHitsOld->FlushHitStack();
39c8eb58 2443}
2444
2445
2446void AliTPC::AddHit2(Int_t track, Int_t *vol, Float_t *hits)
2447{
2448 //
a6005888 2449 // add hit to the list
2450
39c8eb58 2451 Int_t rtrack;
2452 if (fIshunt) {
5d12ce38 2453 int primary = gAlice->GetMCApp()->GetPrimary(track);
2454 gAlice->GetMCApp()->Particle(primary)->SetBit(kKeepBit);
39c8eb58 2455 rtrack=primary;
2456 } else {
2457 rtrack=track;
5d12ce38 2458 gAlice->GetMCApp()->FlagTrack(track);
39c8eb58 2459 }
792bb11c 2460 if (fTrackHits && fHitType&4)
39c8eb58 2461 fTrackHits->AddHitKartez(vol[0],rtrack, hits[0],
e61fd20d 2462 hits[1],hits[2],(Int_t)hits[3],hits[4]);
be5ffbfe 2463 // if (fTrackHitsOld &&fHitType&2 )
2464// fTrackHitsOld->AddHitKartez(vol[0],rtrack, hits[0],
2465// hits[1],hits[2],(Int_t)hits[3]);
792bb11c 2466
39c8eb58 2467}
2468
2469void AliTPC::ResetHits()
88cb7938 2470{
39c8eb58 2471 if (fHitType&1) AliDetector::ResetHits();
792bb11c 2472 if (fHitType>1) ResetHits2();
39c8eb58 2473}
2474
2475void AliTPC::ResetHits2()
2476{
2477 //
2478 //reset hits
792bb11c 2479 if (fTrackHits && fHitType&4) fTrackHits->Clear();
be5ffbfe 2480 // if (fTrackHitsOld && fHitType&2) fTrackHitsOld->Clear();
792bb11c 2481
39c8eb58 2482}
2483
2484AliHit* AliTPC::FirstHit(Int_t track)
2485{
792bb11c 2486 if (fHitType>1) return FirstHit2(track);
39c8eb58 2487 return AliDetector::FirstHit(track);
2488}
2489AliHit* AliTPC::NextHit()
2490{
9bdd974b 2491 //
2492 // gets next hit
2493 //
792bb11c 2494 if (fHitType>1) return NextHit2();
2495
39c8eb58 2496 return AliDetector::NextHit();
2497}
2498
2499AliHit* AliTPC::FirstHit2(Int_t track)
2500{
2501 //
2502 // Initialise the hit iterator
2503 // Return the address of the first hit for track
2504 // If track>=0 the track is read from disk
2505 // while if track<0 the first hit of the current
2506 // track is returned
2507 //
2508 if(track>=0) {
3e2e3ece 2509 gAlice->GetMCApp()->ResetHits();
cb5b8b21 2510 fLoader->TreeH()->GetEvent(track);
39c8eb58 2511 }
2512 //
792bb11c 2513 if (fTrackHits && fHitType&4) {
39c8eb58 2514 fTrackHits->First();
2515 return fTrackHits->GetHit();
2516 }
be5ffbfe 2517 // if (fTrackHitsOld && fHitType&2) {
2518// fTrackHitsOld->First();
2519// return fTrackHitsOld->GetHit();
2520// }
792bb11c 2521
39c8eb58 2522 else return 0;
2523}
2524
2525AliHit* AliTPC::NextHit2()
2526{
2527 //
2528 //Return the next hit for the current track
2529
792bb11c 2530
be5ffbfe 2531// if (fTrackHitsOld && fHitType&2) {
2532// fTrackHitsOld->Next();
2533// return fTrackHitsOld->GetHit();
2534// }
39c8eb58 2535 if (fTrackHits) {
2536 fTrackHits->Next();
2537 return fTrackHits->GetHit();
2538 }
2539 else
2540 return 0;
2541}
2542
39c8eb58 2543void AliTPC::RemapTrackHitIDs(Int_t *map)
2544{
9bdd974b 2545 //
2546 // remapping
2547 //
39c8eb58 2548 if (!fTrackHits) return;
39c8eb58 2549
be5ffbfe 2550// if (fTrackHitsOld && fHitType&2){
2551// AliObjectArray * arr = fTrackHitsOld->fTrackHitsInfo;
2552// for (UInt_t i=0;i<arr->GetSize();i++){
2553// AliTrackHitsInfo * info = (AliTrackHitsInfo *)(arr->At(i));
2554// info->fTrackID = map[info->fTrackID];
2555// }
2556// }
2557// if (fTrackHitsOld && fHitType&4){
2558 if (fTrackHits && fHitType&4){
792bb11c 2559 TClonesArray * arr = fTrackHits->GetArray();;
2560 for (Int_t i=0;i<arr->GetEntriesFast();i++){
2561 AliTrackHitsParamV2 * info = (AliTrackHitsParamV2 *)(arr->At(i));
b9671574 2562 info->SetTrackID(map[info->GetTrackID()]);
792bb11c 2563 }
2564 }
39c8eb58 2565}
2566
792bb11c 2567Bool_t AliTPC::TrackInVolume(Int_t id,Int_t track)
2568{
2569 //return bool information - is track in given volume
2570 //load only part of the track information
2571 //return true if current track is in volume
2572 //
2573 // return kTRUE;
be5ffbfe 2574 // if (fTrackHitsOld && fHitType&2) {
cb5b8b21 2575// TBranch * br = fLoader->TreeH()->GetBranch("fTrackHitsInfo");
be5ffbfe 2576// br->GetEvent(track);
2577// AliObjectArray * ar = fTrackHitsOld->fTrackHitsInfo;
2578// for (UInt_t j=0;j<ar->GetSize();j++){
2579// if ( ((AliTrackHitsInfo*)ar->At(j))->fVolumeID==id) return kTRUE;
2580// }
2581// }
792bb11c 2582
2583 if (fTrackHits && fHitType&4) {
cb5b8b21 2584 TBranch * br1 = fLoader->TreeH()->GetBranch("fVolumes");
2585 TBranch * br2 = fLoader->TreeH()->GetBranch("fNVolumes");
792bb11c 2586 br2->GetEvent(track);
2587 br1->GetEvent(track);
2588 Int_t *volumes = fTrackHits->GetVolumes();
2589 Int_t nvolumes = fTrackHits->GetNVolumes();
2590 if (!volumes && nvolumes>0) {
8c2b3fd7 2591 AliWarning(Form("Problematic track\t%d\t%d",track,nvolumes));
792bb11c 2592 return kFALSE;
2593 }
2594 for (Int_t j=0;j<nvolumes; j++)
2595 if (volumes[j]==id) return kTRUE;
2596 }
2597
2598 if (fHitType&1) {
cb5b8b21 2599 TBranch * br = fLoader->TreeH()->GetBranch("fSector");
792bb11c 2600 br->GetEvent(track);
2601 for (Int_t j=0;j<fHits->GetEntriesFast();j++){
2602 if ( ((AliTPChit*)fHits->At(j))->fSector==id) return kTRUE;
2603 }
2604 }
2605 return kFALSE;
2606
2607}
39c8eb58 2608
39c8eb58 2609
88cb7938 2610AliLoader* AliTPC::MakeLoader(const char* topfoldername)
2611{
8c2b3fd7 2612 //Makes TPC loader
2613 fLoader = new AliTPCLoader(GetName(),topfoldername);
2614 return fLoader;
88cb7938 2615}
2616
42157e55 2617////////////////////////////////////////////////////////////////////////
2618AliTPCParam* AliTPC::LoadTPCParam(TFile *file) {
2619//
2620// load TPC paarmeters from a given file or create new if the object
2621// is not found there
88cb7938 2622// 12/05/2003 This method should be moved to the AliTPCLoader
2623// and one has to decide where to store the TPC parameters
2624// M.Kowalski
42157e55 2625 char paramName[50];
94e6c6f4 2626 //sprintf(paramName,"75x40_100x60_150x60");
2627 snprintf(paramName,50,"75x40_100x60_150x60");
42157e55 2628 AliTPCParam *paramTPC=(AliTPCParam*)file->Get(paramName);
2629 if (paramTPC) {
8c2b3fd7 2630 AliDebugClass(1,Form("TPC parameters %s found.",paramName));
42157e55 2631 } else {
8c2b3fd7 2632 AliWarningClass("TPC parameters not found. Create new (they may be incorrect)");
db2fdcfb 2633 //paramTPC = new AliTPCParamSR;
2634 paramTPC = AliTPCcalibDB::Instance()->GetParameters();
2635 if (!paramTPC->IsGeoRead()){
2636 //
2637 // read transformation matrices for gGeoManager
2638 //
2639 paramTPC->ReadGeoMatrices();
2640 }
2641
42157e55 2642 }
2643 return paramTPC;
2644
2645// the older version of parameters can be accessed with this code.
2646// In some cases, we have old parameters saved in the file but
2647// digits were created with new parameters, it can be distinguish
2648// by the name of TPC TreeD. The code here is just for the case
2649// we would need to compare with old data, uncomment it if needed.
2650//
2651// char paramName[50];
2652// sprintf(paramName,"75x40_100x60");
2653// AliTPCParam *paramTPC=(AliTPCParam*)in->Get(paramName);
2654// if (paramTPC) {
2655// cout<<"TPC parameters "<<paramName<<" found."<<endl;
2656// } else {
2657// sprintf(paramName,"75x40_100x60_150x60");
2658// paramTPC=(AliTPCParam*)in->Get(paramName);
2659// if (paramTPC) {
2660// cout<<"TPC parameters "<<paramName<<" found."<<endl;
2661// } else {
2662// cerr<<"TPC parameters not found. Create new (they may be incorrect)."
2663// <<endl;
2664// paramTPC = new AliTPCParamSR;
2665// }
2666// }
2667// return paramTPC;
2668
2669}
2670
85a5290f 2671