]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPC.cxx
Processing of many events possible now
[u/mrichter/AliRoot.git] / TPC / AliTPC.cxx
index 4a60d9e7c5166c095dc012b13270d8423f6dfde4..88b7c6cd88845c48d94a1e5fcc4241b8b8209edc 100644 (file)
 
 /*
 $Log$
+Revision 1.37  2001/06/12 07:17:18  kowal2
+Hits2SDigits method implemented (summable digits)
+
+Revision 1.36  2001/05/16 14:57:25  alibrary
+New files for folders and Stack
+
+Revision 1.35  2001/05/08 16:02:22  kowal2
+Updated material specifications
+
+Revision 1.34  2001/05/08 15:00:15  hristov
+Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
+
+Revision 1.33  2001/04/03 12:40:43  kowal2
+Removed printouts
+
+Revision 1.32  2001/03/12 17:47:36  hristov
+Changes needed on Sun with CC 5.0
+
+Revision 1.31  2001/03/12 08:21:50  kowal2
+Corrected C++ bug in the material definitions
+
+Revision 1.30  2001/03/01 17:34:47  kowal2
+Correction due to the accuracy problem
+
+Revision 1.29  2001/02/28 16:34:40  kowal2
+Protection against nonphysical values of the avalanche size,
+10**6 is the maximum
+
+Revision 1.28  2001/01/26 19:57:19  hristov
+Major upgrade of AliRoot code
+
+Revision 1.27  2001/01/13 17:29:33  kowal2
+Sun compiler correction
+
+Revision 1.26  2001/01/10 07:59:43  kowal2
+Corrections to load points from the noncompressed hits.
+
+Revision 1.25  2000/11/02 07:25:31  kowal2
+Changes due to the new hit structure.
+Memory leak removed.
+
+Revision 1.24  2000/10/05 16:06:09  kowal2
+Forward declarations. Changes due to a new class AliComplexCluster.
+
+Revision 1.23  2000/10/02 21:28:18  fca
+Removal of useless dependecies via forward declarations
+
+Revision 1.22  2000/07/10 20:57:39  hristov
+Update of TPC code and macros by M.Kowalski
+
 Revision 1.19.2.4  2000/06/26 07:39:42  kowal2
 Changes to obey the coding rules
 
@@ -87,11 +137,15 @@ Introduction of the Copyright and cvs Log
 #include <TObjectTable.h>
 #include "TParticle.h"
 #include "AliTPC.h"
-#include <TFile.h>       
+#include <TFile.h>  
+#include <TROOT.h>
+#include <TSystem.h>     
 #include "AliRun.h"
 #include <iostream.h>
+#include <stdlib.h>
 #include <fstream.h>
 #include "AliMC.h"
+#include "AliMagF.h"
 
 
 #include "AliTPCParamSR.h"
@@ -99,9 +153,13 @@ Introduction of the Copyright and cvs Log
 #include "AliTPCRF1D.h"
 #include "AliDigits.h"
 #include "AliSimDigits.h"
+#include "AliTPCTrackHits.h"
+#include "AliPoints.h"
+#include "AliArrayBranch.h"
+
 
 #include "AliTPCDigitsArray.h"
-#include "AliCluster.h"
+#include "AliComplexCluster.h"
 #include "AliClusters.h"
 #include "AliTPCClustersRow.h"
 #include "AliTPCClustersArray.h"
@@ -111,6 +169,9 @@ Introduction of the Copyright and cvs Log
 #include "AliTPCtracker.h"
 
 #include <TInterpreter.h>
+#include <TTree.h>
+
+
 
 ClassImp(AliTPC) 
 
@@ -127,7 +188,10 @@ AliTPC::AliTPC()
   //MI changes
   fDigitsArray = 0;
   fClustersArray = 0;
-  fTPCParam=0;
+  fDefaults = 0;
+  fTrackHits = 0;  
+  fHitType = 2;  
+  fTPCParam = 0; 
 }
  
 //_____________________________________________________________________________
@@ -145,6 +209,14 @@ AliTPC::AliTPC(const char *name, const char *title)
   //MI change  
   fDigitsArray = 0;
   fClustersArray= 0;
+  fDefaults = 0;
+  //
+  fTrackHits = new AliTPCTrackHits;  //MI - 13.09.2000
+  fTrackHits->SetHitPrecision(0.002);
+  fTrackHits->SetStepPrecision(0.003);  
+  fTrackHits->SetMaxDistance(100); 
+
+  fHitType = 2;
   //
   // Initialise counters
   fNsectors = 0;
@@ -159,8 +231,9 @@ AliTPC::AliTPC(const char *name, const char *title)
   //  Set TPC parameters
   //
 
-  if (!strcmp(title,"Default")) {  
-     fTPCParam = new AliTPCParamSR;
+
+  if (!strcmp(title,"Default")) {       
+    fTPCParam = new AliTPCParamSR;
   } else {
     cerr<<"AliTPC warning: in Config.C you must set non-default parameters\n";
     fTPCParam=0;
@@ -179,6 +252,7 @@ AliTPC::~AliTPC()
   delete fHits;
   delete fDigits;
   delete fTPCParam;
+  delete fTrackHits; //MI 15.09.2000
 }
 
 //_____________________________________________________________________________
@@ -187,8 +261,14 @@ void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
   //
   // Add a hit to the list
   //
-  TClonesArray &lhits = *fHits;
-  new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
+  //  TClonesArray &lhits = *fHits;
+  //  new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
+  if (fHitType&1){
+    TClonesArray &lhits = *fHits;
+    new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
+  }
+  if (fHitType&2)
+   AddHit2(track,vol,hits);
 }
  
 //_____________________________________________________________________________
@@ -290,14 +370,15 @@ void AliTPC::Clusters2Tracks(TFile *of) {
   //-----------------------------------------------------------------
   // This is a track finder.
   //-----------------------------------------------------------------
-  AliTPCtracker::Clusters2Tracks(fTPCParam,of);
+  AliTPCtracker tracker(fTPCParam);
+  tracker.Clusters2Tracks(gFile,of);
 }
 
 //_____________________________________________________________________________
 void AliTPC::CreateMaterials()
 {
   //-----------------------------------------------
-  // Create Materials for for TPC
+  // Create Materials for for TPC simulations
   //-----------------------------------------------
 
   //-----------------------------------------------------------------
@@ -312,37 +393,36 @@ void AliTPC::CreateMaterials()
   Float_t wmat[5]; // proportions
 
   Float_t density;
+  Float_t apure[2];
 
-  //  ********************* Gases *******************
 
-  //--------------------------------------------------------------
+  //***************** Gases *************************
+  
+  //-------------------------------------------------
   // pure gases
-  //--------------------------------------------------------------
+  //-------------------------------------------------
 
-  // Ne
+  // Neon
 
 
-  Float_t aNe = 20.18;
-  Float_t zNe = 10.;
-  
+  amat[0]= 20.18;
+  zmat[0]= 10.;  
   density = 0.0009;
+  apure[0]=amat[0];
 
-  AliMaterial(20,"Ne",aNe,zNe,density,999.,999.);
+  AliMaterial(20,"Ne",amat[0],zmat[0],density,999.,999.);
 
-  // Ar
+  // Argon
 
-  Float_t aAr = 39.948;
-  Float_t zAr = 18.;
+  amat[0]= 39.948;
+  zmat[0]= 18.;  
+  density = 0.001782;  
 
-  density = 0.001782;
-  AliMaterial(21,"Ar",aAr,zAr,density,999.,999.);
+  apure[1]=amat[0];
 
-  Float_t aPure[2];
-  
-  aPure[0] = aNe;
-  aPure[1] = aAr;
-  
+  AliMaterial(21,"Ar",amat[0],zmat[0],density,999.,999.);
 
   //--------------------------------------------------------------
   // gases - compounds
@@ -350,7 +430,7 @@ void AliTPC::CreateMaterials()
 
   Float_t amol[3];
 
-  //  CO2
+  // CO2
 
   amat[0]=12.011;
   amat[1]=15.9994;
@@ -366,7 +446,7 @@ void AliTPC::CreateMaterials()
   amol[0] = amat[0]*wmat[0]+amat[1]*wmat[1];
 
   AliMixture(10,"CO2",amat,zmat,density,-2,wmat);
-
+  
   // CF4
 
   amat[0]=12.011;
@@ -384,6 +464,7 @@ void AliTPC::CreateMaterials()
 
   AliMixture(11,"CF4",amat,zmat,density,-2,wmat); 
 
+
   // CH4
 
   amat[0]=12.011;
@@ -404,29 +485,28 @@ void AliTPC::CreateMaterials()
   //----------------------------------------------------------------
   // gases - mixtures, ID >= 20 pure gases, <= 10 ID < 20 -compounds
   //----------------------------------------------------------------
-  char namate[21];
+
+  char namate[21]; 
   density = 0.;
   Float_t am=0;
   Int_t nc;
-
-  Float_t a,z,rho,absl,x0,buf[1];
+  Float_t rho,absl,X0,buf[1];
   Int_t nbuf;
+  Float_t a,z;
 
   for(nc = 0;nc<fNoComp;nc++)
     {
     
       // retrive material constants
       
-      gMC->Gfmate((*fIdmate)[fMixtComp[nc]],namate,a,z,rho,x0,absl,buf,nbuf);
+      gMC->Gfmate((*fIdmate)[fMixtComp[nc]],namate,a,z,rho,X0,absl,buf,nbuf);
 
       amat[nc] = a;
       zmat[nc] = z;
 
       Int_t nnc = (fMixtComp[nc]>=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
  
-      am += fMixtProp[nc]*((fMixtComp[nc]>=20) ? aPure[nnc] : amol[nnc]); 
+      am += fMixtProp[nc]*((fMixtComp[nc]>=20) ? apure[nnc] : amol[nnc]); 
       density += fMixtProp[nc]*rho;  // density of the mixture
       
     }
@@ -438,41 +518,92 @@ void AliTPC::CreateMaterials()
 
       Int_t nnc = (fMixtComp[nc]>=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
 
-      wmat[nc] = fMixtProp[nc]*((fMixtComp[nc]>=20) ? aPure[nnc] : amol[nnc])/am;
+      wmat[nc] = fMixtProp[nc]*((fMixtComp[nc]>=20) ? 
+                 apure[nnc] : amol[nnc])/am;
+
+    } 
+
+  // Drift gases 1 - nonsensitive, 2 - sensitive
 
-    }  
-  
   AliMixture(31,"Drift gas 1",amat,zmat,density,fNoComp,wmat);
   AliMixture(32,"Drift gas 2",amat,zmat,density,fNoComp,wmat);
-  AliMixture(33,"Drift gas 3",amat,zmat,density,fNoComp,wmat); 
 
-  AliMedium(2, "Drift gas 1", 31, 0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
-  AliMedium(3, "Drift gas 2", 32, 0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
-  AliMedium(4, "Drift gas 3", 33, 1, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
 
-  // Air 
+  // Air
+
+  amat[0] = 14.61;
+  zmat[0] = 7.3;
+  density = 0.001205;
 
-  AliMaterial(24, "Air", 14.61, 7.3, .001205, 30420., 67500.);
+  AliMaterial(24,"Air",amat[0],zmat[0],density,999.,999.); 
 
-  AliMedium(24, "Air", 24, 0, iSXFLD, sXMGMX, 10., .1, .1, .1, .1);
 
   //----------------------------------------------------------------------
   //               solid materials
   //----------------------------------------------------------------------
 
-  // Al
 
-  AliMaterial(30, "Al", 26.98, 13., 2.7, 8.9, 37.2);
+  // Kevlar C14H22O2N2
 
-  AliMedium(0, "Al",30, 0, iSXFLD, sXMGMX, 10., .1, .1, .1,   .1);
+  amat[0] = 12.011;
+  amat[1] = 1.;
+  amat[2] = 15.999;
+  amat[3] = 14.006;
 
-  // Si
+  zmat[0] = 6.;
+  zmat[1] = 1.;
+  zmat[2] = 8.;
+  zmat[3] = 7.;
 
-  AliMaterial(31, "Si", 28.086, 14.,2.33, 9.36, 999.);
+  wmat[0] = 14.;
+  wmat[1] = 22.;
+  wmat[2] = 2.;
+  wmat[3] = 2.;
 
-  AliMedium(7, "Al",31, 0, iSXFLD, sXMGMX, 10., .1, .1, .1,   .1);
+  density = 1.45;
+
+  AliMixture(34,"Kevlar",amat,zmat,density,-4,wmat);  
+
+  // NOMEX
+
+  amat[0] = 12.011;
+  amat[1] = 1.;
+  amat[2] = 15.999;
+  amat[3] = 14.006;
+
+  zmat[0] = 6.;
+  zmat[1] = 1.;
+  zmat[2] = 8.;
+  zmat[3] = 7.;
+
+  wmat[0] = 14.;
+  wmat[1] = 22.;
+  wmat[2] = 2.;
+  wmat[3] = 2.;
+
+  density = 0.03;
+
+  
+  AliMixture(35,"NOMEX",amat,zmat,density,-4,wmat);
+
+  // Makrolon C16H18O3
+
+  amat[0] = 12.011;
+  amat[1] = 1.;
+  amat[2] = 15.999;
+
+  zmat[0] = 6.;
+  zmat[1] = 1.;
+  zmat[2] = 8.;
+
+  wmat[0] = 16.;
+  wmat[1] = 18.;
+  wmat[2] = 3.;
   
+  density = 1.2;
 
+  AliMixture(36,"Makrolon",amat,zmat,density,-3,wmat);
+  
   // Mylar C5H4O2
 
   amat[0]=12.011;
@@ -489,105 +620,181 @@ void AliTPC::CreateMaterials()
 
   density = 1.39;
   
-  AliMixture(32, "Mylar",amat,zmat,density,-3,wmat);
+  AliMixture(37, "Mylar",amat,zmat,density,-3,wmat); 
 
-  AliMedium(5, "Mylar",32, 0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);
+  // SiO2 - used later for the glass fiber
 
+  amat[0]=28.086;
+  amat[1]=15.9994;
 
+  zmat[0]=14.;
+  zmat[1]=8.;
 
+  wmat[0]=1.;
+  wmat[1]=2.;
 
-  // Carbon (normal)
 
-  AliMaterial(33,"C normal",12.011,6.,2.265,18.8,999.);
+  AliMixture(38,"SiO2",amat,zmat,2.2,-2,wmat); //SiO2 - quartz (rho=2.2)
 
-  AliMedium(6,"C normal",33,0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);
+  // Al
 
-  // G10 for inner and outr field cage
-  // G10 is 60% SiO2 + 40% epoxy, right now I use A and Z for SiO2
+  amat[0] = 26.98;
+  zmat[0] = 13.;
 
-  Float_t rhoFactor;
+  density = 2.7;
 
-  amat[0]=28.086;
-  amat[1]=15.9994;
+  AliMaterial(40,"Al",amat[0],zmat[0],density,999.,999.);
 
-  zmat[0]=14.;
-  zmat[1]=8.;
+  // Si
 
-  wmat[0]=1.;
-  wmat[1]=2.;
+  amat[0] = 28.086;
+  zmat[0] = 14.;
 
-  density = 1.7;
-  
+  density = 2.33;
 
-  AliMixture(34,"G10 aux.",amat,zmat,density,-2,wmat);
+  AliMaterial(41,"Si",amat[0],zmat[0],density,999.,999.);
 
+  // Cu
 
-  gMC->Gfmate((*fIdmate)[34],namate,a,z,rho,x0,absl,buf,nbuf);
+  amat[0] = 63.546;
+  zmat[0] = 29.;
 
-  Float_t thickX0 = 0.0052; // field cage in X0 units
-  
-  Float_t thick = 2.; // in cm
+  density = 8.96;
+
+  AliMaterial(42,"Cu",amat[0],zmat[0],density,999.,999.);
+
+  // Tedlar C2H3F
+
+  amat[0] = 12.011;
+  amat[1] = 1.;
+  amat[2] = 18.998;
+
+  zmat[0] = 6.;
+  zmat[1] = 1.;
+  zmat[2] = 9.;
+
+  wmat[0] = 2.;
+  wmat[1] = 3.; 
+  wmat[2] = 1.;
 
-  x0=19.4; // G10 
+  density = 1.71;
 
-  rhoFactor = x0*thickX0/thick;
-  density = rho*rhoFactor;
+  AliMixture(43, "Tedlar",amat,zmat,density,-3,wmat);  
 
-  AliMaterial(35,"G10-fc",a,z,density,999.,999.);
 
-  AliMedium(8,"G10-fc",35,0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);
+  // Plexiglas  C5H8O2
 
-  thickX0 = 0.0027; // inner vessel (eta <0.9)
-  thick=0.5;
-  rhoFactor = x0*thickX0/thick;
-  density = rho*rhoFactor;
+  amat[0]=12.011;
+  amat[1]=1.;
+  amat[2]=15.9994;
 
-  AliMaterial(36,"G10-iv",a,z,density,999.,999.);  
+  zmat[0]=6.;
+  zmat[1]=1.;
+  zmat[2]=8.;
 
-  AliMedium(9,"G10-iv",36,0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);
+  wmat[0]=5.;
+  wmat[1]=8.;
+  wmat[2]=2.;
+
+  density=1.18;
+
+  AliMixture(44,"Plexiglas",amat,zmat,density,-3,wmat);
+
+  // Epoxy - C14 H20 O3
 
-  //  Carbon fibre  
   
-  gMC->Gfmate((*fIdmate)[33],namate,a,z,rho,x0,absl,buf,nbuf);
+  amat[0]=12.011;
+  amat[1]=1.;
+  amat[2]=15.9994;
+
+  zmat[0]=6.;
+  zmat[1]=1.;
+  zmat[2]=8.;
 
-  thickX0 = 0.0133; // outer vessel
-  thick=3.0;
-  rhoFactor = x0*thickX0/thick;
-  density = rho*rhoFactor;
+  wmat[0]=14.;
+  wmat[1]=20.;
+  wmat[2]=3.;
 
+  density=1.25;
 
-  AliMaterial(37,"C-ov",a,z,density,999.,999.);
+  AliMixture(45,"Epoxy",amat,zmat,density,-3,wmat);
 
-  AliMedium(10,"C-ov",37,0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);  
+  // Carbon
 
-  thickX0=0.015; // inner vessel (cone, eta > 0.9)
-  thick=1.5;
-  rhoFactor = x0*thickX0/thick;
-  density = rho*rhoFactor;
+  amat[0]=12.011;
+  zmat[0]=6.;
+  density= 2.265;
 
-  AliMaterial(38,"C-ivc",a,z,density,999.,999.);
+  AliMaterial(46,"C",amat[0],zmat[0],density,999.,999.);
 
-  AliMedium(11,"C-ivc",38,0, iSXFLD, sXMGMX, 10., .1, .1, .001, .01);
+  // get epoxy
 
-  //
+  gMC->Gfmate((*fIdmate)[45],namate,amat[1],zmat[1],rho,X0,absl,buf,nbuf);
+
+  // Carbon fiber
+
+  wmat[0]=0.644; // by weight!
+  wmat[1]=0.356;
+
+  density=0.5*(1.25+2.265);
+
+  AliMixture(47,"Cfiber",amat,zmat,density,2,wmat);
+
+  // get SiO2
+
+  gMC->Gfmate((*fIdmate)[38],namate,amat[0],zmat[0],rho,X0,absl,buf,nbuf); 
+
+  wmat[0]=0.725; // by weight!
+  wmat[1]=0.275;
+
+  density=1.7;
+
+  AliMixture(39,"G10",amat,zmat,density,2,wmat);
+
+
+
+  //----------------------------------------------------------
+  // tracking media for gases
+  //----------------------------------------------------------
+
+  AliMedium(0, "Air", 24, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
+  AliMedium(1, "Drift gas 1", 31, 0, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
+  AliMedium(2, "Drift gas 2", 32, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
+  AliMedium(3,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001); 
 
-  AliMedium(12,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
+  //-----------------------------------------------------------  
+  // tracking media for solids
+  //-----------------------------------------------------------
+  
+  AliMedium(4,"Al",40,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
+  AliMedium(5,"Kevlar",34,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
+  AliMedium(6,"Nomex",35,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(7,"Makrolon",36,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(8,"Mylar",37,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
+  AliMedium(9,"Tedlar",43,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
+  AliMedium(10,"Cu",42,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(11,"Si",41,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(12,"G10",39,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(13,"Plexiglas",44,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
+  AliMedium(14,"Epoxy",45,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
+  AliMedium(15,"Cfiber",47,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
     
 }
 
 
-void AliTPC::Digits2Clusters(TFile *of)
+void AliTPC::Digits2Clusters(TFile *of, Int_t eventnumber)
 {
   //-----------------------------------------------------------------
   // This is a simple cluster finder.
   //-----------------------------------------------------------------
-  AliTPCclusterer::Digits2Clusters(fTPCParam,of);
+  AliTPCclusterer::Digits2Clusters(fTPCParam,of,eventnumber);
 }
 
 extern Double_t SigmaY2(Double_t, Double_t, Double_t);
 extern Double_t SigmaZ2(Double_t, Double_t);
 //_____________________________________________________________________________
-void AliTPC::Hits2Clusters(TFile *of)
+void AliTPC::Hits2Clusters(TFile *of, Int_t eventn)
 {
   //--------------------------------------------------------
   // TPC simple cluster generator from hits
@@ -626,17 +833,13 @@ void AliTPC::Hits2Clusters(TFile *of)
      return;
   }
 
-   if(fTPCParam == 0){
-     printf("AliTPCParam MUST be created firstly\n");
-     return;
-   }
+  //if(fDefaults == 0) SetDefaults();
 
   Float_t sigmaRphi,sigmaZ,clRphi,clZ;
   //
   TParticle *particle; // pointer to a given particle
   AliTPChit *tpcHit; // pointer to a sigle TPC hit
-  TClonesArray *particles; //pointer to the particle list
-  Int_t sector,nhits;
+  Int_t sector;
   Int_t ipart;
   Float_t xyz[5];
   Float_t pl,pt,tanth,rpad,ratio;
@@ -648,11 +851,14 @@ void AliTPC::Hits2Clusters(TFile *of)
   
   TTree *tH = gAlice->TreeH();
   Stat_t ntracks = tH->GetEntries();
-  particles=gAlice->Particles();
 
   //Switch to the output file
   of->cd();
 
+  char   cname[100];
+
+  sprintf(cname,"TreeC_TPC_%d",eventn);
+
   fTPCParam->Write(fTPCParam->GetTitle());
   AliTPCClustersArray carray;
   carray.Setup(fTPCParam);
@@ -684,23 +890,39 @@ void AliTPC::Hits2Clusters(TFile *of)
       //
       //  Get number of the TPC hits
       //
-      nhits=fHits->GetEntriesFast();
+      // nhits=fHits->GetEntriesFast();
       //
+     
+       tpcHit = (AliTPChit*)FirstHit(-1);
+
       // Loop over hits
       //
-      for(Int_t hit=0;hit<nhits;hit++){
-       tpcHit=(AliTPChit*)fHits->UncheckedAt(hit);
-        if (tpcHit->fQ == 0.) continue; //information about track (I.Belikov)
+       //   for(Int_t hit=0;hit<nhits;hit++){
+       //tpcHit=(AliTPChit*)fHits->UncheckedAt(hit);
+
+       while(tpcHit){
+        if (tpcHit->fQ == 0.) {
+           tpcHit = (AliTPChit*) NextHit();
+           continue; //information about track (I.Belikov)
+        }
        sector=tpcHit->fSector; // sector number
-       if(sector != isec) continue; //terminate iteration
-       ipart=tpcHit->fTrack;
-       particle=(TParticle*)particles->UncheckedAt(ipart);
+
+
+       //      if(sector != isec) continue; //terminate iteration
+
+       if(sector != isec){
+        tpcHit = (AliTPChit*) NextHit();
+        continue; 
+       }
+       ipart=tpcHit->Track();
+       particle=gAlice->Particle(ipart);
        pl=particle->Pz();
        pt=particle->Pt();
        if(pt < 1.e-9) pt=1.e-9;
        tanth=pl/pt;
        tanth = TMath::Abs(tanth);
-       rpad=TMath::Sqrt(tpcHit->fX*tpcHit->fX + tpcHit->fY*tpcHit->fY);
+       rpad=TMath::Sqrt(tpcHit->X()*tpcHit->X() + tpcHit->Y()*tpcHit->Y());
        ratio=0.001*rpad/pt; // pt must be in MeV/c - historical reason
 
        //   space-point resolutions
@@ -726,27 +948,30 @@ void AliTPC::Hits2Clusters(TFile *of)
        // smearing --> rotate to the 1 (13) or to the 25 (49) sector,
        // then the inaccuracy in a X-Y plane is only along Y (pad row)!
        //
-        Float_t xprim= tpcHit->fX*cph + tpcHit->fY*sph;
-       Float_t yprim=-tpcHit->fX*sph + tpcHit->fY*cph;
+        Float_t xprim= tpcHit->X()*cph + tpcHit->Y()*sph;
+       Float_t yprim=-tpcHit->X()*sph + tpcHit->Y()*cph;
        xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigmaRphi));   // y
           Float_t alpha=(isec < fTPCParam->GetNInnerSector()) ?
          fTPCParam->GetInnerAngle() : fTPCParam->GetOuterAngle();
           Float_t ymax=xprim*TMath::Tan(0.5*alpha);
           if (TMath::Abs(xyz[0])>ymax) xyz[0]=yprim; 
-       xyz[1]=gRandom->Gaus(tpcHit->fZ,TMath::Sqrt(sigmaZ)); // z
-          if (TMath::Abs(xyz[1])>fTPCParam->GetZLength()) xyz[1]=tpcHit->fZ
-       xyz[2]=tpcHit->fQ;                                     // q
-       xyz[3]=sigmaRphi;                                     // fSigmaY2
-       xyz[4]=sigmaZ;                                        // fSigmaZ2
+       xyz[1]=gRandom->Gaus(tpcHit->Z(),TMath::Sqrt(sigmaZ)); // z
+          if (TMath::Abs(xyz[1])>fTPCParam->GetZLength()) xyz[1]=tpcHit->Z()
+       xyz[2]=sigmaRphi;                                     // fSigmaY2
+       xyz[3]=sigmaZ;                                        // fSigmaZ2
+       xyz[4]=tpcHit->fQ;                                    // q
 
         AliTPCClustersRow *clrow=carray.GetRow(sector,tpcHit->fPadRow);
         if (!clrow) clrow=carray.CreateRow(sector,tpcHit->fPadRow);    
 
-        Int_t tracks[3]={tpcHit->fTrack, -1, -1};
-       AliTPCcluster cluster(xyz,tracks);
+        Int_t tracks[3]={tpcHit->Track(), -1, -1};
+       AliTPCcluster cluster(tracks,xyz);
 
         clrow->InsertCluster(&cluster); nclusters++;
 
+        tpcHit = (AliTPChit*)NextHit();
+        
+
       } // end of loop over hits
 
     }   // end of loop over tracks
@@ -763,7 +988,7 @@ void AliTPC::Hits2Clusters(TFile *of)
 
   cerr<<"Number of made clusters : "<<nclusters<<"                        \n";
 
-  carray.GetTree()->Write();
+  carray.GetTree()->Write(cname);
 
   savedir->cd(); //switch back to the input file
   
@@ -787,7 +1012,6 @@ void AliTPC::Hits2ExactClustersSector(Int_t isec)
   //
   TParticle *particle; // pointer to a given particle
   AliTPChit *tpcHit; // pointer to a sigle TPC hit
-  TClonesArray *particles; //pointer to the particle list
   Int_t sector,nhits;
   Int_t ipart;
   const Int_t kcmaxhits=30000;
@@ -804,8 +1028,7 @@ void AliTPC::Hits2ExactClustersSector(Int_t isec)
   
   TTree *tH = gAlice->TreeH();
   Stat_t ntracks = tH->GetEntries();
-  particles=gAlice->Particles();
-  Int_t npart = particles->GetEntriesFast();
+  Int_t npart = gAlice->GetNtrack();
     
   //------------------------------------------------------------
   // Loop over tracks
@@ -829,12 +1052,12 @@ void AliTPC::Hits2ExactClustersSector(Int_t isec)
       if (tpcHit==0) continue;
       sector=tpcHit->fSector; // sector number
       if(sector != isec) continue; 
-      ipart=tpcHit->fTrack;
-      if (ipart<npart) particle=(TParticle*)particles->UncheckedAt(ipart);
+      ipart=tpcHit->Track();
+      if (ipart<npart) particle=gAlice->Particle(ipart);
       
       //find row number
 
-      Float_t  x[3]={tpcHit->fX,tpcHit->fY,tpcHit->fZ};
+      Float_t  x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()};
       Int_t    index[3]={1,isec,0};
       Int_t    currentrow = fTPCParam->GetPadRow(x,index) ;    
       if (currentrow<0) continue;
@@ -901,7 +1124,7 @@ void AliTPC::Hits2ExactClustersSector(Int_t isec)
          Float_t bz=detbz/det; //z angle
          sumy/=Float_t(currentIndex);
          sumz/=Float_t(currentIndex);
-         AliCluster cl;
+         AliComplexCluster cl;
          cl.fX=z;
          cl.fY=y;
          cl.fQ=sumq;
@@ -927,24 +1150,146 @@ void AliTPC::Hits2ExactClustersSector(Int_t isec)
   xxxx->Delete();
  
 }
+//___________________________________________
+void AliTPC::SDigits2Digits(Int_t eventnumber)
+{
+
+
+  cerr<<"Digitizing TPC...\n";
+
+  Hits2Digits(eventnumber);
+   
+    
+  //write results
+
+  //  char treeName[100];
 
+  //  sprintf(treeName,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
+  
+  //  GetDigitsArray()->GetTree()->Write(treeName);  
+}
+//__________________________________________________________________
+void AliTPC::SetDefaults(){
+
+   
+   cerr<<"Setting default parameters...\n";
+
+  // Set response functions
+
+  AliTPCParamSR *param=(AliTPCParamSR*)gDirectory->Get("75x40_100x60");
+  AliTPCPRF2D    * prfinner   = new AliTPCPRF2D;
+  AliTPCPRF2D    * prfouter   = new AliTPCPRF2D;
+  AliTPCRF1D     * rf    = new AliTPCRF1D(kTRUE);
+  rf->SetGauss(param->GetZSigma(),param->GetZWidth(),1.);
+  rf->SetOffset(3*param->GetZSigma());
+  rf->Update();
+  
+  TDirectory *savedir=gDirectory;
+  TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
+  if (!f->IsOpen()) { 
+    cerr<<"Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !\n" ;
+     exit(3);
+  }
+  prfinner->Read("prf_07504_Gati_056068_d02");
+  prfouter->Read("prf_10006_Gati_047051_d03");
+  f->Close();
+  savedir->cd();
+
+  param->SetInnerPRF(prfinner);
+  param->SetOuterPRF(prfouter); 
+  param->SetTimeRF(rf);
+
+  // set fTPCParam
+
+  SetParam(param);
+
+
+  fDefaults = 1;
+
+}
 //__________________________________________________________________  
-void AliTPC::Hits2Digits()  
+void AliTPC::Hits2Digits(Int_t eventnumber)  
 { 
  //----------------------------------------------------
- // Loop over all sectors
+ // Loop over all sectors for a single event
  //----------------------------------------------------
 
-  if(fTPCParam == 0){
-    printf("AliTPCParam MUST be created firstly\n");
-    return;
-  } 
+
+  if(fDefaults == 0) SetDefaults();  // check if the parameters are set
+
+  //setup TPCDigitsArray 
+
+  if(GetDigitsArray()) delete GetDigitsArray();
+
+  AliTPCDigitsArray *arr = new AliTPCDigitsArray; 
+  arr->SetClass("AliSimDigits");
+  arr->Setup(fTPCParam);
+  arr->MakeTree(fDigitsFile);
+  SetDigitsArray(arr);
+
+  fDigitsSwitch=0; // standard digits
+
+  cerr<<"Digitizing TPC...\n";
 
  for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++) Hits2DigitsSector(isec);
 
+  // write results
+
+  char treeName[100];
+
+  sprintf(treeName,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
+  
+  GetDigitsArray()->GetTree()->Write(treeName);  
+
+
 }
 
 
+
+//__________________________________________________________________
+void AliTPC::Hits2SDigits(Int_t eventnumber)  
+{ 
+
+  //-----------------------------------------------------------
+  //   summable digits - 16 bit "ADC", no noise, no saturation
+  //-----------------------------------------------------------
+
+ //----------------------------------------------------
+ // Loop over all sectors for a single event
+ //----------------------------------------------------
+
+
+  if(fDefaults == 0) SetDefaults();
+
+  //setup TPCDigitsArray 
+
+  if(GetDigitsArray()) delete GetDigitsArray();
+
+  AliTPCDigitsArray *arr = new AliTPCDigitsArray; 
+  arr->SetClass("AliSimDigits");
+  arr->Setup(fTPCParam);
+  arr->MakeTree(fDigitsFile);
+  SetDigitsArray(arr);
+
+  cerr<<"Digitizing TPC...\n"; 
+
+  fDigitsSwitch=1; // summable digits
+
+ for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++) Hits2DigitsSector(isec);
+
+
+  // write results
+
+  char treeName[100];
+
+  sprintf(treeName,"TreeS_%s_%d",fTPCParam->GetTitle(),eventnumber);
+  
+  GetDigitsArray()->GetTree()->Write(treeName); 
+
+}
+
+
+
 //_____________________________________________________________________________
 void AliTPC::Hits2DigitsSector(Int_t isec)
 {
@@ -960,6 +1305,10 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
   //  Get the access to the track hits
   //-------------------------------------------------------
 
+  // check if the parameters are set - important if one calls this method
+  // directly, not from the Hits2Digits
+
+  if(fDefaults == 0) SetDefaults();
 
   TTree *tH = gAlice->TreeH(); // pointer to the hits tree
   Stat_t ntracks = tH->GetEntries();
@@ -972,7 +1321,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
 
     TObjArray **row;
     
-      printf("*** Processing sector number %d ***\n",isec);
+    printf("*** Processing sector number %d ***\n",isec);
 
       Int_t nrows =fTPCParam->GetNRow(isec);
 
@@ -989,7 +1338,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
 
       Int_t i;
 
-      if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree();
+      if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree(fDigitsFile);
 
       for (i=0;i<nrows;i++){
 
@@ -999,9 +1348,10 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
 
        fDigitsArray->StoreRow(isec,i);
 
-       Int_t ndig = dig->GetDigitSize(); 
+               Int_t ndig = dig->GetDigitSize(); 
+        
  
-       printf("*** Sector, row, compressed digits %d %d %d ***\n",isec,i,ndig);
+     printf("*** Sector, row, compressed digits %d %d %d ***\n",isec,i,ndig);
        
         fDigitsArray->ClearRow(isec,i);  
 
@@ -1009,7 +1359,8 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
        } // end of the sector digitization
 
       for(i=0;i<nrows;i++){
-        row[i]->Delete();     
+        row[i]->Delete();  
+        delete row[i];   
       }
       
        delete [] row; // delete the array of pointers to TObjArray-s
@@ -1087,12 +1438,21 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows)
 
       Int_t gi =it*nofPads+ip; // global index
 
-      q = gRandom->Gaus(q,fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac()); 
+      if(fDigitsSwitch == 0){
 
-      q = (Int_t)q;
+        q = gRandom->Gaus(q,fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac()); 
 
-      if(q <=zerosup) continue; // do not fill zeros
-      if(q > fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat();  // saturation
+        q = (Int_t)q;
+
+        if(q <=zerosup) continue; // do not fill zeros
+        if(q > fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat();  // saturation
+
+      }
+
+      else {
+       q *= 16.;
+       q = (Int_t)q;
+      }
 
       //
       //  "real" signal or electronic noise (list = -1)?
@@ -1314,6 +1674,11 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
   Float_t xyz[4]; 
 
   AliTPChit *tpcHit; // pointer to a sigle TPC hit    
+  //MI change
+  TBranch * branch=0;
+  if (fHitType&2) branch = TH->GetBranch("TPC2");
+  else branch = TH->GetBranch("TPC");
+
  
   //----------------------------------------------
   // Create TObjArray-s, one for each row,
@@ -1321,11 +1686,15 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
   // of electrons, one TVector per each track.
   //---------------------------------------------- 
     
+  Int_t *nofElectrons = new Int_t [nrows]; // electron counter for each row
+  TVector **tracks = new TVector* [nrows]; //pointers to the track vectors
   for(i=0; i<nrows; i++){
     row[i] = new TObjArray;
+    nofElectrons[i]=0;
+    tracks[i]=0;
   }
-  Int_t *nofElectrons = new Int_t [nrows]; // electron counter for each row
-  TVector **tracks = new TVector* [nrows]; //pointers to the track vectors
+
 
   //--------------------------------------------------------------------
   //  Loop over tracks, the "track" contains the full history
@@ -1335,26 +1704,43 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
   previousTrack = -1; // nothing to store so far!
 
   for(Int_t track=0;track<ntracks;track++){
-
+    Bool_t isInSector=kTRUE;
     ResetHits();
 
-    TH->GetEvent(track); // get next track
-    Int_t nhits = fHits->GetEntriesFast(); // get number of hits for this track
+    if (fHitType&2) {
+      isInSector=kFALSE;
+      TBranch * br = TH->GetBranch("fTrackHitsInfo");
+      br->GetEvent(track);
+      AliObjectArray * ar = fTrackHits->fTrackHitsInfo;
+      for (UInt_t j=0;j<ar->GetSize();j++){
+       if (  ((AliTrackHitsInfo*)ar->At(j))->fVolumeID==isec) isInSector=kTRUE;
+      }
+    }
+    if (!isInSector) continue;
+    //MI change
+    branch->GetEntry(track); // get next track
+
+    //M.I. changes
 
-    if(nhits == 0) continue; // no hits in the TPC for this track
+    tpcHit = (AliTPChit*)FirstHit(-1);
 
     //--------------------------------------------------------------
     //  Loop over hits
     //--------------------------------------------------------------
 
-    for(Int_t hit=0;hit<nhits;hit++){
 
-      tpcHit = (AliTPChit*)fHits->UncheckedAt(hit); // get a pointer to a hit
+    while(tpcHit){
       
       Int_t sector=tpcHit->fSector; // sector number
-      if(sector != isec) continue; 
+      //      if(sector != isec) continue; 
+      if(sector != isec){
+       tpcHit = (AliTPChit*) NextHit();
+       continue; 
+      }
+
+       currentTrack = tpcHit->Track(); // track number
+
 
-       currentTrack = tpcHit->fTrack; // track number
         if(currentTrack != previousTrack){
                           
            // store already filled fTrack
@@ -1388,7 +1774,7 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
        //---------------------------------------------------
 
 
-        Float_t time = 1.e6*(fTPCParam->GetZLength()-TMath::Abs(tpcHit->fZ))
+        Float_t time = 1.e6*(fTPCParam->GetZLength()-TMath::Abs(tpcHit->Z()))
                                                         /fTPCParam->GetDriftV(); 
        // in microseconds!     
        Float_t attProb = fTPCParam->GetAttCoef()*
@@ -1402,10 +1788,14 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
         for(Int_t nel=0;nel<qI;nel++){
           // skip if electron lost due to the attachment
           if((gRandom->Rndm(0)) < attProb) continue; // electron lost!
-         xyz[0]=tpcHit->fX;
-         xyz[1]=tpcHit->fY;
-         xyz[2]=tpcHit->fZ;      
-         xyz[3]= (Float_t) (-gasgain*TMath::Log(gRandom->Rndm()));
+         xyz[0]=tpcHit->X();
+         xyz[1]=tpcHit->Y();
+         xyz[2]=tpcHit->Z();   
+         //
+         // protection for the nonphysical avalanche size (10**6 maximum)
+         //  
+          Double_t rn=TMath::Max(gRandom->Rndm(0),1.93e-22);
+         xyz[3]= (Float_t) (-gasgain*TMath::Log(rn)); 
          index[0]=1;
          
          TransportElectron(xyz,index); //MI change -august       
@@ -1435,6 +1825,8 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
           v(idx+2)=xyz[2];   // Z - time bin coordinate
          v(idx+3)=xyz[3];   // avalanche size  
        } // end of loop over electrons
+
+        tpcHit = (AliTPChit*)NextHit();
         
       } // end of loop over hits
     } // end of loop over tracks
@@ -1471,18 +1863,20 @@ void AliTPC::Init()
   //
   Int_t i;
   //
-  printf("\n");
-  for(i=0;i<35;i++) printf("*");
-  printf(" TPC_INIT ");
-  for(i=0;i<35;i++) printf("*");
-  printf("\n");
-  //
-  for(i=0;i<80;i++) printf("*");
-  printf("\n");
+  if(fDebug) {
+    printf("\n%s: ",ClassName());
+    for(i=0;i<35;i++) printf("*");
+    printf(" TPC_INIT ");
+    for(i=0;i<35;i++) printf("*");
+    printf("\n%s: ",ClassName());
+    //
+    for(i=0;i<80;i++) printf("*");
+    printf("\n");
+  }
 }
 
 //_____________________________________________________________________________
-void AliTPC::MakeBranch(Option_t* option)
+void AliTPC::MakeBranch(Option_t* option, const char *file)
 {
   //
   // Create Tree branches for the TPC.
@@ -1491,14 +1885,16 @@ void AliTPC::MakeBranch(Option_t* option)
   char branchname[10];
   sprintf(branchname,"%s",GetName());
 
-  AliDetector::MakeBranch(option);
+  AliDetector::MakeBranch(option,file);
 
-  char *d = strstr(option,"D");
+  const char *d = strstr(option,"D");
 
   if (fDigits   && gAlice->TreeD() && d) {
-    gAlice->TreeD()->Branch(branchname,&fDigits, buffersize);
-    printf("Making Branch %s for digits\n",branchname);
+      MakeBranchInTree(gAlice->TreeD(), 
+                       branchname, &fDigits, buffersize, file);
   }    
+
+  if (fHitType&2) MakeBranch2(option,file); // MI change 14.09.2000
 }
  
 //_____________________________________________________________________________
@@ -1600,6 +1996,7 @@ void AliTPC::SetSens(Int_t sens)
 
   fSens = sens;
 }
+
  
 void AliTPC::SetSide(Float_t side=0.)
 {
@@ -1663,23 +2060,6 @@ void AliTPC::TransportElectron(Float_t *xyz, Int_t *index)
   //add nonisochronity (not implemented yet)
   
 }
-//_____________________________________________________________________________
-void AliTPC::Streamer(TBuffer &R__b)
-{
-  //
-  // Stream an object of class AliTPC.
-  //
-   if (R__b.IsReading()) {
-      Version_t R__v = R__b.ReadVersion(); if (R__v) { }
-      AliDetector::Streamer(R__b);
-      if (R__v < 2) return;
-      R__b >> fNsectors;
-   } else {
-      R__b.WriteVersion(AliTPC::IsA());
-      AliDetector::Streamer(R__b);
-      R__b << fNsectors;
-   }
-}
   
 ClassImp(AliTPCdigit)
  
@@ -1716,3 +2096,459 @@ AliHit(shunt,track)
 }
  
 
+//________________________________________________________________________
+// Additional code because of the AliTPCTrackHits
+
+void AliTPC::MakeBranch2(Option_t *option,const char *file)
+{
+  //
+  // Create a new branch in the current Root Tree
+  // The branch of fHits is automatically split
+  // MI change 14.09.2000
+  if (fHitType&2==0) return;
+  char branchname[10];
+  sprintf(branchname,"%s2",GetName());  
+  //
+  // Get the pointer to the header
+  const char *cH = strstr(option,"H");
+  //
+  if (fTrackHits   && gAlice->TreeH() && cH) {    
+    AliObjectBranch * branch = new AliObjectBranch(branchname,"AliTPCTrackHits",&fTrackHits, 
+                                                  gAlice->TreeH(),fBufferSize,1);
+    gAlice->TreeH()->GetListOfBranches()->Add(branch);
+    if (GetDebug()>1) 
+      printf("* AliDetector::MakeBranch * Making Branch %s for trackhits\n",branchname);
+    const char folder [] = "RunMC/Event/Data";
+    if (GetDebug())
+      printf("%15s: Publishing %s to %s\n",ClassName(),branchname,folder);
+    Publish(folder,&fTrackHits,branchname);
+    if (file) {
+        TBranch *b = gAlice->TreeH()->GetBranch(branchname);
+        TDirectory *wd = gDirectory;
+        b->SetFile(file);
+        TIter next( b->GetListOfBranches());
+        while ((b=(TBranch*)next())) {
+         b->SetFile(file);
+        }
+        wd->cd(); 
+        if (GetDebug()>1) 
+             cout << "Diverting branch " << branchname << " to file " << file << endl;  
+    }
+  }    
+}
+
+void AliTPC::SetTreeAddress()
+{
+  if (fHitType&1) AliDetector::SetTreeAddress();
+  if (fHitType&2) SetTreeAddress2();
+}
+
+void AliTPC::SetTreeAddress2()
+{
+  //
+  // Set branch address for the TrackHits Tree
+  // 
+  TBranch *branch;
+  char branchname[20];
+  sprintf(branchname,"%s2",GetName());
+  //
+  // Branch address for hit tree
+  TTree *treeH = gAlice->TreeH();
+  if (treeH) {
+    branch = treeH->GetBranch(branchname);
+    if (branch) branch->SetAddress(&fTrackHits);
+  }
+}
+
+void AliTPC::FinishPrimary()
+{
+  if (fTrackHits) fTrackHits->FlushHitStack();  
+}
+
+
+void AliTPC::AddHit2(Int_t track, Int_t *vol, Float_t *hits)
+{ 
+  //
+  // add hit to the list  
+  Int_t rtrack;
+  if (fIshunt) {
+    int primary = gAlice->GetPrimary(track);
+    gAlice->Particle(primary)->SetBit(kKeepBit);
+    rtrack=primary;
+  } else {
+    rtrack=track;
+    gAlice->FlagTrack(track);
+  }  
+  //AliTPChit *hit = (AliTPChit*)fHits->UncheckedAt(fNhits-1);
+  //if (hit->fTrack!=rtrack)
+  //  cout<<"bad track number\n";
+  if (fTrackHits) 
+    fTrackHits->AddHitKartez(vol[0],rtrack, hits[0],
+                            hits[1],hits[2],(Int_t)hits[3]);
+}
+
+void AliTPC::ResetHits()
+{
+  if (fHitType&1) AliDetector::ResetHits();
+  if (fHitType&2) ResetHits2();
+}
+
+void AliTPC::ResetHits2()
+{
+  //
+  //reset hits
+  if (fTrackHits) fTrackHits->Clear();
+}   
+
+AliHit* AliTPC::FirstHit(Int_t track)
+{
+  if (fHitType&2) return FirstHit2(track);
+  return AliDetector::FirstHit(track);
+}
+AliHit* AliTPC::NextHit()
+{
+  if (fHitType&2) return NextHit2();
+  return AliDetector::NextHit();
+}
+
+AliHit* AliTPC::FirstHit2(Int_t track)
+{
+  //
+  // Initialise the hit iterator
+  // Return the address of the first hit for track
+  // If track>=0 the track is read from disk
+  // while if track<0 the first hit of the current
+  // track is returned
+  // 
+  if(track>=0) {
+    gAlice->ResetHits();
+    gAlice->TreeH()->GetEvent(track);
+  }
+  //
+  if (fTrackHits) {
+    fTrackHits->First();
+    return fTrackHits->GetHit();
+  }
+  else return 0;
+}
+
+AliHit* AliTPC::NextHit2()
+{
+  //
+  //Return the next hit for the current track
+
+  if (fTrackHits) {
+    fTrackHits->Next();
+    return fTrackHits->GetHit();
+  }
+  else 
+    return 0;
+}
+
+void AliTPC::LoadPoints(Int_t)
+{
+  //
+  Int_t a = 0;
+  /*  if(fHitType==1) return AliDetector::LoadPoints(a);
+  LoadPoints2(a);
+  */
+  if(fHitType==1) AliDetector::LoadPoints(a);
+  else LoadPoints2(a);
+   
+  // LoadPoints3(a);
+
+}
+
+
+void AliTPC::RemapTrackHitIDs(Int_t *map)
+{
+  if (!fTrackHits) return;
+  AliObjectArray * arr = fTrackHits->fTrackHitsInfo;
+  for (UInt_t i=0;i<arr->GetSize();i++){
+    AliTrackHitsInfo * info = (AliTrackHitsInfo *)(arr->At(i));
+    info->fTrackID = map[info->fTrackID];
+  }
+  
+}
+
+
+//_____________________________________________________________________________
+void AliTPC::LoadPoints2(Int_t)
+{
+  //
+  // Store x, y, z of all hits in memory
+  //
+  if (fTrackHits == 0) return;
+  //
+  Int_t nhits = fTrackHits->GetEntriesFast();
+  if (nhits == 0) return;
+  Int_t tracks = gAlice->GetNtrack();
+  if (fPoints == 0) fPoints = new TObjArray(tracks);
+  AliHit *ahit;
+  //
+  Int_t *ntrk=new Int_t[tracks];
+  Int_t *limi=new Int_t[tracks];
+  Float_t **coor=new Float_t*[tracks];
+  for(Int_t i=0;i<tracks;i++) {
+    ntrk[i]=0;
+    coor[i]=0;
+    limi[i]=0;
+  }
+  //
+  AliPoints *points = 0;
+  Float_t *fp=0;
+  Int_t trk;
+  Int_t chunk=nhits/4+1;
+  //
+  // Loop over all the hits and store their position
+  //
+  ahit = FirstHit2(-1);
+  //for (Int_t hit=0;hit<nhits;hit++) {
+  while (ahit){
+    //    ahit = (AliHit*)fHits->UncheckedAt(hit);
+    trk=ahit->GetTrack();
+    if(ntrk[trk]==limi[trk]) {
+      //
+      // Initialise a new track
+      fp=new Float_t[3*(limi[trk]+chunk)];
+      if(coor[trk]) {
+       memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]);
+       delete [] coor[trk];
+      }
+      limi[trk]+=chunk;
+      coor[trk] = fp;
+    } else {
+      fp = coor[trk];
+    }
+    fp[3*ntrk[trk]  ] = ahit->X();
+    fp[3*ntrk[trk]+1] = ahit->Y();
+    fp[3*ntrk[trk]+2] = ahit->Z();
+    ntrk[trk]++;
+    ahit = NextHit2();
+  }
+  //
+  for(trk=0; trk<tracks; ++trk) {
+    if(ntrk[trk]) {
+      points = new AliPoints();
+      points->SetMarkerColor(GetMarkerColor());
+      points->SetMarkerSize(GetMarkerSize());
+      points->SetDetector(this);
+      points->SetParticle(trk);
+      points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle());
+      fPoints->AddAt(points,trk);
+      delete [] coor[trk];
+      coor[trk]=0;
+    }
+  }
+  delete [] coor;
+  delete [] ntrk;
+  delete [] limi;
+}
+
+
+//_____________________________________________________________________________
+void AliTPC::LoadPoints3(Int_t)
+{
+  //
+  // Store x, y, z of all hits in memory
+  // - only intersection point with pad row
+  if (fTrackHits == 0) return;
+  //
+  Int_t nhits = fTrackHits->GetEntriesFast();
+  if (nhits == 0) return;
+  Int_t tracks = gAlice->GetNtrack();
+  if (fPoints == 0) fPoints = new TObjArray(2*tracks);
+  fPoints->Expand(2*tracks);
+  AliHit *ahit;
+  //
+  Int_t *ntrk=new Int_t[tracks];
+  Int_t *limi=new Int_t[tracks];
+  Float_t **coor=new Float_t*[tracks];
+  for(Int_t i=0;i<tracks;i++) {
+    ntrk[i]=0;
+    coor[i]=0;
+    limi[i]=0;
+  }
+  //
+  AliPoints *points = 0;
+  Float_t *fp=0;
+  Int_t trk;
+  Int_t chunk=nhits/4+1;
+  //
+  // Loop over all the hits and store their position
+  //
+  ahit = FirstHit2(-1);
+  //for (Int_t hit=0;hit<nhits;hit++) {
+
+  Int_t lastrow = -1;
+  while (ahit){
+    //    ahit = (AliHit*)fHits->UncheckedAt(hit);
+    trk=ahit->GetTrack(); 
+    Float_t  x[3]={ahit->X(),ahit->Y(),ahit->Z()};
+    Int_t    index[3]={1,((AliTPChit*)ahit)->fSector,0};
+    Int_t    currentrow = fTPCParam->GetPadRow(x,index) ;
+    if (currentrow!=lastrow){
+      lastrow = currentrow;
+      //later calculate intersection point           
+      if(ntrk[trk]==limi[trk]) {
+       //
+       // Initialise a new track
+       fp=new Float_t[3*(limi[trk]+chunk)];
+       if(coor[trk]) {
+         memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]);
+         delete [] coor[trk];
+       }
+       limi[trk]+=chunk;
+       coor[trk] = fp;
+      } else {
+       fp = coor[trk];
+      }
+      fp[3*ntrk[trk]  ] = ahit->X();
+      fp[3*ntrk[trk]+1] = ahit->Y();
+      fp[3*ntrk[trk]+2] = ahit->Z();
+      ntrk[trk]++;
+    }
+    ahit = NextHit2();
+  }
+  
+  //
+  for(trk=0; trk<tracks; ++trk) {
+    if(ntrk[trk]) {
+      points = new AliPoints();
+      points->SetMarkerColor(GetMarkerColor()+1);
+      points->SetMarkerStyle(5);
+      points->SetMarkerSize(0.2);
+      points->SetDetector(this);
+      points->SetParticle(trk);
+      //      points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle()20);
+      points->SetPolyMarker(ntrk[trk],coor[trk],30);
+      fPoints->AddAt(points,tracks+trk);
+      delete [] coor[trk];
+      coor[trk]=0;
+    }
+  }
+  delete [] coor;
+  delete [] ntrk;
+  delete [] limi;
+}
+
+
+
+void AliTPC::FindTrackHitsIntersection(TClonesArray * arr)
+{
+
+  //
+  //fill clones array with intersection of current point with the
+  //middle of the row
+  Int_t sector;
+  Int_t ipart;
+  
+  const Int_t kcmaxhits=30000;
+  TVector * xxxx = new TVector(kcmaxhits*4);
+  TVector & xxx = *xxxx;
+  Int_t maxhits = kcmaxhits;
+      
+  //
+  AliTPChit * tpcHit=0;
+  tpcHit = (AliTPChit*)FirstHit2(-1);
+  Int_t currentIndex=0;
+  Int_t lastrow=-1;  //last writen row
+
+  while (tpcHit){
+    if (tpcHit==0) continue;
+    sector=tpcHit->fSector; // sector number
+    ipart=tpcHit->Track();
+    
+    //find row number
+    
+    Float_t  x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()};
+    Int_t    index[3]={1,sector,0};
+    Int_t    currentrow = fTPCParam->GetPadRow(x,index) ;      
+    if (currentrow<0) continue;
+    if (lastrow<0) lastrow=currentrow;
+    if (currentrow==lastrow){
+      if ( currentIndex>=maxhits){
+       maxhits+=kcmaxhits;
+       xxx.ResizeTo(4*maxhits);
+      }     
+      xxx(currentIndex*4)=x[0];
+      xxx(currentIndex*4+1)=x[1];
+      xxx(currentIndex*4+2)=x[2];      
+      xxx(currentIndex*4+3)=tpcHit->fQ;
+      currentIndex++;  
+    }
+    else 
+      if (currentIndex>2){
+       Float_t sumx=0;
+       Float_t sumx2=0;
+       Float_t sumx3=0;
+       Float_t sumx4=0;
+       Float_t sumy=0;
+       Float_t sumxy=0;
+       Float_t sumx2y=0;
+       Float_t sumz=0;
+       Float_t sumxz=0;
+       Float_t sumx2z=0;
+       Float_t sumq=0;
+       for (Int_t index=0;index<currentIndex;index++){
+         Float_t x,x2,x3,x4;
+         x=x2=x3=x4=xxx(index*4);
+         x2*=x;
+         x3*=x2;
+         x4*=x3;
+         sumx+=x;
+         sumx2+=x2;
+         sumx3+=x3;
+         sumx4+=x4;
+         sumy+=xxx(index*4+1);
+         sumxy+=xxx(index*4+1)*x;
+         sumx2y+=xxx(index*4+1)*x2;
+         sumz+=xxx(index*4+2);
+         sumxz+=xxx(index*4+2)*x;
+         sumx2z+=xxx(index*4+2)*x2;     
+         sumq+=xxx(index*4+3);
+       }
+       Float_t centralPad = (fTPCParam->GetNPads(sector,lastrow)-1)/2;
+       Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+
+         sumx2*(sumx*sumx3-sumx2*sumx2);
+       
+       Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+
+         sumx2*(sumxy*sumx3-sumx2y*sumx2);
+       Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+
+         sumx2*(sumxz*sumx3-sumx2z*sumx2);
+       
+       Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+
+         sumx2*(sumx*sumx2y-sumx2*sumxy);
+       Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+
+         sumx2*(sumx*sumx2z-sumx2*sumxz);
+       
+       Float_t y=detay/det+centralPad;
+       Float_t z=detaz/det;    
+       Float_t by=detby/det; //y angle
+       Float_t bz=detbz/det; //z angle
+       sumy/=Float_t(currentIndex);
+       sumz/=Float_t(currentIndex);
+       
+       AliComplexCluster cl;
+       cl.fX=z;
+       cl.fY=y;
+       cl.fQ=sumq;
+       cl.fSigmaX2=bz;
+       cl.fSigmaY2=by;
+       cl.fTracks[0]=ipart;
+       
+       AliTPCClustersRow * row = (fClustersArray->GetRow(sector,lastrow));
+       if (row!=0) row->InsertCluster(&cl);
+       currentIndex=0;
+       lastrow=currentrow;
+      } //end of calculating cluster for given row
+               
+  } // end of loop over hits
+  xxxx->Delete();
+
+}
+//_______________________________________________________________________________
+void AliTPC::Digits2Reco(Int_t eventnumber)
+{
+  // empty for a time being
+}