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