/*
$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
#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"
#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"
#include "AliTPCtracker.h"
#include <TInterpreter.h>
+#include <TTree.h>
+
+
ClassImp(AliTPC)
//MI changes
fDigitsArray = 0;
fClustersArray = 0;
- fTPCParam=0;
+ fDefaults = 0;
+ fTrackHits = 0;
+ fHitType = 2;
+ fTPCParam = 0;
}
//_____________________________________________________________________________
//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;
// 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;
delete fHits;
delete fDigits;
delete fTPCParam;
+ delete fTrackHits; //MI 15.09.2000
}
//_____________________________________________________________________________
//
// 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);
}
//_____________________________________________________________________________
//-----------------------------------------------------------------
// 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
//-----------------------------------------------
//-----------------------------------------------------------------
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
Float_t amol[3];
- // CO2
+ // CO2
amat[0]=12.011;
amat[1]=15.9994;
amol[0] = amat[0]*wmat[0]+amat[1]*wmat[1];
AliMixture(10,"CO2",amat,zmat,density,-2,wmat);
-
+
// CF4
amat[0]=12.011;
AliMixture(11,"CF4",amat,zmat,density,-2,wmat);
+
// CH4
amat[0]=12.011;
//----------------------------------------------------------------
// 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
}
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;
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
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;
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);
//
// 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
// 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
cerr<<"Number of made clusters : "<<nclusters<<" \n";
- carray.GetTree()->Write();
+ carray.GetTree()->Write(cname);
savedir->cd(); //switch back to the input file
//
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;
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
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;
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;
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)
{
// 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();
TObjArray **row;
- printf("*** Processing sector number %d ***\n",isec);
+ printf("*** Processing sector number %d ***\n",isec);
Int_t nrows =fTPCParam->GetNRow(isec);
Int_t i;
- if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree();
+ if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree(fDigitsFile);
for (i=0;i<nrows;i++){
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);
} // 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
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)?
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,
// 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
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
//---------------------------------------------------
- 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()*
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
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
//
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.
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
}
//_____________________________________________________________________________
fSens = sens;
}
+
void AliTPC::SetSide(Float_t side=0.)
{
//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)
}
+//________________________________________________________________________
+// 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
+}