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