]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPC.cxx
Forward declarations. Changes due to a new class AliComplexCluster.
[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
16/*
17$Log$
94de3818 18Revision 1.22 2000/07/10 20:57:39 hristov
19Update of TPC code and macros by M.Kowalski
20
73042f01 21Revision 1.19.2.4 2000/06/26 07:39:42 kowal2
22Changes to obey the coding rules
23
24Revision 1.19.2.3 2000/06/25 08:38:41 kowal2
25Splitted from AliTPCtracking
26
27Revision 1.19.2.2 2000/06/16 12:59:28 kowal2
28Changed parameter settings
29
30Revision 1.19.2.1 2000/06/09 07:15:07 kowal2
31
32Defaults loaded automatically (hard-wired)
33Optional parameters can be set via macro called in the constructor
34
35Revision 1.19 2000/04/18 19:00:59 fca
36Small bug fixes to TPC files
37
4d68a14a 38Revision 1.18 2000/04/17 09:37:33 kowal2
39removed obsolete AliTPCDigitsDisplay.C
40
cc80f89e 41Revision 1.17.2.2 2000/04/10 08:15:12 kowal2
42
43New, experimental data structure from M. Ivanov
44New tracking algorithm
45Different pad geometry for different sectors
46Digitization rewritten
47
48Revision 1.17.2.1 2000/04/10 07:56:53 kowal2
49Not used anymore - removed
50
51Revision 1.17 2000/01/19 17:17:30 fca
52Introducing a list of lists of hits -- more hits allowed for detector now
53
1cedd08a 54Revision 1.16 1999/11/05 09:29:23 fca
55Accept only signals > 0
56
921bf71a 57Revision 1.15 1999/10/08 06:26:53 fca
58Removed ClustersIndex - not used anymore
59
e674b993 60Revision 1.14 1999/09/29 09:24:33 fca
61Introduction of the Copyright and cvs Log
62
4c039060 63*/
64
fe4da5cc 65///////////////////////////////////////////////////////////////////////////////
66// //
67// Time Projection Chamber //
68// This class contains the basic functions for the Time Projection Chamber //
69// detector. Functions specific to one particular geometry are //
70// contained in the derived classes //
71// //
72//Begin_Html
73/*
1439f98e 74<img src="picts/AliTPCClass.gif">
fe4da5cc 75*/
76//End_Html
77// //
8c555625 78// //
fe4da5cc 79///////////////////////////////////////////////////////////////////////////////
80
73042f01 81//
82
fe4da5cc 83#include <TMath.h>
84#include <TRandom.h>
85#include <TVector.h>
8c555625 86#include <TMatrix.h>
fe4da5cc 87#include <TGeometry.h>
88#include <TNode.h>
89#include <TTUBS.h>
90#include <TObjectTable.h>
1578254f 91#include "TParticle.h"
fe4da5cc 92#include "AliTPC.h"
73042f01 93#include <TFile.h>
fe4da5cc 94#include "AliRun.h"
95#include <iostream.h>
96#include <fstream.h>
97#include "AliMC.h"
94de3818 98#include "AliMagF.h"
fe4da5cc 99
cc80f89e 100
73042f01 101#include "AliTPCParamSR.h"
8c555625 102#include "AliTPCPRF2D.h"
103#include "AliTPCRF1D.h"
cc80f89e 104#include "AliDigits.h"
105#include "AliSimDigits.h"
106
107#include "AliTPCDigitsArray.h"
108#include "AliCluster.h"
109#include "AliClusters.h"
110#include "AliTPCClustersRow.h"
111#include "AliTPCClustersArray.h"
8c555625 112
73042f01 113#include "AliTPCcluster.h"
114#include "AliTPCclusterer.h"
115#include "AliTPCtracker.h"
8c555625 116
73042f01 117#include <TInterpreter.h>
1283eee5 118
fe4da5cc 119ClassImp(AliTPC)
120
121//_____________________________________________________________________________
122AliTPC::AliTPC()
123{
124 //
125 // Default constructor
126 //
127 fIshunt = 0;
fe4da5cc 128 fHits = 0;
129 fDigits = 0;
fe4da5cc 130 fNsectors = 0;
cc80f89e 131 //MI changes
132 fDigitsArray = 0;
133 fClustersArray = 0;
73042f01 134 fTPCParam=0;
fe4da5cc 135}
136
137//_____________________________________________________________________________
138AliTPC::AliTPC(const char *name, const char *title)
139 : AliDetector(name,title)
140{
141 //
142 // Standard constructor
143 //
144
145 //
146 // Initialise arrays of hits and digits
147 fHits = new TClonesArray("AliTPChit", 176);
4d68a14a 148 gAlice->AddHitList(fHits);
cc80f89e 149 //MI change
150 fDigitsArray = 0;
151 fClustersArray= 0;
fe4da5cc 152 //
153 // Initialise counters
cc80f89e 154 fNsectors = 0;
cc80f89e 155
fe4da5cc 156 //
157 fIshunt = 0;
158 //
159 // Initialise color attributes
160 SetMarkerColor(kYellow);
73042f01 161
162 //
163 // Set TPC parameters
164 //
165
166 if (!strcmp(title,"Default")) {
167 fTPCParam = new AliTPCParamSR;
168 } else {
169 cerr<<"AliTPC warning: in Config.C you must set non-default parameters\n";
170 fTPCParam=0;
171 }
172
fe4da5cc 173}
174
175//_____________________________________________________________________________
176AliTPC::~AliTPC()
177{
178 //
179 // TPC destructor
180 //
73042f01 181
fe4da5cc 182 fIshunt = 0;
183 delete fHits;
184 delete fDigits;
73042f01 185 delete fTPCParam;
fe4da5cc 186}
187
fe4da5cc 188//_____________________________________________________________________________
189void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
190{
191 //
192 // Add a hit to the list
193 //
194 TClonesArray &lhits = *fHits;
195 new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
196}
197
fe4da5cc 198//_____________________________________________________________________________
199void AliTPC::BuildGeometry()
200{
cc80f89e 201
fe4da5cc 202 //
203 // Build TPC ROOT TNode geometry for the event display
204 //
73042f01 205 TNode *nNode, *nTop;
fe4da5cc 206 TTUBS *tubs;
207 Int_t i;
208 const int kColorTPC=19;
1283eee5 209 char name[5], title[25];
fe4da5cc 210 const Double_t kDegrad=TMath::Pi()/180;
1283eee5 211 const Double_t kRaddeg=180./TMath::Pi();
212
1283eee5 213
73042f01 214 Float_t innerOpenAngle = fTPCParam->GetInnerAngle();
215 Float_t outerOpenAngle = fTPCParam->GetOuterAngle();
1283eee5 216
73042f01 217 Float_t innerAngleShift = fTPCParam->GetInnerAngleShift();
218 Float_t outerAngleShift = fTPCParam->GetOuterAngleShift();
1283eee5 219
220 Int_t nLo = fTPCParam->GetNInnerSector()/2;
221 Int_t nHi = fTPCParam->GetNOuterSector()/2;
222
73042f01 223 const Double_t kloAng = (Double_t)TMath::Nint(innerOpenAngle*kRaddeg);
224 const Double_t khiAng = (Double_t)TMath::Nint(outerOpenAngle*kRaddeg);
225 const Double_t kloAngSh = (Double_t)TMath::Nint(innerAngleShift*kRaddeg);
226 const Double_t khiAngSh = (Double_t)TMath::Nint(outerAngleShift*kRaddeg);
1283eee5 227
228
73042f01 229 const Double_t kloCorr = 1/TMath::Cos(0.5*kloAng*kDegrad);
230 const Double_t khiCorr = 1/TMath::Cos(0.5*khiAng*kDegrad);
1283eee5 231
232 Double_t rl,ru;
233
234
fe4da5cc 235 //
236 // Get ALICE top node
fe4da5cc 237 //
1283eee5 238
73042f01 239 nTop=gAlice->GetGeometry()->GetNode("alice");
1283eee5 240
241 // inner sectors
242
cc80f89e 243 rl = fTPCParam->GetInnerRadiusLow();
244 ru = fTPCParam->GetInnerRadiusUp();
1283eee5 245
246
fe4da5cc 247 for(i=0;i<nLo;i++) {
248 sprintf(name,"LS%2.2d",i);
1283eee5 249 name[4]='\0';
250 sprintf(title,"TPC low sector %3d",i);
251 title[24]='\0';
252
73042f01 253 tubs = new TTUBS(name,title,"void",rl*kloCorr,ru*kloCorr,250.,
254 kloAng*(i-0.5)+kloAngSh,kloAng*(i+0.5)+kloAngSh);
fe4da5cc 255 tubs->SetNumberOfDivisions(1);
73042f01 256 nTop->cd();
257 nNode = new TNode(name,title,name,0,0,0,"");
258 nNode->SetLineColor(kColorTPC);
259 fNodes->Add(nNode);
fe4da5cc 260 }
1283eee5 261
fe4da5cc 262 // Outer sectors
1283eee5 263
cc80f89e 264 rl = fTPCParam->GetOuterRadiusLow();
265 ru = fTPCParam->GetOuterRadiusUp();
1283eee5 266
fe4da5cc 267 for(i=0;i<nHi;i++) {
268 sprintf(name,"US%2.2d",i);
1283eee5 269 name[4]='\0';
fe4da5cc 270 sprintf(title,"TPC upper sector %d",i);
1283eee5 271 title[24]='\0';
73042f01 272 tubs = new TTUBS(name,title,"void",rl*khiCorr,ru*khiCorr,250,
273 khiAng*(i-0.5)+khiAngSh,khiAng*(i+0.5)+khiAngSh);
fe4da5cc 274 tubs->SetNumberOfDivisions(1);
73042f01 275 nTop->cd();
276 nNode = new TNode(name,title,name,0,0,0,"");
277 nNode->SetLineColor(kColorTPC);
278 fNodes->Add(nNode);
fe4da5cc 279 }
cc80f89e 280
73042f01 281}
1283eee5 282
fe4da5cc 283//_____________________________________________________________________________
284Int_t AliTPC::DistancetoPrimitive(Int_t , Int_t )
285{
286 //
287 // Calculate distance from TPC to mouse on the display
288 // Dummy procedure
289 //
290 return 9999;
291}
292
73042f01 293void AliTPC::Clusters2Tracks(TFile *of) {
3c0f9266 294 //-----------------------------------------------------------------
295 // This is a track finder.
3c0f9266 296 //-----------------------------------------------------------------
73042f01 297 AliTPCtracker::Clusters2Tracks(fTPCParam,of);
fe4da5cc 298}
299
300//_____________________________________________________________________________
301void AliTPC::CreateMaterials()
302{
8c555625 303 //-----------------------------------------------
37831078 304 // Create Materials for for TPC simulations
8c555625 305 //-----------------------------------------------
306
307 //-----------------------------------------------------------------
308 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
309 //-----------------------------------------------------------------
1283eee5 310
73042f01 311 Int_t iSXFLD=gAlice->Field()->Integ();
312 Float_t sXMGMX=gAlice->Field()->Max();
1283eee5 313
314 Float_t amat[5]; // atomic numbers
315 Float_t zmat[5]; // z
316 Float_t wmat[5]; // proportions
317
318 Float_t density;
37831078 319 Float_t apure[2];
1283eee5 320
1283eee5 321
37831078 322 //***************** Gases *************************
323
324 //-------------------------------------------------
1283eee5 325 // pure gases
37831078 326 //-------------------------------------------------
1283eee5 327
37831078 328 // Neon
1283eee5 329
330
37831078 331 amat[0]= 20.18;
332 zmat[0]= 10.;
1283eee5 333 density = 0.0009;
37831078 334
335 apure[0]=amat[0];
1283eee5 336
37831078 337 AliMaterial(20,"Ne",amat[0],zmat[0],density,999.,999.);
1283eee5 338
37831078 339 // Argon
1283eee5 340
37831078 341 amat[0]= 39.948;
342 zmat[0]= 18.;
343 density = 0.001782;
1283eee5 344
37831078 345 apure[1]=amat[0];
1283eee5 346
37831078 347 AliMaterial(21,"Ar",amat[0],zmat[0],density,999.,999.);
348
1283eee5 349
350 //--------------------------------------------------------------
351 // gases - compounds
352 //--------------------------------------------------------------
353
354 Float_t amol[3];
355
37831078 356 // CO2
1283eee5 357
358 amat[0]=12.011;
359 amat[1]=15.9994;
360
361 zmat[0]=6.;
362 zmat[1]=8.;
363
364 wmat[0]=1.;
365 wmat[1]=2.;
366
367 density=0.001977;
368
369 amol[0] = amat[0]*wmat[0]+amat[1]*wmat[1];
370
371 AliMixture(10,"CO2",amat,zmat,density,-2,wmat);
37831078 372
1283eee5 373 // CF4
374
375 amat[0]=12.011;
376 amat[1]=18.998;
377
378 zmat[0]=6.;
379 zmat[1]=9.;
380
381 wmat[0]=1.;
382 wmat[1]=4.;
383
384 density=0.003034;
385
386 amol[1] = amat[0]*wmat[0]+amat[1]*wmat[1];
387
388 AliMixture(11,"CF4",amat,zmat,density,-2,wmat);
389
37831078 390
1283eee5 391 // CH4
392
393 amat[0]=12.011;
394 amat[1]=1.;
395
396 zmat[0]=6.;
397 zmat[1]=1.;
398
399 wmat[0]=1.;
400 wmat[1]=4.;
401
402 density=0.000717;
403
404 amol[2] = amat[0]*wmat[0]+amat[1]*wmat[1];
405
406 AliMixture(12,"CH4",amat,zmat,density,-2,wmat);
407
408 //----------------------------------------------------------------
409 // gases - mixtures, ID >= 20 pure gases, <= 10 ID < 20 -compounds
410 //----------------------------------------------------------------
37831078 411
412 char namate[21];
1283eee5 413 density = 0.;
414 Float_t am=0;
415 Int_t nc;
37831078 416 Float_t rho,absl,X0,buf[1];
1283eee5 417 Int_t nbuf;
37831078 418 Float_t a,z;
1283eee5 419
420 for(nc = 0;nc<fNoComp;nc++)
421 {
422
423 // retrive material constants
424
37831078 425 gMC->Gfmate((*fIdmate)[fMixtComp[nc]],namate,a,z,rho,X0,absl,buf,nbuf);
1283eee5 426
427 amat[nc] = a;
428 zmat[nc] = z;
429
430 Int_t nnc = (fMixtComp[nc]>=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
431
37831078 432 am += fMixtProp[nc]*((fMixtComp[nc]>=20) ? apure[nnc] : amol[nnc]);
1283eee5 433 density += fMixtProp[nc]*rho; // density of the mixture
434
435 }
436
437 // mixture proportions by weight!
438
439 for(nc = 0;nc<fNoComp;nc++)
440 {
441
442 Int_t nnc = (fMixtComp[nc]>=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
443
37831078 444 wmat[nc] = fMixtProp[nc]*((fMixtComp[nc]>=20) ?
445 apure[nnc] : amol[nnc])/am;
446
447 }
448
449 // Drift gases 1 - nonsensitive, 2 - sensitive
1283eee5 450
1283eee5 451 AliMixture(31,"Drift gas 1",amat,zmat,density,fNoComp,wmat);
452 AliMixture(32,"Drift gas 2",amat,zmat,density,fNoComp,wmat);
1283eee5 453
1283eee5 454
37831078 455 // Air
456
457 amat[0] = 14.61;
458 zmat[0] = 7.3;
459 density = 0.001205;
1283eee5 460
37831078 461 AliMaterial(24,"Air",amat[0],zmat[0],density,999.,999.);
1283eee5 462
1283eee5 463
464 //----------------------------------------------------------------------
465 // solid materials
466 //----------------------------------------------------------------------
467
1283eee5 468
37831078 469 // Kevlar C14H22O2N2
1283eee5 470
37831078 471 amat[0] = 12.011;
472 amat[1] = 1.;
473 amat[2] = 15.999;
474 amat[3] = 14.006;
1283eee5 475
37831078 476 zmat[0] = 6.;
477 zmat[1] = 1.;
478 zmat[2] = 8.;
479 zmat[3] = 7.;
480
481 wmat[0] = 14.;
482 wmat[1] = 22.;
483 wmat[2] = 2.;
484 wmat[3] = 2.;
485
486 density = 1.45;
487
488 AliMixture(34,"Kevlar",amat,zmat,density,-4,wmat);
489
490 // NOMEX
1283eee5 491
37831078 492 amat[0] = 12.011;
493 amat[1] = 1.;
494 amat[2] = 15.999;
495 amat[3] = 14.006;
496
497 zmat[0] = 6.;
498 zmat[1] = 1.;
499 zmat[2] = 8.;
500 zmat[3] = 7.;
501
502 wmat[0] = 14.;
503 wmat[1] = 22.;
504 wmat[2] = 2.;
505 wmat[3] = 2.;
506
507 density = 0.03;
1283eee5 508
fe4da5cc 509
37831078 510 AliMixture(35,"NOMEX",amat,zmat,density,-4,wmat);
511
512 // Makrolon C16H18O3
513
514 amat[0] = 12.011;
515 amat[1] = 1.;
516 amat[2] = 15.999;
1283eee5 517
37831078 518 zmat[0] = 6.;
519 zmat[1] = 1.;
520 zmat[2] = 8.;
521
522 wmat[0] = 16.;
523 wmat[1] = 18.;
524 wmat[2] = 3.;
525
526 density = 1.2;
527
528 AliMixture(36,"Makrolon",amat,zmat,density,-3,wmat);
529
1283eee5 530 // Mylar C5H4O2
531
532 amat[0]=12.011;
533 amat[1]=1.;
534 amat[2]=15.9994;
535
536 zmat[0]=6.;
537 zmat[1]=1.;
538 zmat[2]=8.;
539
540 wmat[0]=5.;
541 wmat[1]=4.;
542 wmat[2]=2.;
543
544 density = 1.39;
fe4da5cc 545
37831078 546 AliMixture(37, "Mylar",amat,zmat,density,-3,wmat);
1283eee5 547
37831078 548 // G10 60% SiO2 + 40% epoxy, I use A and Z for SiO2
1283eee5 549
37831078 550 amat[0]=28.086;
551 amat[1]=15.9994;
1283eee5 552
37831078 553 zmat[0]=14.;
554 zmat[1]=8.;
1283eee5 555
37831078 556 wmat[0]=1.;
557 wmat[1]=2.;
1283eee5 558
37831078 559 density = 1.7;
1283eee5 560
37831078 561 AliMixture(38,"SiO2",amat,zmat,2.2,-2,wmat); //SiO2 - quartz
562
563 gMC->Gfmate((*fIdmate)[38],namate,amat[0],zmat[0],rho,X0,absl,buf,nbuf);
1283eee5 564
37831078 565 AliMaterial(39,"G10",amat[0],zmat[0],density,999.,999.);
1283eee5 566
37831078 567 // Al
1283eee5 568
37831078 569 amat[0] = 26.98;
570 zmat[0] = 13.;
1283eee5 571
37831078 572 density = 2.7;
1283eee5 573
37831078 574 AliMaterial(40,"Al",amat[0],zmat[0],density,999.,999.);
1283eee5 575
37831078 576 // Si
1283eee5 577
37831078 578 amat[0] = 28.086;
579 zmat[0] = 14.,
1283eee5 580
37831078 581 density = 2.33;
1283eee5 582
37831078 583 AliMaterial(41,"Si",amat[0],zmat[0],density,999.,999.);
1283eee5 584
37831078 585 // Cu
1283eee5 586
37831078 587 amat[0] = 63.546;
588 zmat[0] = 29.;
1283eee5 589
37831078 590 density = 8.96;
1283eee5 591
37831078 592 AliMaterial(42,"Cu",amat[0],zmat[0],density,999.,999.);
1283eee5 593
37831078 594 // Tedlar C2H3F
1283eee5 595
37831078 596 amat[0] = 12.011;
597 amat[1] = 1.;
598 amat[2] = 18.998;
1283eee5 599
37831078 600 zmat[0] = 6.;
601 zmat[1] = 1.;
602 zmat[2] = 9.;
1283eee5 603
37831078 604 wmat[0] = 2.;
605 wmat[1] = 3.;
606 wmat[2] = 1.;
1283eee5 607
37831078 608 density = 1.71;
1283eee5 609
37831078 610 AliMixture(43, "Tedlar",amat,zmat,density,-3,wmat);
1283eee5 611
1283eee5 612
37831078 613 // Plexiglas C5H8O2
1283eee5 614
37831078 615 amat[0]=12.011;
616 amat[1]=1.;
617 amat[2]=15.9994;
1283eee5 618
37831078 619 zmat[0]=6.;
620 zmat[1]=1.;
621 zmat[2]=8.;
1283eee5 622
37831078 623 wmat[0]=5.;
624 wmat[1]=8.;
625 wmat[2]=2.;
1283eee5 626
37831078 627 density=1.18;
1283eee5 628
37831078 629 AliMixture(44,"Plexiglas",amat,zmat,density,-3,wmat);
1283eee5 630
1283eee5 631
37831078 632
633 //----------------------------------------------------------
634 // tracking media for gases
635 //----------------------------------------------------------
636
637 AliMedium(0, "Air", 24, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
638 AliMedium(1, "Drift gas 1", 31, 0, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
639 AliMedium(2, "Drift gas 2", 32, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
640 AliMedium(3,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
641
642 //-----------------------------------------------------------
643 // tracking media for solids
644 //-----------------------------------------------------------
645
646 AliMedium(4,"Al",40,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
647 AliMedium(5,"Kevlar",34,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
648 AliMedium(6,"Nomex",35,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
649 AliMedium(7,"Makrolon",36,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
650 AliMedium(8,"Mylar",37,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
651 AliMedium(9,"Tedlar",43,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
652 AliMedium(10,"Cu",42,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
653 AliMedium(11,"Si",41,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
654 AliMedium(12,"G10",39,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
655 AliMedium(13,"Plexiglas",44,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
1283eee5 656
fe4da5cc 657}
658
fe4da5cc 659
73042f01 660void AliTPC::Digits2Clusters(TFile *of)
fe4da5cc 661{
3c0f9266 662 //-----------------------------------------------------------------
663 // This is a simple cluster finder.
3c0f9266 664 //-----------------------------------------------------------------
73042f01 665 AliTPCclusterer::Digits2Clusters(fTPCParam,of);
fe4da5cc 666}
667
73042f01 668extern Double_t SigmaY2(Double_t, Double_t, Double_t);
669extern Double_t SigmaZ2(Double_t, Double_t);
fe4da5cc 670//_____________________________________________________________________________
73042f01 671void AliTPC::Hits2Clusters(TFile *of)
fe4da5cc 672{
8c555625 673 //--------------------------------------------------------
fe4da5cc 674 // TPC simple cluster generator from hits
675 // obtained from the TPC Fast Simulator
8c555625 676 // The point errors are taken from the parametrization
677 //--------------------------------------------------------
678
679 //-----------------------------------------------------------------
680 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
681 //-----------------------------------------------------------------
73042f01 682 // Adopted to Marian's cluster data structure by I.Belikov, CERN,
683 // Jouri.Belikov@cern.ch
684 //----------------------------------------------------------------
685
686 /////////////////////////////////////////////////////////////////////////////
687 //
688 //---------------------------------------------------------------------
689 // ALICE TPC Cluster Parameters
690 //--------------------------------------------------------------------
691
692
693
694 // Cluster width in rphi
695 const Float_t kACrphi=0.18322;
696 const Float_t kBCrphi=0.59551e-3;
697 const Float_t kCCrphi=0.60952e-1;
698 // Cluster width in z
699 const Float_t kACz=0.19081;
700 const Float_t kBCz=0.55938e-3;
701 const Float_t kCCz=0.30428;
702
703 TDirectory *savedir=gDirectory;
704
705 if (!of->IsOpen()) {
706 cerr<<"AliTPC::Hits2Clusters(): output file not open !\n";
707 return;
708 }
3c0f9266 709
cc80f89e 710 if(fTPCParam == 0){
711 printf("AliTPCParam MUST be created firstly\n");
712 return;
713 }
714
73042f01 715 Float_t sigmaRphi,sigmaZ,clRphi,clZ;
fe4da5cc 716 //
1578254f 717 TParticle *particle; // pointer to a given particle
fe4da5cc 718 AliTPChit *tpcHit; // pointer to a sigle TPC hit
73042f01 719 TClonesArray *particles; //pointer to the particle list
fe4da5cc 720 Int_t sector,nhits;
721 Int_t ipart;
722 Float_t xyz[5];
723 Float_t pl,pt,tanth,rpad,ratio;
fe4da5cc 724 Float_t cph,sph;
725
726 //---------------------------------------------------------------
727 // Get the access to the tracks
728 //---------------------------------------------------------------
729
73042f01 730 TTree *tH = gAlice->TreeH();
731 Stat_t ntracks = tH->GetEntries();
732 particles=gAlice->Particles();
733
734 //Switch to the output file
735 of->cd();
736
737 fTPCParam->Write(fTPCParam->GetTitle());
738 AliTPCClustersArray carray;
739 carray.Setup(fTPCParam);
740 carray.SetClusterType("AliTPCcluster");
741 carray.MakeTree();
742
743 Int_t nclusters=0; //cluster counter
fe4da5cc 744
745 //------------------------------------------------------------
cc80f89e 746 // Loop over all sectors (72 sectors for 20 deg
747 // segmentation for both lower and upper sectors)
748 // Sectors 0-35 are lower sectors, 0-17 z>0, 17-35 z<0
3c0f9266 749 // Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0
fe4da5cc 750 //
3c0f9266 751 // First cluster for sector 0 starts at "0"
fe4da5cc 752 //------------------------------------------------------------
cc80f89e 753
754 for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++){
8c555625 755 //MI change
cc80f89e 756 fTPCParam->AdjustCosSin(isec,cph,sph);
fe4da5cc 757
758 //------------------------------------------------------------
759 // Loop over tracks
760 //------------------------------------------------------------
761
762 for(Int_t track=0;track<ntracks;track++){
763 ResetHits();
73042f01 764 tH->GetEvent(track);
fe4da5cc 765 //
73042f01 766 // Get number of the TPC hits
fe4da5cc 767 //
768 nhits=fHits->GetEntriesFast();
fe4da5cc 769 //
770 // Loop over hits
771 //
772 for(Int_t hit=0;hit<nhits;hit++){
773 tpcHit=(AliTPChit*)fHits->UncheckedAt(hit);
cc80f89e 774 if (tpcHit->fQ == 0.) continue; //information about track (I.Belikov)
fe4da5cc 775 sector=tpcHit->fSector; // sector number
776 if(sector != isec) continue; //terminate iteration
94de3818 777 ipart=tpcHit->Track();
73042f01 778 particle=(TParticle*)particles->UncheckedAt(ipart);
1578254f 779 pl=particle->Pz();
780 pt=particle->Pt();
fe4da5cc 781 if(pt < 1.e-9) pt=1.e-9;
782 tanth=pl/pt;
783 tanth = TMath::Abs(tanth);
94de3818 784 rpad=TMath::Sqrt(tpcHit->X()*tpcHit->X() + tpcHit->Y()*tpcHit->Y());
fe4da5cc 785 ratio=0.001*rpad/pt; // pt must be in MeV/c - historical reason
73042f01 786
fe4da5cc 787 // space-point resolutions
788
73042f01 789 sigmaRphi=SigmaY2(rpad,tanth,pt);
790 sigmaZ =SigmaZ2(rpad,tanth );
fe4da5cc 791
792 // cluster widths
793
73042f01 794 clRphi=kACrphi-kBCrphi*rpad*tanth+kCCrphi*ratio*ratio;
795 clZ=kACz-kBCz*rpad*tanth+kCCz*tanth*tanth;
fe4da5cc 796
797 // temporary protection
798
73042f01 799 if(sigmaRphi < 0.) sigmaRphi=0.4e-3;
800 if(sigmaZ < 0.) sigmaZ=0.4e-3;
801 if(clRphi < 0.) clRphi=2.5e-3;
802 if(clZ < 0.) clZ=2.5e-5;
fe4da5cc 803
804 //
cc80f89e 805
806 //
807 // smearing --> rotate to the 1 (13) or to the 25 (49) sector,
fe4da5cc 808 // then the inaccuracy in a X-Y plane is only along Y (pad row)!
809 //
94de3818 810 Float_t xprim= tpcHit->X()*cph + tpcHit->Y()*sph;
811 Float_t yprim=-tpcHit->X()*sph + tpcHit->Y()*cph;
73042f01 812 xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigmaRphi)); // y
813 Float_t alpha=(isec < fTPCParam->GetNInnerSector()) ?
814 fTPCParam->GetInnerAngle() : fTPCParam->GetOuterAngle();
815 Float_t ymax=xprim*TMath::Tan(0.5*alpha);
816 if (TMath::Abs(xyz[0])>ymax) xyz[0]=yprim;
94de3818 817 xyz[1]=gRandom->Gaus(tpcHit->Z(),TMath::Sqrt(sigmaZ)); // z
818 if (TMath::Abs(xyz[1])>fTPCParam->GetZLength()) xyz[1]=tpcHit->Z();
cc80f89e 819 xyz[2]=tpcHit->fQ; // q
73042f01 820 xyz[3]=sigmaRphi; // fSigmaY2
821 xyz[4]=sigmaZ; // fSigmaZ2
822
823 AliTPCClustersRow *clrow=carray.GetRow(sector,tpcHit->fPadRow);
824 if (!clrow) clrow=carray.CreateRow(sector,tpcHit->fPadRow);
825
94de3818 826 Int_t tracks[3]={tpcHit->Track(), -1, -1};
73042f01 827 AliTPCcluster cluster(xyz,tracks);
828
829 clrow->InsertCluster(&cluster); nclusters++;
830
fe4da5cc 831 } // end of loop over hits
73042f01 832
833 } // end of loop over tracks
834
835 Int_t nrows=fTPCParam->GetNRow(isec);
836 for (Int_t irow=0; irow<nrows; irow++) {
837 AliTPCClustersRow *clrow=carray.GetRow(isec,irow);
838 if (!clrow) continue;
839 carray.StoreRow(isec,irow);
840 carray.ClearRow(isec,irow);
841 }
842
cc80f89e 843 } // end of loop over sectors
73042f01 844
845 cerr<<"Number of made clusters : "<<nclusters<<" \n";
846
847 carray.GetTree()->Write();
848
849 savedir->cd(); //switch back to the input file
cc80f89e 850
851} // end of function
852
853//_________________________________________________________________
854void AliTPC::Hits2ExactClustersSector(Int_t isec)
855{
856 //--------------------------------------------------------
857 //calculate exact cross point of track and given pad row
858 //resulting values are expressed in "digit" coordinata
859 //--------------------------------------------------------
860
861 //-----------------------------------------------------------------
862 // Origin: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
863 //-----------------------------------------------------------------
864 //
865 if (fClustersArray==0){
866 return;
867 }
868 //
869 TParticle *particle; // pointer to a given particle
870 AliTPChit *tpcHit; // pointer to a sigle TPC hit
73042f01 871 TClonesArray *particles; //pointer to the particle list
cc80f89e 872 Int_t sector,nhits;
873 Int_t ipart;
73042f01 874 const Int_t kcmaxhits=30000;
875 TVector * xxxx = new TVector(kcmaxhits*4);
cc80f89e 876 TVector & xxx = *xxxx;
73042f01 877 Int_t maxhits = kcmaxhits;
cc80f89e 878 //construct array for each padrow
879 for (Int_t i=0; i<fTPCParam->GetNRow(isec);i++)
880 fClustersArray->CreateRow(isec,i);
fe4da5cc 881
cc80f89e 882 //---------------------------------------------------------------
883 // Get the access to the tracks
884 //---------------------------------------------------------------
885
73042f01 886 TTree *tH = gAlice->TreeH();
887 Stat_t ntracks = tH->GetEntries();
888 particles=gAlice->Particles();
889 Int_t npart = particles->GetEntriesFast();
cc80f89e 890
891 //------------------------------------------------------------
892 // Loop over tracks
893 //------------------------------------------------------------
fe4da5cc 894
cc80f89e 895 for(Int_t track=0;track<ntracks;track++){
896 ResetHits();
73042f01 897 tH->GetEvent(track);
cc80f89e 898 //
899 // Get number of the TPC hits and a pointer
900 // to the particles
901 //
902 nhits=fHits->GetEntriesFast();
903 //
904 // Loop over hits
905 //
906 Int_t currentIndex=0;
907 Int_t lastrow=-1; //last writen row
908 for(Int_t hit=0;hit<nhits;hit++){
909 tpcHit=(AliTPChit*)fHits->UncheckedAt(hit);
910 if (tpcHit==0) continue;
911 sector=tpcHit->fSector; // sector number
912 if(sector != isec) continue;
94de3818 913 ipart=tpcHit->Track();
73042f01 914 if (ipart<npart) particle=(TParticle*)particles->UncheckedAt(ipart);
cc80f89e 915
916 //find row number
917
94de3818 918 Float_t x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()};
cc80f89e 919 Int_t index[3]={1,isec,0};
920 Int_t currentrow = fTPCParam->GetPadRow(x,index) ;
921 if (currentrow<0) continue;
922 if (lastrow<0) lastrow=currentrow;
923 if (currentrow==lastrow){
924 if ( currentIndex>=maxhits){
73042f01 925 maxhits+=kcmaxhits;
cc80f89e 926 xxx.ResizeTo(4*maxhits);
927 }
928 xxx(currentIndex*4)=x[0];
929 xxx(currentIndex*4+1)=x[1];
930 xxx(currentIndex*4+2)=x[2];
931 xxx(currentIndex*4+3)=tpcHit->fQ;
932 currentIndex++;
933 }
934 else
935 if (currentIndex>2){
936 Float_t sumx=0;
937 Float_t sumx2=0;
938 Float_t sumx3=0;
939 Float_t sumx4=0;
940 Float_t sumy=0;
941 Float_t sumxy=0;
942 Float_t sumx2y=0;
943 Float_t sumz=0;
944 Float_t sumxz=0;
945 Float_t sumx2z=0;
946 Float_t sumq=0;
947 for (Int_t index=0;index<currentIndex;index++){
948 Float_t x,x2,x3,x4;
949 x=x2=x3=x4=xxx(index*4);
950 x2*=x;
951 x3*=x2;
952 x4*=x3;
953 sumx+=x;
954 sumx2+=x2;
955 sumx3+=x3;
956 sumx4+=x4;
957 sumy+=xxx(index*4+1);
958 sumxy+=xxx(index*4+1)*x;
959 sumx2y+=xxx(index*4+1)*x2;
960 sumz+=xxx(index*4+2);
961 sumxz+=xxx(index*4+2)*x;
962 sumx2z+=xxx(index*4+2)*x2;
963 sumq+=xxx(index*4+3);
964 }
73042f01 965 Float_t centralPad = (fTPCParam->GetNPads(isec,lastrow)-1)/2;
cc80f89e 966 Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+
967 sumx2*(sumx*sumx3-sumx2*sumx2);
968
969 Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+
970 sumx2*(sumxy*sumx3-sumx2y*sumx2);
971 Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+
972 sumx2*(sumxz*sumx3-sumx2z*sumx2);
973
974 Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+
975 sumx2*(sumx*sumx2y-sumx2*sumxy);
976 Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+
977 sumx2*(sumx*sumx2z-sumx2*sumxz);
978
73042f01 979 Float_t y=detay/det+centralPad;
cc80f89e 980 Float_t z=detaz/det;
981 Float_t by=detby/det; //y angle
982 Float_t bz=detbz/det; //z angle
983 sumy/=Float_t(currentIndex);
984 sumz/=Float_t(currentIndex);
985 AliCluster cl;
986 cl.fX=z;
987 cl.fY=y;
988 cl.fQ=sumq;
989 cl.fSigmaX2=bz;
990 cl.fSigmaY2=by;
991 cl.fTracks[0]=ipart;
992
993 AliTPCClustersRow * row = (fClustersArray->GetRow(isec,lastrow));
994 if (row!=0) row->InsertCluster(&cl);
995 currentIndex=0;
996 lastrow=currentrow;
997 } //end of calculating cluster for given row
998
999
1000
1001 } // end of loop over hits
1002 } // end of loop over tracks
1003 //write padrows to tree
1004 for (Int_t ii=0; ii<fTPCParam->GetNRow(isec);ii++) {
1005 fClustersArray->StoreRow(isec,ii);
1006 fClustersArray->ClearRow(isec,ii);
1007 }
1008 xxxx->Delete();
1009
fe4da5cc 1010}
1011
cc80f89e 1012//__________________________________________________________________
8c555625 1013void AliTPC::Hits2Digits()
1014{
8c555625 1015 //----------------------------------------------------
cc80f89e 1016 // Loop over all sectors
1017 //----------------------------------------------------
1018
1019 if(fTPCParam == 0){
1020 printf("AliTPCParam MUST be created firstly\n");
1021 return;
1022 }
1023
1024 for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++) Hits2DigitsSector(isec);
1025
8c555625 1026}
1027
1028
fe4da5cc 1029//_____________________________________________________________________________
8c555625 1030void AliTPC::Hits2DigitsSector(Int_t isec)
fe4da5cc 1031{
8c555625 1032 //-------------------------------------------------------------------
fe4da5cc 1033 // TPC conversion from hits to digits.
8c555625 1034 //-------------------------------------------------------------------
1035
1036 //-----------------------------------------------------------------
1037 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1038 //-----------------------------------------------------------------
1039
fe4da5cc 1040 //-------------------------------------------------------
8c555625 1041 // Get the access to the track hits
fe4da5cc 1042 //-------------------------------------------------------
8c555625 1043
cc80f89e 1044
73042f01 1045 TTree *tH = gAlice->TreeH(); // pointer to the hits tree
1046 Stat_t ntracks = tH->GetEntries();
8c555625 1047
1048 if( ntracks > 0){
1049
1050 //-------------------------------------------
1051 // Only if there are any tracks...
1052 //-------------------------------------------
1053
8c555625 1054 TObjArray **row;
fe4da5cc 1055
8c555625 1056 printf("*** Processing sector number %d ***\n",isec);
1057
1058 Int_t nrows =fTPCParam->GetNRow(isec);
1059
1060 row= new TObjArray* [nrows];
fe4da5cc 1061
73042f01 1062 MakeSector(isec,nrows,tH,ntracks,row);
8c555625 1063
1064 //--------------------------------------------------------
1065 // Digitize this sector, row by row
1066 // row[i] is the pointer to the TObjArray of TVectors,
1067 // each one containing electrons accepted on this
1068 // row, assigned into tracks
1069 //--------------------------------------------------------
1070
1071 Int_t i;
1072
cc80f89e 1073 if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree();
8c555625 1074
cc80f89e 1075 for (i=0;i<nrows;i++){
8c555625 1076
cc80f89e 1077 AliDigits * dig = fDigitsArray->CreateRow(isec,i);
8c555625 1078
cc80f89e 1079 DigitizeRow(i,isec,row);
8c555625 1080
cc80f89e 1081 fDigitsArray->StoreRow(isec,i);
8c555625 1082
73042f01 1083 Int_t ndig = dig->GetDigitSize();
cc80f89e 1084
1085 printf("*** Sector, row, compressed digits %d %d %d ***\n",isec,i,ndig);
1086
1087 fDigitsArray->ClearRow(isec,i);
8c555625 1088
cc80f89e 1089
8c555625 1090 } // end of the sector digitization
8c555625 1091
cc80f89e 1092 for(i=0;i<nrows;i++){
1093 row[i]->Delete();
1094 }
1095
8c555625 1096 delete [] row; // delete the array of pointers to TObjArray-s
1097
1098 } // ntracks >0
8c555625 1099
cc80f89e 1100} // end of Hits2DigitsSector
8c555625 1101
8c555625 1102
8c555625 1103//_____________________________________________________________________________
cc80f89e 1104void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows)
8c555625 1105{
1106 //-----------------------------------------------------------
1107 // Single row digitization, coupling from the neighbouring
1108 // rows taken into account
1109 //-----------------------------------------------------------
1110
1111 //-----------------------------------------------------------------
1112 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
cc80f89e 1113 // Modified: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
8c555625 1114 //-----------------------------------------------------------------
1115
1116
8c555625 1117 Float_t zerosup = fTPCParam->GetZeroSup();
1118 Int_t nrows =fTPCParam->GetNRow(isec);
cc80f89e 1119 fCurrentIndex[1]= isec;
8c555625 1120
8c555625 1121
73042f01 1122 Int_t nofPads = fTPCParam->GetNPads(isec,irow);
1123 Int_t nofTbins = fTPCParam->GetMaxTBin();
1124 Int_t indexRange[4];
8c555625 1125 //
1126 // Integrated signal for this row
1127 // and a single track signal
cc80f89e 1128 //
73042f01 1129 TMatrix *m1 = new TMatrix(0,nofPads,0,nofTbins); // integrated
1130 TMatrix *m2 = new TMatrix(0,nofPads,0,nofTbins); // single
8c555625 1131 //
73042f01 1132 TMatrix &total = *m1;
8c555625 1133
1134 // Array of pointers to the label-signal list
1135
73042f01 1136 Int_t nofDigits = nofPads*nofTbins; // number of digits for this row
1137 Float_t **pList = new Float_t* [nofDigits];
8c555625 1138
1139 Int_t lp;
cc80f89e 1140 Int_t i1;
73042f01 1141 for(lp=0;lp<nofDigits;lp++)pList[lp]=0; // set all pointers to NULL
8c555625 1142 //
cc80f89e 1143 //calculate signal
1144 //
1145 Int_t row1 = TMath::Max(irow-fTPCParam->GetNCrossRows(),0);
1146 Int_t row2 = TMath::Min(irow+fTPCParam->GetNCrossRows(),nrows-1);
1147 for (Int_t row= row1;row<=row2;row++){
1148 Int_t nTracks= rows[row]->GetEntries();
1149 for (i1=0;i1<nTracks;i1++){
1150 fCurrentIndex[2]= row;
1151 fCurrentIndex[3]=irow;
1152 if (row==irow){
1153 m2->Zero(); // clear single track signal matrix
73042f01 1154 Float_t trackLabel = GetSignal(rows[row],i1,m2,m1,indexRange);
1155 GetList(trackLabel,nofPads,m2,indexRange,pList);
cc80f89e 1156 }
73042f01 1157 else GetSignal(rows[row],i1,0,m1,indexRange);
cc80f89e 1158 }
8c555625 1159 }
cc80f89e 1160
8c555625 1161 Int_t tracks[3];
8c555625 1162
cc80f89e 1163 AliDigits *dig = fDigitsArray->GetRow(isec,irow);
73042f01 1164 for(Int_t ip=0;ip<nofPads;ip++){
1165 for(Int_t it=0;it<nofTbins;it++){
8c555625 1166
73042f01 1167 Float_t q = total(ip,it);
8c555625 1168
73042f01 1169 Int_t gi =it*nofPads+ip; // global index
8c555625 1170
cc80f89e 1171 q = gRandom->Gaus(q,fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac());
8c555625 1172
cc80f89e 1173 q = (Int_t)q;
1174
1175 if(q <=zerosup) continue; // do not fill zeros
73042f01 1176 if(q > fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat(); // saturation
8c555625 1177
1178 //
1179 // "real" signal or electronic noise (list = -1)?
1180 //
1181
1182 for(Int_t j1=0;j1<3;j1++){
1183 tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -1;
1184 }
1185
cc80f89e 1186//Begin_Html
1187/*
1188 <A NAME="AliDigits"></A>
1189 using of AliDigits object
1190*/
1191//End_Html
1192 dig->SetDigitFast((Short_t)q,it,ip);
1193 if (fDigitsArray->IsSimulated())
1194 {
1195 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[0],it,ip,0);
1196 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[1],it,ip,1);
1197 ((AliSimDigits*)dig)->SetTrackIDFast(tracks[2],it,ip,2);
1198 }
1199
8c555625 1200
1201 } // end of loop over time buckets
1202 } // end of lop over pads
1203
1204 //
1205 // This row has been digitized, delete nonused stuff
1206 //
1207
73042f01 1208 for(lp=0;lp<nofDigits;lp++){
8c555625 1209 if(pList[lp]) delete [] pList[lp];
1210 }
1211
1212 delete [] pList;
1213
1214 delete m1;
1215 delete m2;
cc80f89e 1216 // delete m3;
8c555625 1217
1218} // end of DigitizeRow
cc80f89e 1219
8c555625 1220//_____________________________________________________________________________
cc80f89e 1221
1222Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, TMatrix *m1, TMatrix *m2,
73042f01 1223 Int_t *indexRange)
8c555625 1224{
1225
1226 //---------------------------------------------------------------
1227 // Calculates 2-D signal (pad,time) for a single track,
1228 // returns a pointer to the signal matrix and the track label
1229 // No digitization is performed at this level!!!
1230 //---------------------------------------------------------------
1231
1232 //-----------------------------------------------------------------
1233 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
cc80f89e 1234 // Modified: Marian Ivanov
8c555625 1235 //-----------------------------------------------------------------
1236
1237 TVector *tv;
8c555625 1238
8c555625 1239 tv = (TVector*)p1->At(ntr); // pointer to a track
1240 TVector &v = *tv;
1241
1242 Float_t label = v(0);
73042f01 1243 Int_t centralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3])-1)/2;
8c555625 1244
8c555625 1245 Int_t nElectrons = (tv->GetNrows()-1)/4;
73042f01 1246 indexRange[0]=9999; // min pad
1247 indexRange[1]=-1; // max pad
1248 indexRange[2]=9999; //min time
1249 indexRange[3]=-1; // max time
8c555625 1250
cc80f89e 1251 // Float_t IneffFactor = 0.5; // inefficiency in the gain close to the edge, as above
1252
1253 TMatrix &signal = *m1;
1254 TMatrix &total = *m2;
8c555625 1255 //
1256 // Loop over all electrons
1257 //
8c555625 1258 for(Int_t nel=0; nel<nElectrons; nel++){
cc80f89e 1259 Int_t idx=nel*4;
1260 Float_t aval = v(idx+4);
1261 Float_t eltoadcfac=aval*fTPCParam->GetTotalNormFac();
1262 Float_t xyz[3]={v(idx+1),v(idx+2),v(idx+3)};
1263 Int_t n = fTPCParam->CalcResponse(xyz,fCurrentIndex,fCurrentIndex[3]);
8c555625 1264
cc80f89e 1265 if (n>0) for (Int_t i =0; i<n; i++){
1266 Int_t *index = fTPCParam->GetResBin(i);
73042f01 1267 Int_t pad=index[1]+centralPad; //in digit coordinates central pad has coordinate 0
cc80f89e 1268 if ( ( pad<(fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3]))) && (pad>0)) {
1269 Int_t time=index[2];
1270 Float_t weight = fTPCParam->GetResWeight(i); //we normalise response to ADC channel
1271 weight *= eltoadcfac;
1272
1273 if (m1!=0) signal(pad,time)+=weight;
1274 total(pad,time)+=weight;
73042f01 1275 indexRange[0]=TMath::Min(indexRange[0],pad);
1276 indexRange[1]=TMath::Max(indexRange[1],pad);
1277 indexRange[2]=TMath::Min(indexRange[2],time);
1278 indexRange[3]=TMath::Max(indexRange[3],time);
cc80f89e 1279 }
1280 }
8c555625 1281 } // end of loop over electrons
cc80f89e 1282
8c555625 1283 return label; // returns track label when finished
1284}
1285
1286//_____________________________________________________________________________
73042f01 1287void AliTPC::GetList(Float_t label,Int_t np,TMatrix *m,Int_t *indexRange,
8c555625 1288 Float_t **pList)
1289{
1290 //----------------------------------------------------------------------
1291 // Updates the list of tracks contributing to digits for a given row
1292 //----------------------------------------------------------------------
1293
1294 //-----------------------------------------------------------------
1295 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1296 //-----------------------------------------------------------------
1297
1298 TMatrix &signal = *m;
1299
1300 // lop over nonzero digits
1301
73042f01 1302 for(Int_t it=indexRange[2];it<indexRange[3]+1;it++){
1303 for(Int_t ip=indexRange[0];ip<indexRange[1]+1;ip++){
8c555625 1304
1305
921bf71a 1306 // accept only the contribution larger than 500 electrons (1/2 s_noise)
1307
cc80f89e 1308 if(signal(ip,it)<0.5) continue;
921bf71a 1309
1310
73042f01 1311 Int_t globalIndex = it*np+ip; // globalIndex starts from 0!
8c555625 1312
73042f01 1313 if(!pList[globalIndex]){
8c555625 1314
1315 //
1316 // Create new list (6 elements - 3 signals and 3 labels),
8c555625 1317 //
1318
73042f01 1319 pList[globalIndex] = new Float_t [6];
8c555625 1320
1321 // set list to -1
1322
73042f01 1323 *pList[globalIndex] = -1.;
1324 *(pList[globalIndex]+1) = -1.;
1325 *(pList[globalIndex]+2) = -1.;
1326 *(pList[globalIndex]+3) = -1.;
1327 *(pList[globalIndex]+4) = -1.;
1328 *(pList[globalIndex]+5) = -1.;
8c555625 1329
1330
73042f01 1331 *pList[globalIndex] = label;
1332 *(pList[globalIndex]+3) = signal(ip,it);
8c555625 1333 }
1334 else{
1335
1336 // check the signal magnitude
1337
73042f01 1338 Float_t highest = *(pList[globalIndex]+3);
1339 Float_t middle = *(pList[globalIndex]+4);
1340 Float_t lowest = *(pList[globalIndex]+5);
8c555625 1341
1342 //
1343 // compare the new signal with already existing list
1344 //
1345
1346 if(signal(ip,it)<lowest) continue; // neglect this track
1347
1348 //
1349
1350 if (signal(ip,it)>highest){
73042f01 1351 *(pList[globalIndex]+5) = middle;
1352 *(pList[globalIndex]+4) = highest;
1353 *(pList[globalIndex]+3) = signal(ip,it);
8c555625 1354
73042f01 1355 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
1356 *(pList[globalIndex]+1) = *pList[globalIndex];
1357 *pList[globalIndex] = label;
8c555625 1358 }
1359 else if (signal(ip,it)>middle){
73042f01 1360 *(pList[globalIndex]+5) = middle;
1361 *(pList[globalIndex]+4) = signal(ip,it);
8c555625 1362
73042f01 1363 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
1364 *(pList[globalIndex]+1) = label;
8c555625 1365 }
1366 else{
73042f01 1367 *(pList[globalIndex]+5) = signal(ip,it);
1368 *(pList[globalIndex]+2) = label;
8c555625 1369 }
1370 }
1371
1372 } // end of loop over pads
1373 } // end of loop over time bins
1374
1375
1376
8c555625 1377}//end of GetList
1378//___________________________________________________________________
1379void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
1380 Stat_t ntracks,TObjArray **row)
1381{
1382
1383 //-----------------------------------------------------------------
1384 // Prepares the sector digitization, creates the vectors of
1385 // tracks for each row of this sector. The track vector
1386 // contains the track label and the position of electrons.
1387 //-----------------------------------------------------------------
1388
1389 //-----------------------------------------------------------------
1390 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1391 //-----------------------------------------------------------------
1392
cc80f89e 1393 Float_t gasgain = fTPCParam->GetGasGain();
8c555625 1394 Int_t i;
cc80f89e 1395 Float_t xyz[4];
8c555625 1396
1397 AliTPChit *tpcHit; // pointer to a sigle TPC hit
1398
1399 //----------------------------------------------
1400 // Create TObjArray-s, one for each row,
1401 // each TObjArray will store the TVectors
1402 // of electrons, one TVector per each track.
1403 //----------------------------------------------
1404
f74bb6f5 1405 Int_t *nofElectrons = new Int_t [nrows]; // electron counter for each row
1406 TVector **tracks = new TVector* [nrows]; //pointers to the track vectors
8c555625 1407 for(i=0; i<nrows; i++){
1408 row[i] = new TObjArray;
f74bb6f5 1409 nofElectrons[i]=0;
1410 tracks[i]=0;
8c555625 1411 }
8c555625 1412
37831078 1413
1414
8c555625 1415 //--------------------------------------------------------------------
1416 // Loop over tracks, the "track" contains the full history
1417 //--------------------------------------------------------------------
1418
1419 Int_t previousTrack,currentTrack;
1420 previousTrack = -1; // nothing to store so far!
1421
1422 for(Int_t track=0;track<ntracks;track++){
1423
1424 ResetHits();
1425
1426 TH->GetEvent(track); // get next track
1427 Int_t nhits = fHits->GetEntriesFast(); // get number of hits for this track
1428
1429 if(nhits == 0) continue; // no hits in the TPC for this track
1430
1431 //--------------------------------------------------------------
1432 // Loop over hits
1433 //--------------------------------------------------------------
1434
1435 for(Int_t hit=0;hit<nhits;hit++){
1436
1437 tpcHit = (AliTPChit*)fHits->UncheckedAt(hit); // get a pointer to a hit
1438
1439 Int_t sector=tpcHit->fSector; // sector number
cc80f89e 1440 if(sector != isec) continue;
8c555625 1441
94de3818 1442 currentTrack = tpcHit->Track(); // track number
8c555625 1443 if(currentTrack != previousTrack){
1444
1445 // store already filled fTrack
1446
1447 for(i=0;i<nrows;i++){
1448 if(previousTrack != -1){
73042f01 1449 if(nofElectrons[i]>0){
cc80f89e 1450 TVector &v = *tracks[i];
8c555625 1451 v(0) = previousTrack;
73042f01 1452 tracks[i]->ResizeTo(4*nofElectrons[i]+1); // shrink if necessary
cc80f89e 1453 row[i]->Add(tracks[i]);
8c555625 1454 }
1455 else{
cc80f89e 1456 delete tracks[i]; // delete empty TVector
1457 tracks[i]=0;
8c555625 1458 }
1459 }
1460
73042f01 1461 nofElectrons[i]=0;
cc80f89e 1462 tracks[i] = new TVector(481); // TVectors for the next fTrack
8c555625 1463
1464 } // end of loop over rows
1465
1466 previousTrack=currentTrack; // update track label
1467 }
1468
73042f01 1469 Int_t qI = (Int_t) (tpcHit->fQ); // energy loss (number of electrons)
8c555625 1470
1471 //---------------------------------------------------
1472 // Calculate the electron attachment probability
1473 //---------------------------------------------------
1474
cc80f89e 1475
94de3818 1476 Float_t time = 1.e6*(fTPCParam->GetZLength()-TMath::Abs(tpcHit->Z()))
cc80f89e 1477 /fTPCParam->GetDriftV();
8c555625 1478 // in microseconds!
73042f01 1479 Float_t attProb = fTPCParam->GetAttCoef()*
8c555625 1480 fTPCParam->GetOxyCont()*time; // fraction!
1481
1482 //-----------------------------------------------
1483 // Loop over electrons
1484 //-----------------------------------------------
cc80f89e 1485 Int_t index[3];
1486 index[1]=isec;
73042f01 1487 for(Int_t nel=0;nel<qI;nel++){
8c555625 1488 // skip if electron lost due to the attachment
73042f01 1489 if((gRandom->Rndm(0)) < attProb) continue; // electron lost!
94de3818 1490 xyz[0]=tpcHit->X();
1491 xyz[1]=tpcHit->Y();
1492 xyz[2]=tpcHit->Z();
cc80f89e 1493 xyz[3]= (Float_t) (-gasgain*TMath::Log(gRandom->Rndm()));
1494 index[0]=1;
1495
1496 TransportElectron(xyz,index); //MI change -august
73042f01 1497 Int_t rowNumber;
cc80f89e 1498 fTPCParam->GetPadRow(xyz,index); //MI change august
73042f01 1499 rowNumber = index[2];
cc80f89e 1500 //transform position to local digit coordinates
1501 //relative to nearest pad row
73042f01 1502 if ((rowNumber<0)||rowNumber>=fTPCParam->GetNRow(isec)) continue;
1503 nofElectrons[rowNumber]++;
8c555625 1504 //----------------------------------
1505 // Expand vector if necessary
1506 //----------------------------------
73042f01 1507 if(nofElectrons[rowNumber]>120){
1508 Int_t range = tracks[rowNumber]->GetNrows();
1509 if((nofElectrons[rowNumber])>(range-1)/4){
cc80f89e 1510
73042f01 1511 tracks[rowNumber]->ResizeTo(range+400); // Add 100 electrons
fe4da5cc 1512 }
1513 }
1514
73042f01 1515 TVector &v = *tracks[rowNumber];
1516 Int_t idx = 4*nofElectrons[rowNumber]-3;
8c555625 1517
cc80f89e 1518 v(idx)= xyz[0]; // X - pad row coordinate
1519 v(idx+1)=xyz[1]; // Y - pad coordinate (along the pad-row)
1520 v(idx+2)=xyz[2]; // Z - time bin coordinate
1521 v(idx+3)=xyz[3]; // avalanche size
8c555625 1522 } // end of loop over electrons
1523
1524 } // end of loop over hits
1525 } // end of loop over tracks
1526
1527 //
1528 // store remaining track (the last one) if not empty
1529 //
1530
1531 for(i=0;i<nrows;i++){
73042f01 1532 if(nofElectrons[i]>0){
cc80f89e 1533 TVector &v = *tracks[i];
8c555625 1534 v(0) = previousTrack;
73042f01 1535 tracks[i]->ResizeTo(4*nofElectrons[i]+1); // shrink if necessary
cc80f89e 1536 row[i]->Add(tracks[i]);
fe4da5cc 1537 }
1538 else{
cc80f89e 1539 delete tracks[i];
1540 tracks[i]=0;
8c555625 1541 }
1542 }
1543
cc80f89e 1544 delete [] tracks;
73042f01 1545 delete [] nofElectrons;
8c555625 1546
8c555625 1547
cc80f89e 1548} // end of MakeSector
8c555625 1549
fe4da5cc 1550
1551//_____________________________________________________________________________
1552void AliTPC::Init()
1553{
1554 //
1555 // Initialise TPC detector after definition of geometry
1556 //
1557 Int_t i;
1558 //
1559 printf("\n");
1560 for(i=0;i<35;i++) printf("*");
1561 printf(" TPC_INIT ");
1562 for(i=0;i<35;i++) printf("*");
1563 printf("\n");
1564 //
1565 for(i=0;i<80;i++) printf("*");
1566 printf("\n");
1567}
1568
1569//_____________________________________________________________________________
1570void AliTPC::MakeBranch(Option_t* option)
1571{
1572 //
1573 // Create Tree branches for the TPC.
1574 //
1575 Int_t buffersize = 4000;
1576 char branchname[10];
1577 sprintf(branchname,"%s",GetName());
1578
1579 AliDetector::MakeBranch(option);
1580
73042f01 1581 char *d = strstr(option,"D");
fe4da5cc 1582
73042f01 1583 if (fDigits && gAlice->TreeD() && d) {
fe4da5cc 1584 gAlice->TreeD()->Branch(branchname,&fDigits, buffersize);
1585 printf("Making Branch %s for digits\n",branchname);
1586 }
fe4da5cc 1587}
1588
1589//_____________________________________________________________________________
1590void AliTPC::ResetDigits()
1591{
1592 //
1593 // Reset number of digits and the digits array for this detector
fe4da5cc 1594 //
1595 fNdigits = 0;
cc80f89e 1596 if (fDigits) fDigits->Clear();
fe4da5cc 1597}
1598
1599//_____________________________________________________________________________
1600void AliTPC::SetSecAL(Int_t sec)
1601{
8c555625 1602 //---------------------------------------------------
fe4da5cc 1603 // Activate/deactivate selection for lower sectors
8c555625 1604 //---------------------------------------------------
1605
1606 //-----------------------------------------------------------------
1607 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1608 //-----------------------------------------------------------------
1609
fe4da5cc 1610 fSecAL = sec;
1611}
1612
1613//_____________________________________________________________________________
1614void AliTPC::SetSecAU(Int_t sec)
1615{
8c555625 1616 //----------------------------------------------------
fe4da5cc 1617 // Activate/deactivate selection for upper sectors
8c555625 1618 //---------------------------------------------------
1619
1620 //-----------------------------------------------------------------
1621 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1622 //-----------------------------------------------------------------
1623
fe4da5cc 1624 fSecAU = sec;
1625}
1626
1627//_____________________________________________________________________________
1628void AliTPC::SetSecLows(Int_t s1,Int_t s2,Int_t s3,Int_t s4,Int_t s5, Int_t s6)
1629{
8c555625 1630 //----------------------------------------
fe4da5cc 1631 // Select active lower sectors
8c555625 1632 //----------------------------------------
1633
1634 //-----------------------------------------------------------------
1635 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1636 //-----------------------------------------------------------------
1637
fe4da5cc 1638 fSecLows[0] = s1;
1639 fSecLows[1] = s2;
1640 fSecLows[2] = s3;
1641 fSecLows[3] = s4;
1642 fSecLows[4] = s5;
1643 fSecLows[5] = s6;
1644}
1645
1646//_____________________________________________________________________________
1647void AliTPC::SetSecUps(Int_t s1,Int_t s2,Int_t s3,Int_t s4,Int_t s5, Int_t s6,
1648 Int_t s7, Int_t s8 ,Int_t s9 ,Int_t s10,
1649 Int_t s11 , Int_t s12)
1650{
8c555625 1651 //--------------------------------
fe4da5cc 1652 // Select active upper sectors
8c555625 1653 //--------------------------------
1654
1655 //-----------------------------------------------------------------
1656 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1657 //-----------------------------------------------------------------
1658
fe4da5cc 1659 fSecUps[0] = s1;
1660 fSecUps[1] = s2;
1661 fSecUps[2] = s3;
1662 fSecUps[3] = s4;
1663 fSecUps[4] = s5;
1664 fSecUps[5] = s6;
1665 fSecUps[6] = s7;
1666 fSecUps[7] = s8;
1667 fSecUps[8] = s9;
1668 fSecUps[9] = s10;
1669 fSecUps[10] = s11;
1670 fSecUps[11] = s12;
1671}
1672
1673//_____________________________________________________________________________
1674void AliTPC::SetSens(Int_t sens)
1675{
8c555625 1676
1677 //-------------------------------------------------------------
1678 // Activates/deactivates the sensitive strips at the center of
1679 // the pad row -- this is for the space-point resolution calculations
1680 //-------------------------------------------------------------
1681
1682 //-----------------------------------------------------------------
1683 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
1684 //-----------------------------------------------------------------
1685
fe4da5cc 1686 fSens = sens;
1687}
4b0fdcad 1688
73042f01 1689void AliTPC::SetSide(Float_t side=0.)
4b0fdcad 1690{
73042f01 1691 // choice of the TPC side
1692
4b0fdcad 1693 fSide = side;
1694
1695}
1283eee5 1696//____________________________________________________________________________
1697void AliTPC::SetGasMixt(Int_t nc,Int_t c1,Int_t c2,Int_t c3,Float_t p1,
1698 Float_t p2,Float_t p3)
1699{
fe4da5cc 1700
73042f01 1701 // gax mixture definition
1702
1283eee5 1703 fNoComp = nc;
1704
1705 fMixtComp[0]=c1;
1706 fMixtComp[1]=c2;
1707 fMixtComp[2]=c3;
1708
1709 fMixtProp[0]=p1;
1710 fMixtProp[1]=p2;
1711 fMixtProp[2]=p3;
1712
1713
cc80f89e 1714}
1715//_____________________________________________________________________________
1716
1717void AliTPC::TransportElectron(Float_t *xyz, Int_t *index)
1718{
1719 //
1720 // electron transport taking into account:
1721 // 1. diffusion,
1722 // 2.ExB at the wires
1723 // 3. nonisochronity
1724 //
1725 // xyz and index must be already transformed to system 1
1726 //
1727
1728 fTPCParam->Transform1to2(xyz,index);
1729
1730 //add diffusion
1731 Float_t driftl=xyz[2];
1732 if(driftl<0.01) driftl=0.01;
1733 driftl=TMath::Sqrt(driftl);
73042f01 1734 Float_t sigT = driftl*(fTPCParam->GetDiffT());
1735 Float_t sigL = driftl*(fTPCParam->GetDiffL());
1736 xyz[0]=gRandom->Gaus(xyz[0],sigT);
1737 xyz[1]=gRandom->Gaus(xyz[1],sigT);
1738 xyz[2]=gRandom->Gaus(xyz[2],sigL);
cc80f89e 1739
1740 // ExB
1741
1742 if (fTPCParam->GetMWPCReadout()==kTRUE){
1743 Float_t x1=xyz[0];
1744 fTPCParam->Transform2to2NearestWire(xyz,index);
1745 Float_t dx=xyz[0]-x1;
1746 xyz[1]+=dx*(fTPCParam->GetOmegaTau());
1747 }
1748 //add nonisochronity (not implemented yet)
1749
1283eee5 1750}
fe4da5cc 1751//_____________________________________________________________________________
1752void AliTPC::Streamer(TBuffer &R__b)
1753{
1754 //
1755 // Stream an object of class AliTPC.
1756 //
1757 if (R__b.IsReading()) {
1758 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1759 AliDetector::Streamer(R__b);
1760 if (R__v < 2) return;
1761 R__b >> fNsectors;
fe4da5cc 1762 } else {
1763 R__b.WriteVersion(AliTPC::IsA());
1764 AliDetector::Streamer(R__b);
1765 R__b << fNsectors;
fe4da5cc 1766 }
1767}
1768
fe4da5cc 1769ClassImp(AliTPCdigit)
1770
1771//_____________________________________________________________________________
1772AliTPCdigit::AliTPCdigit(Int_t *tracks, Int_t *digits):
1773 AliDigit(tracks)
1774{
1775 //
1776 // Creates a TPC digit object
1777 //
1778 fSector = digits[0];
1779 fPadRow = digits[1];
1780 fPad = digits[2];
1781 fTime = digits[3];
1782 fSignal = digits[4];
1783}
1784
1785
1786ClassImp(AliTPChit)
1787
1788//_____________________________________________________________________________
1789AliTPChit::AliTPChit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits):
1790AliHit(shunt,track)
1791{
1792 //
1793 // Creates a TPC hit object
1794 //
1795 fSector = vol[0];
1796 fPadRow = vol[1];
1797 fX = hits[0];
1798 fY = hits[1];
1799 fZ = hits[2];
1800 fQ = hits[3];
1801}
1802
8c555625 1803