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