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