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