which included commits to RCS files with non-trunk default branches.
--- /dev/null
+#include <TFile.h>
+#include "TGraphAsymmErrors.h"
+#include "TString.h"
+#include "TStopwatch.h"
+#include "AliL3Benchmark.h"
+#include "TStopwatch.h"
+#include "TMath.h"
+#include "AliL3Logging.h"
+
+ClassImp(AliL3Benchmark)
+
+AliL3Benchmark::AliL3Benchmark()
+{
+ fNbench = 0;
+ fNmax = 20;
+ fNames = 0;
+ fTimer = 0;
+ fSum = 0;
+ fMin = 0;
+ fMax = 0;
+ fCount = 0;
+// fStopwatch = 0;
+}
+
+AliL3Benchmark::~AliL3Benchmark()
+{
+ fNbench = 0;
+ if (fNames) {delete [] fNames; fNames = 0;}
+ if (fTimer) {delete [] fTimer; fTimer = 0;}
+ if (fSum) {delete [] fSum; fSum = 0;}
+ if (fMin) {delete [] fMin; fMin = 0;}
+ if (fMax) {delete [] fMax; fMax = 0;}
+ if (fCount) {delete [] fCount; fCount =0;}
+// if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+}
+
+Int_t AliL3Benchmark::GetBench(const char *name)
+{
+ for (Int_t i=0;i<fNbench;i++) {
+ if (!strcmp(name,(const char*)fNames[i])) return i;
+ }
+ return -1;
+}
+
+
+void AliL3Benchmark::Start(const char *name)
+{
+ if (!fNbench) {
+ fNames = new TString[fNmax];
+ fTimer = new TStopwatch[fNmax];
+ fSum = new Float_t[fNmax];
+ fMin = new Float_t[fNmax];
+ fMax = new Float_t[fNmax];
+ fCount = new Int_t[fNmax];
+ for(Int_t i =0;i<fNmax;i++){
+ fSum[i]=0;
+ fMin[i]=0;
+ fMax[i]=0;
+ fCount[i]=0;
+ }
+ }
+ Int_t bench = GetBench(name);
+ if (bench < 0 && fNbench < fNmax ) {
+ // define a new benchmark to Start
+ fNames[fNbench] = name;
+ bench = fNbench;
+ fNbench++;
+ fTimer[bench].Reset();
+ fTimer[bench].Start();
+// if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+// fStopwatch = new TStopwatch();
+// fStopwatch->Reset();
+// fStopwatch->Start();
+ } else if (bench >=0) {
+ // Resume the existen benchmark
+ fTimer[bench].Reset();
+ fTimer[bench].Start();
+// if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+// fStopwatch = new TStopwatch();
+// fStopwatch->Reset();
+// fStopwatch->Start();
+ }
+ else
+ LOG(AliL3Log::kWarning,"AliL3Benchmark::Start","Start")
+ <<"too many benches"<<ENDLOG;
+}
+
+void AliL3Benchmark::Stop(const char *name)
+{
+ Int_t bench = GetBench(name);
+ if (bench < 0) return;
+
+ fTimer[bench].Stop();
+ Float_t val = fTimer[bench].CpuTime();
+// fStopwatch->Stop();
+// Float_t val = fStopwatch->CpuTime();
+
+ fSum[bench] += val;
+ fCount[bench]++;
+ if(fCount[bench]==1){
+ fMin[bench] = val;
+ fMax[bench] = val;
+ }
+ else{
+ if(val<fMin[bench])fMin[bench]=val;
+ if(val>fMax[bench])fMax[bench]=val;
+ }
+}
+
+void AliL3Benchmark::Analyze(const char* name){
+ Float_t *x = new Float_t[fNbench];
+ Float_t *y = new Float_t[fNbench];
+ Float_t *eyl = new Float_t[fNbench];
+ Float_t *eyh = new Float_t[fNbench];
+ char filename[256];
+ sprintf(filename,"%s.dat",name);
+ FILE *f= fopen(filename,"w");
+ for (Int_t i=0;i<fNbench;i++) {
+ Float_t av =0;
+ if(fCount[i]) av = fSum[i]/fCount[i];
+ x[i]=i+1;
+ y[i]=av*1000;
+ eyl[i]=(av-fMin[i])*1000;
+ eyh[i]=(fMax[i]-av)*1000;
+ fprintf(f,"%2d. %s: ",i+1,fNames[i].Data());
+ fprintf(f,"%4.0f ms\n",av*1000);
+ }
+ fclose(f);
+ sprintf(filename,"%s.tmp",name);
+/* only a workaround!!
+ FILE *f2= fopen(filename,"w");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",x[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",y[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",eyl[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",eyh[i]); fprintf(f2,"\n");
+ fclose(f2);
+*/
+ sprintf(filename,"%s.root",name);
+ TFile *file = new TFile(filename,"RECREATE");
+ TGraphAsymmErrors *gr = new TGraphAsymmErrors(fNbench,x,y,0,0,eyl,eyh);
+ gr->SetTitle("benchmark");
+ gr->SetMarkerStyle(8);
+ gr->SetMinimum(0);
+ gr->Draw("ALP");
+ gr->Write();
+ file->Close();
+ delete file;
+ file=0;
+ delete[] x;
+ delete[] y;
+ delete[] eyl;
+ delete[] eyh;
+}
+
+
--- /dev/null
+#ifndef AliL3_Benchmark
+#define AliL3_Benchmark
+
+#include <Rtypes.h>
+
+class TStopwatch;
+class TString;
+class AliL3Benchmark {
+
+private:
+
+ Int_t fNbench; //Number of active benchmarks
+ Int_t fNmax; //Maximum number of benchmarks initialized
+ TString *fNames; //Names of benchmarks
+ TStopwatch *fTimer; //Timers
+ Float_t *fSum;
+ Float_t *fMin;
+ Float_t *fMax;
+ Int_t *fCount;
+
+// TStopwatch *fStopwatch; //Stopwatch
+public:
+ AliL3Benchmark();
+ virtual ~AliL3Benchmark();
+ Int_t GetBench(const char *name);
+ void Start(const char *name);
+ void Stop(const char *name);
+ void Analyze(const char* name);
+
+ ClassDef(AliL3Benchmark,0) //L3 benchmark
+};
+
+#endif
--- /dev/null
+//Author: Anders Strand Vestbo
+//Last Modified: 14.12.2000
+
+#include <iostream.h>
+
+#include "AliL3Logging.h"
+#include "AliL3ClustFinder.h"
+#include "AliL3Transform.h"
+#include "AliL3DigitData.h"
+#include "AliL3SpacePointData.h"
+
+//
+//Simple clusterfinder. Initial version by Tonko.
+//
+
+ClassImp(AliL3ClustFinder)
+
+AliL3ClustFinder::AliL3ClustFinder()
+{
+
+ fDeconvTime=false;
+ fDeconvPad=false;
+ fXYErr = 0;
+ fZErr = 0;
+}
+
+AliL3ClustFinder::AliL3ClustFinder(AliL3Transform *transform)
+{
+
+ fTransform = transform;
+
+ fThreshold = 20;
+ fDeconvTime = true;
+ fDeconvPad = true;
+}
+
+
+AliL3ClustFinder::~AliL3ClustFinder()
+{
+ //destructor
+}
+
+
+ void AliL3ClustFinder::SetTransformer( AliL3Transform *transform )
+ {
+ fTransform = transform;
+ }
+
+
+void AliL3ClustFinder::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
+{
+ fNClusters = 0;
+ fMaxNClusters = nmaxpoints;
+ fCurrentSlice = slice;
+ fCurrentPatch = patch;
+ fFirstRow = firstrow;
+ fLastRow = lastrow;
+}
+
+
+void AliL3ClustFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
+{
+ fNClusters = 0;
+ fMaxNClusters = nmaxpoints;
+ fCurrentSlice = slice;
+ fCurrentPatch = patch;
+}
+
+void AliL3ClustFinder::SetOutputArray(AliL3SpacePointData *pt)
+{
+
+ fSpacePointData = pt;
+}
+
+void AliL3ClustFinder::Read(UInt_t ndigits,AliL3DigitRowData *ptr)
+{
+ fNDigitRowData = ndigits;
+ fDigitRowData = ptr;
+
+}
+
+void AliL3ClustFinder::ProcessDigits()
+{
+ //Loop over rows, and call processrow
+
+
+ AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fDigitRowData;
+
+ for(Int_t i=fFirstRow; i<=fLastRow; i++)
+ {
+ fCurrentRow = i;
+ ProcessRow(tempPt);
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliL3DigitRowData) + tempPt->fNDigit*sizeof(AliL3DigitData);
+ tmp += size;
+ tempPt = (AliL3DigitRowData*)tmp;
+ }
+
+ LOG(AliL3Log::kInformational,"AliL3ClustFinder","Cluster Finder")
+ <<AliL3Log::kDec<<"ClusterFinder found "<<fNClusters<<" clusters"<<ENDLOG;
+}
+
+void AliL3ClustFinder::ProcessRow(AliL3DigitRowData* tempPt)
+{
+
+ Int_t cl_found,trackID[3];
+ //UInt_t rows;
+
+ //Reserve array for found clusters:
+ resx aliresx[5000];
+ bzero((char *)aliresx,5000*sizeof(resx));
+
+ //local results
+ resx *r;
+// UInt_t pres1[2500],pres2[2500];
+ resx *pres1[2500];
+ resx *pres2[2500];
+ resx rr_local;
+ resx *rr = &rr_local;
+
+ //Set variables for each row:
+ Int_t pres_cou1,pres_cou2;
+// UInt_t *r1,*r2;
+ resx **r1,**r2;
+ pres_cou1=pres_cou2=0;
+ r1=pres2;
+ r2=pres1;
+ r=aliresx;
+
+ //variables for each pad:
+ UInt_t start;
+ Int_t start_new=-1;
+ Int_t go_on;
+ Int_t cl_counter=0,rows;
+ Int_t prev_start;
+
+ UInt_t last_pad = 123456789;
+
+ //Loop over digits in this row:
+ for(start=0; start<tempPt->fNDigit; start++)
+ {
+ AliL3DigitData *bins = tempPt->fDigitData;
+
+ if(bins[start].fPad!=last_pad)
+ {//new pad
+
+ last_pad=bins[start].fPad;
+
+ if(r2==pres2)
+ {
+ r1=pres2;
+ r2=pres1;
+ }
+ else
+ {
+ r1=pres1;
+ r2=pres2;
+ }
+ pres_cou1=pres_cou2;
+ pres_cou2=0;
+
+ start_new=-1;
+
+ cl_counter=0;
+ prev_start=0;
+
+
+ }//Looping over pads
+
+ UInt_t av,charge;
+ UInt_t mean;
+ UInt_t flags;
+ Int_t last_falling=0;
+// UInt_t *ri;
+ resx **ri;
+ UInt_t tmp_charge;
+
+ //Set flag:
+ flags=0;
+
+ cl_counter++;
+ if(cl_counter>MAX_C) {LOG(AliL3Log::kWarning,"AliL3ClustFinder::ProcessRow","Cluster Finder")
+ <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG; return;} //too many clusters
+
+
+ if(fDeconvTime)
+ {
+
+ //this is a goto label:
+ redo: ;
+ //divide sequenz in two in case there is a change in slope:
+ if(start_new>-1)
+ {
+ start=start_new;
+ start_new=-1;
+ }
+ }
+ //average and charge
+ av=charge=0;
+
+ //ok, create a new cluster:
+ go_on=1;
+
+ if(fDeconvTime)
+ {
+
+ last_falling=flags=0;
+ }
+
+ if(fDeconvPad)
+ {
+ flags=0;
+ }
+
+
+ //block to introduce new variables:
+ {
+ UInt_t last_a;
+ last_a=0;
+
+ //Loop over this sequenz:
+ while(1)
+ {
+ UInt_t aa;
+ //Int_t start_temp=start;
+
+ //get the adc-value:
+ aa=bins[start].fCharge;
+
+
+ if(fDeconvTime)
+ {
+ //Check if the last pixel in this sequenz is bigger or smaller than this:
+ if(aa>last_a)
+ {
+ if(last_falling)
+ {
+ start_new=start;
+ break;
+ }
+ }
+ else last_falling=1;
+ last_a=aa;
+
+ }
+ //sum of total charge of this cluster on this pad
+ charge +=aa;
+ //this one is needed to determine the mean over all pads:
+ //av += start * (aa);
+ av+=bins[start].fTime*(aa);
+
+ if((bins[start+1].fTime)!=(bins[start].fTime+1) ||
+ ((bins[start+1].fPad)!=(bins[start].fPad))) break;
+
+ start++;
+ }//Loop over sequenz
+ }//block of new variables
+
+ if(fDeconvTime)
+ {
+ if(start_new>0) flags = FLAG_DOUBLE_T;
+ }
+ //calculate mean in time direction for this sequenz:
+ if(charge)
+ {
+ //mean=cog for this sequenz:
+ mean=av/charge;
+ }
+ else
+ {
+ charge=1;
+ mean=1;
+ }
+ //get the pointer to results on previous pad(s)
+ ri=r1;
+
+ //Center of gravity in pad direction
+ //tmp_charge=charge*bins[start-1].fPad;
+ tmp_charge=charge*bins[start].fPad;
+
+ //compare with prevously stored results (previous pads)
+ for(int k=0; k<pres_cou1; k++)
+ {
+ //variable to store difference:
+ Int_t v;
+
+ //structure that contains means (+more) of last pads(s)
+ resx *rr_tmp;
+
+ //go get it
+ rr_tmp = (resx *) *ri;
+
+ //difference between mean and mean on previous pads
+ v=mean-rr_tmp->mean;
+
+
+ if(v<-PARAM1) break;
+
+ //goto next mean on previous pad
+ ri++;
+
+ //is there a matching cluster on previous pad:
+ if(v<=PARAM1)
+ {
+ //ok, we got a new one, so we will add the new and the old
+ rr=&rr_local;
+
+ //Add this function somewhere
+ memcpy7((UInt_t *)rr,(UInt_t *)rr_tmp);
+
+ /* in case we found another sequenz-section on this pad
+ don't loop over all sequenzes on last pad but start
+ where we found a matching candidate for this sequenz-
+ section, adjust upper limit (=pres_cou1)*/
+ r1=ri;
+ pres_cou1-=1+k;
+
+ if(fDeconvPad)
+ {
+ if(charge>rr->scharge)
+ {
+ if(rr->falling)
+ {
+ //previous state was falling
+ flags |= FLAG_DOUBLE_PAD;
+ rr_tmp->flags |= flags;
+ //and create a new one
+ break;
+ }
+ }
+ else
+ {
+ rr->falling = 1;
+ }
+
+ }
+ //don't create a new one
+ go_on=0;
+
+ //store the pointer to the matched in "2"
+// r2[pres_cou2++] = (UInt_t) rr_tmp;
+ r2[pres_cou2++] = rr_tmp;
+
+ //calculate and fill the new means, charge etc. in rr_tmp
+ //charge on this pad to determine whether we cut in pad direction
+ rr->scharge = charge;
+ //unset FLAG_ONEPAD since we have at least 2 pads
+ rr->flags &= (~FLAG_ONEPAD);
+ //summ the charges for de/dx
+ rr->charge += charge;
+ //calculate mean in pad direction
+ rr->pad += tmp_charge;
+ //calculate mean in time direction
+ rr->t+=av;
+ //store the mean of this sequenz on this pad
+ rr->mean = mean;
+
+ //Copy it back to storage
+ memcpy7((UInt_t *)rr_tmp,(UInt_t *)rr);
+
+ //we found a matching one so stop looping over pads on previous pad
+ break;
+
+ }//matching cluster on previous pads
+ }//loop: means on previous pad
+
+ //here we create from scratch new clusters
+ if(go_on)
+ {
+ //store this one beacuse it is the first
+// r2[pres_cou2++]= (UInt_t )r;
+ r2[pres_cou2++]= r;
+
+ mstore((UInt_t *)r,av,tmp_charge,charge,flags|FLAG_ONEPAD,mean,trackID);
+ r++;
+ }
+
+ if(fDeconvTime)
+ {
+
+ //maybe we still have to do something
+ if(start_new>=0) goto redo;
+ }
+
+ }//end of loop over digits
+
+
+ //number of clusters found
+ cl_found = r-aliresx;
+
+ //tot_cl_found+=cl_found;
+
+ //there was something on this padrow
+ rows++;
+
+ WriteClusters(cl_found,aliresx);
+
+}
+
+void AliL3ClustFinder::memcpy7(UInt_t *dst, UInt_t *src)
+{
+ Int_t i;
+ for(i=0; i<7; i++)
+ {
+ *dst++ = *src++;
+ }
+ return;
+}
+
+void AliL3ClustFinder::mstore(UInt_t *r,UInt_t av,UInt_t pad,UInt_t ch,UInt_t flags,UInt_t mean,Int_t *trackID)
+{
+ resx *rr = (resx *) r;
+
+ rr->mean = mean;
+ rr->charge = ch;
+ rr->flags =flags;
+ rr->scharge = ch;
+ rr->pad = pad;
+ rr->t = av;
+ rr->falling=0;
+
+ rr->trackID[0]=trackID[0];
+ rr->trackID[1]=trackID[1];
+ rr->trackID[2]=trackID[2];
+ return;
+}
+
+void AliL3ClustFinder::WriteClusters(Int_t ncl,resx *r)
+{
+/*
+ if(fNClusters >= fMaxNClusters)
+ {
+ LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
+ <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
+ return;
+ }
+*/
+ Int_t thisrow,thissector;
+ UInt_t counter = fNClusters;
+
+ if(!fXYErr || !fZErr)
+ {
+ LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Errors")
+ <<"No Errors"<<ENDLOG;
+ return;
+ }
+
+ for(int j=0; j<ncl; j++)
+ {
+ if(r[j].flags & FLAG_ONEPAD) continue; //discard 1 pad clusters
+ if(r[j].charge < fThreshold) continue; //noise cluster
+ Float_t xyz[3];
+
+ Float_t fpad=(Float_t)r[j].pad/(Float_t)r[j].charge;
+ Float_t ftime=(Float_t)r[j].t/(Float_t)r[j].charge;
+
+ if(fCurrentRow > 54) {thisrow = fCurrentRow-55; thissector = fCurrentSlice+36;}
+ else {thisrow = fCurrentRow; thissector = fCurrentSlice;}
+ fTransform->Raw2Local(xyz,thissector,thisrow,fpad,ftime);
+ if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder")
+ <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG;
+ if(fNClusters >= fMaxNClusters)
+ {
+ LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
+ <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
+ return;
+ }
+ fSpacePointData[counter].fX = xyz[0];
+ fSpacePointData[counter].fY = xyz[1];
+ fSpacePointData[counter].fZ = xyz[2];
+ fSpacePointData[counter].fPadRow = fCurrentRow;
+ fSpacePointData[counter].fXYErr = fXYErr;
+ fSpacePointData[counter].fZErr = fZErr;
+ fSpacePointData[counter].fID = counter
+ +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);//uli
+
+
+ fNClusters++;
+ counter++;
+
+ }
+
+
+}
--- /dev/null
+#ifndef ALIL3_ClustFinder
+#define ALIL3_ClustFinder
+
+#include "AliL3RootTypes.h"
+class AliL3Transform;
+
+#define FLAG_ONEPAD 1 //cluster had only one pad
+#define FLAG_DOUBLE_PAD 2
+#define FLAG_DOUBLE_T 1//4
+#define PARAM1 1//4
+#define MAX_C 112 //Maximum number of clusters on 1 pad.
+
+
+
+struct resx
+{
+ UInt_t t ;
+ UInt_t pad ;
+ UInt_t charge ;
+ UInt_t flags ;
+ Int_t mean ;
+ UInt_t falling ;
+ UInt_t scharge ;
+
+ Int_t trackID[3];
+};
+typedef struct resx resx;
+
+class AliL3DigitRowData;
+class AliL3SpacePointData;
+
+class AliL3ClustFinder {
+
+ private:
+
+ AliL3Transform *fTransform; //!
+
+ UInt_t fNDigitRowData;
+ AliL3DigitRowData *fDigitRowData; //!
+
+
+ AliL3SpacePointData *fSpacePointData; //!
+ Int_t fNClusters;
+ Int_t fMaxNClusters;
+ Int_t fFirstRow;
+ Int_t fLastRow;
+ Int_t fCurrentSlice;
+ Int_t fCurrentPatch;
+ Int_t fCurrentRow;
+ Bool_t fDeconvTime;
+ Bool_t fDeconvPad;
+ UInt_t fThreshold;
+
+ Float_t fXYErr;
+ Float_t fZErr;
+
+ public:
+ AliL3ClustFinder();
+ AliL3ClustFinder(AliL3Transform *transform);
+ virtual ~AliL3ClustFinder();
+
+ void SetTransformer( AliL3Transform *transform );
+ void InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t maxpoints);
+ void InitSlice(Int_t slice,Int_t patch,Int_t maxpoints);
+ void Read(UInt_t ndigits,AliL3DigitRowData *ptr);
+ void ProcessDigits();
+ void ProcessRow(AliL3DigitRowData *tempPt);
+ void SetOutputArray(AliL3SpacePointData *pt);
+
+ void memcpy7(UInt_t *dst, UInt_t *src);
+ void mstore(UInt_t *r,UInt_t av,UInt_t pad,UInt_t ch,UInt_t flags,UInt_t mean,Int_t *trackID);
+ void WriteClusters(Int_t ncl,resx *r);
+
+ void SetXYError(Float_t f) {fXYErr = f;}
+ void SetZError(Float_t f) {fZErr = f;}
+
+ //Getters
+ Int_t GetNumberOfClusters() {return fNClusters;}
+
+ ClassDef(AliL3ClustFinder,1)
+};
+
+#endif
--- /dev/null
+#include <math.h>
+
+#include "AliL3Logging.h"
+#include "AliL3ConfMapFit.h"
+#include "AliL3Vertex.h"
+#include "AliL3ConfMapTrack.h"
+#include "AliL3ConfMapPoint.h"
+
+//_______________________________
+// AliL3ConfMapFit
+//
+// Fit class for conformal mapping tracking
+
+ClassImp(AliL3ConfMapFit)
+
+Double_t AliL3ConfMapFit::pi=3.14159265358979323846;
+
+AliL3ConfMapFit::AliL3ConfMapFit(AliL3ConfMapTrack *track,AliL3Vertex *vertex)
+{
+ //constructor
+ fTrack = track;
+ fVertex = vertex;
+ BFACT = 0.0029980;
+ bField = 0.2;
+
+}
+
+Int_t AliL3ConfMapFit::FitHelix()
+{
+ if(FitCircle())
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapFit::FitHelix","TrackFit")<<AliL3Log::kDec<<
+ "Problems during circle fit"<<ENDLOG;
+ return 1;
+ }
+ if(FitLine())
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapFit::FitHelix","TrackFit")<<AliL3Log::kDec<<
+ "Problems during line fit"<<ENDLOG;
+ return 1;
+ }
+ return 0;
+}
+
+Int_t AliL3ConfMapFit::FitCircle()
+{
+ //-----------------------------------------------------------------
+ //Fits circle parameters using algorithm
+ //described by ChErnov and Oskov in Computer Physics
+ //Communications.
+ //
+ //Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin
+ //Moved to C by Pablo Yepes
+ //Moved to AliROOT by ASV.
+ //------------------------------------------------------------------
+
+ Double_t wsum = 0.0 ;
+ Double_t xav = 0.0 ;
+ Double_t yav = 0.0 ;
+
+ Int_t num_of_hits = fTrack->GetNumberOfPoints();
+ //
+ // Loop over hits calculating average
+ Int_t co=0;
+
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ co++;
+ AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)fTrack->currentHit;
+ cHit->SetXYWeight( 1./ (Double_t)(cHit->GetXerr()*cHit->GetXerr() + cHit->GetYerr()*cHit->GetYerr()) );
+ wsum += cHit->GetXYWeight() ;
+ xav += cHit->GetXYWeight() * cHit->GetX() ;
+ yav += cHit->GetXYWeight() * cHit->GetY() ;
+ }
+ if(co!=num_of_hits)
+ LOG(AliL3Log::kError,"AliL3ConfMapFit::FitCircle","TrackFit")<<AliL3Log::kDec<<
+ "Mismatch of hits. Counter: "<<co<<" nHits: "<<num_of_hits<<ENDLOG;
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ wsum += fVertex->GetXYWeight() ;
+ xav += fVertex->GetX() ;
+ yav += fVertex->GetY() ;
+ }
+
+ xav = xav / wsum ;
+ yav = yav / wsum ;
+//
+// CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
+//
+ Double_t xxav = 0.0 ;
+ Double_t xyav = 0.0 ;
+ Double_t yyav = 0.0 ;
+ Double_t xi, yi ;
+
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint *)hits->At(hit_counter);
+ AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)fTrack->currentHit;
+ xi = cHit->GetX() - xav ;
+ yi = cHit->GetY() - yav ;
+ xxav += xi * xi * cHit->GetXYWeight() ;
+ xyav += xi * yi * cHit->GetXYWeight() ;
+ yyav += yi * yi * cHit->GetXYWeight() ;
+ }
+
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ xi = fVertex->GetX() - xav ;
+ yi = fVertex->GetY() - yav ;
+ xxav += xi * xi * fVertex->GetXYWeight() ;
+ xyav += xi * yi * fVertex->GetXYWeight() ;
+ yyav += yi * yi * fVertex->GetXYWeight() ;
+ }
+ xxav = xxav / wsum ;
+ xyav = xyav / wsum ;
+ yyav = yyav / wsum ;
+//
+//--> ROTATE COORDINATES SO THAT <XY> = 0
+//
+//--> SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
+//--> & > ==> NEW : (XXAV-YYAV) > 0
+//--> SIGN(S) = SIGN(XYAV) >
+
+ Double_t a = fabs( xxav - yyav ) ;
+ Double_t b = 4.0 * xyav * xyav ;
+
+ Double_t asqpb = a * a + b ;
+ Double_t rasqpb = sqrt ( asqpb) ;
+
+ Double_t splus = 1.0 + a / rasqpb ;
+ Double_t sminus = b / (asqpb * splus) ;
+
+ splus = sqrt (0.5 * splus ) ;
+ sminus = sqrt (0.5 * sminus) ;
+//
+//-> FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
+//
+ Double_t sinrot, cosrot ;
+ if ( xxav <= yyav ) {
+ cosrot = sminus ;
+ sinrot = splus ;
+ }
+ else {
+ cosrot = splus ;
+ sinrot = sminus ;
+ }
+//
+//-> REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
+//
+ if ( xyav < 0.0 ) sinrot = - sinrot ;
+//
+//--> WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
+//--> TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
+//--> OUTWARD FROM THE ORGIN. WE ARE FREE TO CHANGE SIGNS OF BOTH
+//--> COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
+//
+//--> CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
+//
+ if ( cosrot*xav+sinrot*yav < 0.0 ) {
+ cosrot = -cosrot ;
+ sinrot = -sinrot ;
+ }
+//
+//-> NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
+//
+ Double_t rrav = xxav + yyav ;
+ Double_t rscale = sqrt(rrav) ;
+
+ xxav = 0.0 ;
+ yyav = 0.0 ;
+ xyav = 0.0 ;
+ Double_t xrrav = 0.0 ;
+ Double_t yrrav = 0.0 ;
+ Double_t rrrrav = 0.0 ;
+
+ Double_t xixi, yiyi, riri, wiriri, xold, yold ;
+
+ //for (hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)hits->At(hit_counter);
+ AliL3ConfMapPoint* cHit = (AliL3ConfMapPoint*)fTrack->currentHit;
+
+ xold = cHit->GetX() - xav ;
+ yold = cHit->GetY() - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = cHit->GetXYWeight() * riri ;
+
+ xyav += cHit->GetXYWeight() * xi * yi ;
+ xxav += cHit->GetXYWeight() * xixi ;
+ yyav += cHit->GetXYWeight() * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+ //
+// Include vertex if required
+//
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ xold = fVertex->GetX() - xav ;
+ yold = fVertex->GetY() - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = fVertex->GetXYWeight() * riri ;
+
+ xyav += fVertex->GetXYWeight() * xi * yi ;
+ xxav += fVertex->GetXYWeight() * xixi ;
+ yyav += fVertex->GetXYWeight() * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+ //
+ //
+ //
+ //--> DIVIDE BY WSUM TO MAKE AVERAGES
+ //
+ xxav = xxav / wsum ;
+ yyav = yyav / wsum ;
+ xrrav = xrrav / wsum ;
+ yrrav = yrrav / wsum ;
+ rrrrav = rrrrav / wsum ;
+ xyav = xyav / wsum ;
+
+ Int_t const ntry = 5 ;
+//
+//--> USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
+//--> DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
+//
+ Double_t xrrxrr = xrrav * xrrav ;
+ Double_t yrryrr = yrrav * yrrav ;
+ Double_t rrrrm1 = rrrrav - 1.0 ;
+ Double_t xxyy = xxav * yyav ;
+
+ Double_t c0 = rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
+ Double_t c1 = - rrrrm1 + xrrxrr + yrryrr - 4.0*xxyy ;
+ Double_t c2 = 4.0 + rrrrm1 - 4.0*xxyy ;
+ Double_t c4 = - 4.0 ;
+//
+//--> COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
+//
+ Double_t c2d = 2.0 * c2 ;
+ Double_t c4d = 4.0 * c4 ;
+//
+//--> 0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
+//
+// LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
+ Double_t lamda = 0.0 ;
+ Double_t dlamda = 0.0 ;
+//
+ Double_t chiscl = wsum * rscale * rscale ;
+ Double_t dlamax = 0.001 / chiscl ;
+
+ Double_t p, pd ;
+ for ( int itry = 1 ; itry <= ntry ; itry++ ) {
+ p = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
+ pd = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
+ dlamda = -p / pd ;
+ lamda = lamda + dlamda ;
+ if (fabs(dlamda)< dlamax) break ;
+ }
+
+ Double_t chi2 = (Double_t)(chiscl * lamda) ;
+
+ fTrack->SetChiSq1(chi2);
+ // Double_t dchisq = chiscl * dlamda ;
+//
+//--> NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
+//
+ Double_t h11 = xxav - lamda ;
+ Double_t h14 = xrrav ;
+ Double_t h22 = yyav - lamda ;
+ Double_t h24 = yrrav ;
+ Double_t h34 = 1.0 + 2.0*lamda ;
+ if ( h11 == 0.0 || h22 == 0.0 ){
+ LOG(AliL3Log::kError,"AliL3ConfMapFit::FitCircle","TrackFit")<<AliL3Log::kDec<<
+ "Problems fitting circle"<<ENDLOG;
+ return 1 ;
+ }
+ Double_t rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
+
+ Double_t ratio, kappa, beta ;
+ if ( fabs(h22) > fabs(h24) ) {
+ ratio = h24 / h22 ;
+ rootsq = ratio * ratio + rootsq ;
+ kappa = 1.0 / sqrt(rootsq) ;
+ beta = - ratio * kappa ;
+ }
+ else {
+ ratio = h22 / h24 ;
+ rootsq = 1.0 + ratio * ratio * rootsq ;
+ beta = 1.0 / sqrt(rootsq) ;
+ if ( h24 > 0 ) beta = - beta ;
+ kappa = -ratio * beta ;
+ }
+ Double_t alpha = - (h14/h11) * kappa ;
+//
+//--> transform these into the lab coordinate system
+//--> first get kappa and back to real dimensions
+//
+ Double_t kappa1 = kappa / rscale ;
+ Double_t dbro = 0.5 / kappa1 ;
+//
+//--> next rotate alpha and beta and scale
+//
+ Double_t alphar = (cosrot * alpha - sinrot * beta)* dbro ;
+ Double_t betar = (sinrot * alpha + cosrot * beta)* dbro ;
+//
+//--> then translate by (xav,yav)
+//
+ Double_t acent = (double)(xav - alphar) ;
+ Double_t bcent = (double)(yav - betar ) ;
+ Double_t radius = (double)dbro ;
+//
+// Get charge
+//
+ Double_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
+
+ fTrack->SetCharge(q);
+
+//
+// Get other track parameters
+//
+ Double_t x0, y0,phi0,r0,psi,pt ;
+ if ( fTrack->ComesFromMainVertex() == true )
+ {
+ //flag = 1 ; // primary track flag
+ x0 = fVertex->GetX() ;
+ y0 = fVertex->GetY() ;
+ phi0 = fVertex->GetPhi() ;
+ r0 = fVertex->GetR() ;
+ fTrack->SetPhi0(phi0);
+ fTrack->SetR0(r0);
+ }
+ else
+ {
+ //AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)hits->Last();
+ AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)fTrack->lastHit;
+ //flag = 0 ; // primary track flag
+ x0 = lHit->GetX() ;
+ y0 = lHit->GetY() ;
+ phi0 = atan2(lHit->GetY(),lHit->GetX());
+ if ( phi0 < 0 ) phi0 += 2*pi;
+ r0 = sqrt ( lHit->GetX() * lHit->GetX() + lHit->GetY() * lHit->GetY() ) ;
+ fTrack->SetPhi0(phi0);
+ fTrack->SetR0(r0);
+ }
+ //
+ psi = (Double_t)atan2(bcent-y0,acent-x0) ;
+ psi = psi + q * 0.5F * pi ;
+ if ( psi < 0 ) psi = psi + 2*pi;
+
+ pt = (Double_t)(BFACT * bField * radius ) ;
+ fTrack->SetPsi(psi);
+ fTrack->SetPt(pt);
+
+ //
+// Get errors from fast fit
+//
+ //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+ return 0 ;
+
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliL3ConfMapFit::FitLine ( )
+{
+ //
+ //Initialization
+ //
+ Double_t sum = 0.F ;
+ Double_t ss = 0.F ;
+ Double_t sz = 0.F ;
+ Double_t sss = 0.F ;
+ Double_t ssz = 0.F ;
+ //
+ //find sum , sums ,sumz, sumss
+ //
+ Double_t dx, dy ;
+ Double_t radius = (Double_t)(fTrack->GetPt() / ( BFACT * bField ) ) ;
+
+ //TObjArray *hits = fTrack->GetHits();
+ //Int_t num_of_hits = fTrack->GetNumberOfPoints();
+
+ if ( fTrack->ComesFromMainVertex() == true )
+ {
+ dx = ((AliL3ConfMapPoint*)fTrack->firstHit)->GetX() - fVertex->GetX();
+ dy = ((AliL3ConfMapPoint*)fTrack->firstHit)->GetY() - fVertex->GetY() ;
+ }
+ else
+ {
+ dx = ((AliL3ConfMapPoint *)fTrack->firstHit)->GetX() - ((AliL3ConfMapPoint *)fTrack->lastHit)->GetX() ;
+ dy = ((AliL3ConfMapPoint *)fTrack->firstHit)->GetY() - ((AliL3ConfMapPoint *)fTrack->lastHit)->GetY() ;
+ //dx = ((AliL3ConfMapPoint *)hits->First())->GetX() - ((AliL3ConfMapPoint *)hits->Last())->GetX() ;
+ //dy = ((AliL3ConfMapPoint *)hits->First())->GetY() - ((AliL3ConfMapPoint *)hits->Last())->GetY() ;
+ }
+
+ Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
+ Double_t total_s ;
+
+ if ( fabs(localPsi) < 1. )
+ {
+ total_s = 2.0 * radius * asin ( localPsi ) ;
+ }
+ else
+ {
+ total_s = 2.0 * radius * pi ;
+ }
+
+ AliL3ConfMapPoint *previousHit = NULL;
+
+ // FtfBaseHit *previousHit = 0 ;
+
+ //for ( startLoop() ; done() ; nextHit() ) {
+ Double_t dpsi,s;
+
+ // for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ // AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)hits->At(hit_counter);
+ AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)fTrack->currentHit;
+ // if ( currentHit != firstHit )
+ if(cHit != fTrack->firstHit)// hits->First())
+ {
+ dx = cHit->GetX() - previousHit->GetX() ;
+ dy = cHit->GetY() - previousHit->GetY() ;
+ dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
+ fTrack->SetPsierr(dpsi);
+ s = previousHit->GetS() - 2.0 * radius * (Double_t)asin ( dpsi ) ;
+ cHit->SetS(s);
+ }
+ else
+ cHit->SetS(total_s);
+ // cHit->s = total_s ;
+
+ sum += cHit->GetZWeight() ;
+ ss += cHit->GetZWeight() * cHit->GetS() ;
+ sz += cHit->GetZWeight() * cHit->GetZ() ;
+ sss += cHit->GetZWeight() * cHit->GetS() * cHit->GetS() ;
+ ssz += cHit->GetZWeight() * cHit->GetS() * cHit->GetZ() ;
+ previousHit = cHit ;
+ }
+
+ Double_t chi2,det = sum * sss - ss * ss;
+ if ( fabs(det) < 1e-20)
+ {
+ chi2 = 99999.F ;
+ fTrack->SetChiSq2(chi2);
+ return 0 ;
+ }
+
+ //Compute the best fitted parameters A,B
+ Double_t tanl,z0,dtanl,dz0;
+
+ tanl = (Double_t)((sum * ssz - ss * sz ) / det );
+ z0 = (Double_t)((sz * sss - ssz * ss ) / det );
+
+ fTrack->SetTgl(tanl);
+ fTrack->SetZ0(z0);
+
+ // calculate chi-square
+
+ chi2 = 0.;
+ Double_t r1 ;
+
+ //for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)hits->At(hit_counter);
+ AliL3ConfMapPoint *cHit = (AliL3ConfMapPoint*)fTrack->currentHit;
+ r1 = cHit->GetZ() - tanl * cHit->GetS() - z0 ;
+ chi2 += (Double_t) ( (Double_t)cHit->GetZWeight() * (r1 * r1) );
+ }
+ fTrack->SetChiSq2(chi2);
+ //
+ // calculate estimated variance
+ // varsq=chi/(double(n)-2.)
+ // calculate covariance matrix
+ // siga=sqrt(varsq*sxx/det)
+ // sigb=sqrt(varsq*sum/det)
+ //
+ dtanl = (Double_t) ( sum / det );
+ dz0 = (Double_t) ( sss / det );
+
+ fTrack->SetTglerr(dtanl);
+ fTrack->SetZ0err(dz0);
+
+ return 0 ;
+}
--- /dev/null
+#ifndef ALIL3_ConfMapFit
+#define ALIL3_ConfMapFit
+
+#include "AliL3RootTypes.h"
+
+class AliL3ConfMapTrack;
+class AliL3Vertex;
+
+class AliL3ConfMapFit {
+
+ private:
+ AliL3ConfMapTrack *fTrack; //!
+ AliL3Vertex *fVertex; //!
+ Double_t BFACT;
+ Double_t bField;
+
+ static Double_t pi;
+
+ public:
+ AliL3ConfMapFit (AliL3ConfMapTrack *track,AliL3Vertex *vertex);
+ virtual ~AliL3ConfMapFit() {};
+
+ Int_t FitHelix();
+ Int_t FitCircle();
+ Int_t FitLine();
+
+ ClassDef(AliL3ConfMapFit,1) //Conformal mapping fit class
+};
+
+#endif
--- /dev/null
+//Author: Anders Strand Vestbo
+
+//________________________________
+// AliL3ConfMapPoint
+//
+// Hit class for conformal mapper
+
+#include <iostream.h>
+#include <math.h>
+#include "AliL3Logging.h"
+
+#include "AliL3ConfMapPoint.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3Vertex.h"
+#include "AliL3ConfMapTrack.h"
+
+//ClassImp(AliL3ConfMapPoint)
+
+AliL3ConfMapPoint::AliL3ConfMapPoint()
+{
+ //Constructor
+
+ SetUsage(false);
+ SetHitNumber(-1);
+ SetX(0);
+ SetY(0);
+ SetZ(0);
+ SetXerr(0);
+ SetYerr(0);
+ SetZerr(0);
+
+ SetPhi(0.);
+ SetEta(0.);
+
+ SetXprime(0.);
+ SetYprime(0.);
+ SetXprimeerr(0.);
+ SetYprimeerr(0.);
+ SetIntPoint(0., 0., 0., 0., 0., 0.);
+ SetShiftedCoord();
+ SetMCTrackID(0.,0.,0.);
+}
+
+AliL3ConfMapPoint::~AliL3ConfMapPoint()
+{
+ // Destructor.
+ // Does nothing except destruct.
+}
+
+Bool_t AliL3ConfMapPoint::ReadHits(AliL3SpacePointData* hits ){
+ SetHitNumber(hits->fID);
+ SetPadRow(hits->fPadRow);
+ Int_t slice = (hits->fID>>25) & 0x7f;
+ SetSector(slice);
+ SetX(hits->fX);
+ SetY(hits->fY);
+ SetZ(hits->fZ);
+ SetXerr(sqrt(hits->fXYErr));
+ SetYerr(sqrt(hits->fXYErr));
+ SetZerr(sqrt(hits->fZErr));
+ return kTRUE;
+}
+
+void AliL3ConfMapPoint::Setup(AliL3Vertex *vertex)
+{
+ //Setup. Sets the vertex, conformal coordinates, and phi and eta of each hit.
+
+ SetIntPoint(vertex->GetX(), vertex->GetY(), vertex->GetZ(),
+ vertex->GetXErr(), vertex->GetYErr(), vertex->GetZErr());
+ SetShiftedCoord();
+ SetConfCoord();
+ // The angles are set properly if they are set after the interaction point and the shifted coordinates
+ SetAngles();
+ //SetDist(0., 0.);
+
+ return;
+}
+
+void AliL3ConfMapPoint::SetIntPoint(const Double_t in_x,const Double_t in_y,
+ const Double_t in_z,
+ const Double_t in_x_err, const Double_t in_y_err,
+ const Double_t in_z_err)
+{
+ // Defines a new interaction point. This point is needed to calculate
+ // the conformal coordinates.
+
+ SetXt(in_x);
+ SetYt(in_y);
+ SetZt(in_z);
+ SetXterr(in_x_err);
+ SetYterr(in_y_err);
+ SetZterr(in_z_err);
+
+ return;
+}
+
+void AliL3ConfMapPoint::SetAllCoord(const AliL3ConfMapPoint *preceding_hit)
+{
+ // Sets the interaction point, the shifted coordinates, and the conformal mapping coordinates.
+ // These values are calculated from the interaction point of the given cluster which should be a
+ // already found cluster on the same track.
+
+ if (this == preceding_hit) {
+ SetIntPoint(preceding_hit->GetX(), preceding_hit->GetY(), preceding_hit->GetZ(),
+ preceding_hit->GetXerr(), preceding_hit->GetYerr(), preceding_hit->GetZerr());
+ }
+
+ else {
+ SetIntPoint(preceding_hit->GetXt(), preceding_hit->GetYt(), preceding_hit->GetZt(),
+ preceding_hit->GetXterr(), preceding_hit->GetYterr(), preceding_hit->GetZterr());
+ }
+
+ SetShiftedCoord();
+ SetConfCoord();
+
+ return;
+}
+
+void AliL3ConfMapPoint::SetShiftedCoord()
+{
+ // Sets the coordinates with resepct to the given vertex point
+
+ SetXv(GetX() - fXt);
+ SetYv(GetY() - fYt);
+ SetZv(GetZ() - fZt);
+ /*
+ SetXverr(TMath::Sqrt(GetXerr()*GetXerr() + fXterr*fXterr));
+ SetYverr(TMath::Sqrt(GetYerr()*GetYerr() + fYterr*fYterr));
+ SetZverr(TMath::Sqrt(GetZerr()*GetZerr() + fZterr*fZterr));
+ */
+ return;
+}
+
+void AliL3ConfMapPoint::SetConfCoord()
+{
+ // Calculates the conformal coordinates of one cluster.
+ // If the option "vertex_constraint" applies the interaction point is
+ // assumed to be at (0, 0, 0). Otherwise the function will use the
+ // interaction point specified by fXt and fYt.
+
+ Double_t r2;
+ Double_t xyErrorScale = 1;
+ Double_t szErrorScale = 1;
+
+ if ((r2 = fXv*fXv + fYv*fYv))
+ {
+ fXprime = fXv / r2;
+ fYprime = -fYv / r2;
+ // fXprimeerr = TMath::Sqrt(TMath::Power((-fXv * fXv + fYv*fYv) * fXverr, 2) + TMath::Power( 2*fXv*fYv*fYverr, 2)) / TMath::Power(fXv*fXv + fYv*fYv, 2);
+ // fXprimeerr = TMath::Sqrt(TMath::Power((-fXv * fXv - 3*fYv*fYv) * fYverr, 2) + TMath::Power(-2*fXv*fYv*fXverr, 2)) / TMath::Power(fXv*fXv + fYv*fYv, 2);
+
+
+ //set weights:
+ //fWxy = r2*r2 / (TMath::Power(xyErrorScale,2)*(TMath::Power(xerr,2)+TMath::Power(yerr,2)));
+ fWxy = r2*r2 / ((xyErrorScale*xyErrorScale)*((xerr*xerr)+(yerr*yerr)));
+ s = 0; //track trajectory
+ //fWz = (Double_t)(1./TMath::Power(szErrorScale*zerr,2));
+ fWz = (Double_t)(1./(szErrorScale*zerr*zerr));
+ }
+
+ else {
+ fXprime = 0.;
+ fYprime = 0.;
+ fXprimeerr = 0.;
+ fYprimeerr = 0.;
+ fWxy = 0;
+ fWz = 0;
+ s = 0;
+ }
+
+ return;
+}
+
+void AliL3ConfMapPoint::SetAngles()
+{
+ // Calculates the angle phi and the pseudorapidity eta for each cluster.
+ /*
+ Double_t r = TMath::Sqrt(x*x + y*y);
+
+ fPhi = TMath::ATan2(y,x);
+ if(fPhi<0) fPhi = fPhi + 2*TMath::Pi();
+ fEta = 3.*z/(TMath::Abs(z)+2.*r);
+ return;
+ */
+ // Double_t r3dim = TMath::Sqrt(fXv*fXv + fYv*fYv + fZv*fZv);
+ Double_t r3dim = sqrt(fXv*fXv + fYv*fYv + fZv*fZv);
+ //Double_t r2dim = TMath::Sqrt(fXv*fXv + fYv*fYv);
+
+ /*if (r2dim == 0.) {
+ // If r2dim == 0 the pseudorapidity eta cannot be calculated (division by zero)!
+ // This can only happen if the point is lying on the z-axis and this should never be possible.
+ cerr << "The pseudorapidity eta cannot be calculated (division by zero)! Set to 1.e-10." << endl;
+ r2dim = 1.e-10;
+ }
+
+ if (fXv == 0.) {
+ fPhi = (fYv > 0.) ? TMath::Pi() / 2. : - TMath::Pi() / 2.;
+ }
+
+ else {
+ fPhi = (fXv > 0.) ? TMath::ASin(fYv/r2dim) : TMath::Pi() - TMath::ASin(fYv/r2dim);
+ }
+
+ if (fPhi < 0.) {
+ fPhi += 2. * TMath::Pi();
+ }
+ */
+ //fPhi = TMath::ATan2(y,x);
+ fPhi = atan2(y,x);
+ //if(fPhi<0) fPhi = fPhi + 2*TMath::Pi();
+
+ //fEta = 0.5 * TMath::Log((r3dim + fZv)/(r3dim - fZv));
+ fEta = 0.5 * log((r3dim + fZv)/(r3dim - fZv));
+ return;
+}
+/*
+AliL3ConfMapTrack *AliL3ConfMapPoint::GetTrack(TClonesArray *tracks) const
+{
+ // Returns the pointer to the track to which this hit belongs.
+
+ return (AliL3ConfMapTrack*)tracks->At(this->GetTrackNumber());
+}
+*/
--- /dev/null
+#ifndef ALIL3_ConfMapPoint
+#define ALIL3_ConfMapPoint
+
+#include "AliL3RootTypes.h"
+
+class AliL3SpacePointData;
+class AliL3ConfMapTrack;
+class AliL3Vertex;
+
+class AliL3ConfMapPoint {
+
+ private:
+
+ Int_t fHitNumber;
+ Int_t fTrackNumber;
+ Int_t fNextHitNumber;
+ Bool_t fUsed;
+
+ Int_t fPadrow;
+ Int_t fSector;
+
+ //global coordinates and their errors
+ Double_t x;
+ Double_t y;
+ Double_t z;
+ Double_t xerr;
+ Double_t yerr;
+ Double_t zerr;
+
+ Double_t fWxy; // x-y weight on x-y
+ Double_t fWz; // z weight on z
+ Float_t s; //track trajectory
+
+ // Interaction point
+ Double_t fXt; // x-value of the interaction point
+ Double_t fYt; // y-value of the interaction point
+ Double_t fZt; // z-value of the interaction point
+
+ Double_t fXterr; // error of mXt
+ Double_t fYterr; // error of mYt
+ Double_t fZterr; // error of mZt
+
+ // conformal mapping coordinates
+ Double_t fXprime; // transformed x
+ Double_t fYprime; // transformed y
+
+ Double_t fXprimeerr; // error of mXprime
+ Double_t fYprimeerr; // error of mYprime
+
+ // coordinates with respect to the vertex
+
+ // cartesian coordinates
+ Double_t fXv; // x with respect to vertex
+ Double_t fYv; // y with respect to vertex
+ Double_t fZv; // z with respect to vertex
+
+ Double_t fXverr; // error of mXv
+ Double_t fYverr; // error of mYv
+ Double_t fZverr; // error of mZv
+
+ // spherical coordinates
+ Double_t fPhi; // angle phi
+ Double_t fEta; // pseudorapidity
+
+
+ public:
+
+ AliL3ConfMapPoint();
+ virtual ~AliL3ConfMapPoint();
+
+ Bool_t ReadHits(AliL3SpacePointData* hits ); //!
+
+ AliL3ConfMapPoint *nextVolumeHit; //!
+ AliL3ConfMapPoint *nextRowHit; //!
+
+ AliL3ConfMapPoint *nextTrackHit; //! Linked chain of points in a track
+ Short_t phiIndex;
+ Short_t etaIndex;
+
+ Double_t xyChi2;
+ Double_t szChi2;
+ Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+ // getter
+ Double_t GetX() const {return x;}
+ Double_t GetY() const {return y;}
+ Double_t GetZ() const {return z;}
+ Double_t GetXerr() const {return xerr;}
+ Double_t GetYerr() const {return yerr;}
+ Double_t GetZerr() const {return zerr;}
+ Int_t GetPadRow() const {return fPadrow;}
+ Int_t GetSector() const {return fSector;}
+
+ Double_t GetXYWeight() const {return fWxy;}
+ Double_t GetZWeight() const {return fWz;}
+ Float_t GetS() const {return s;}
+
+ //AliL3ConfMapTrack *GetTrack(TClonesArray *tracks) const;
+
+ Bool_t GetUsage() const {return fUsed;}
+ Double_t GetPhi() const { return fPhi; }
+ Double_t GetEta() const { return fEta; }
+
+ Double_t GetXprime() const { return fXprime; }
+ Double_t GetYprime() const { return fYprime; }
+ Double_t GetXprimeerr() const { return fXprimeerr; }
+ Double_t GetYprimeerr() const { return fYprimeerr; }
+
+ Double_t GetXt() const { return fXt; }
+ Double_t GetYt() const { return fYt; }
+ Double_t GetZt() const { return fZt; }
+ Double_t GetXterr() const { return fXterr; }
+ Double_t GetYterr() const { return fYterr; }
+ Double_t GetZterr() const { return fZterr; }
+
+ Double_t GetXv() const { return fXv; }
+ Double_t GetYv() const { return fYv; }
+ Double_t GetZv() const { return fZv; }
+ Double_t GetXverr() const { return fXverr; }
+ Double_t GetYverr() const { return fYverr; }
+ Double_t GetZverr() const { return fZverr; }
+
+ Int_t GetHitNumber() const {return fHitNumber;}
+ Int_t GetNextHitNumber() const {return fNextHitNumber;}
+ Int_t GetTrackNumber() const {return fTrackNumber;}
+ // Int_t const *GetMCTrackID() const {return fMCTrackID;}
+
+ // setter
+ void SetX(Double_t f) {x=f;}
+ void SetY(Double_t f) {y=f;}
+ void SetZ(Double_t f) {z=f;}
+ void SetXerr(Double_t f) {xerr=f;}
+ void SetYerr(Double_t f) {yerr=f;}
+ void SetZerr(Double_t f) {zerr=f;}
+ void SetPadRow(Int_t f) {fPadrow=f;}
+ void SetSector(Int_t f) {fSector=f;}
+ void SetMCTrackID(Int_t f,Int_t g,Int_t h) {fMCTrackID[0] = f; fMCTrackID[1]=g; fMCTrackID[2]=h;}
+
+ void SetXYWeight(Float_t f) {fWxy = f;}
+ void SetZWeight(Float_t f) {fWz = f;}
+ void SetS(Float_t f) {s = f;}
+
+ void SetUsage(Bool_t f) {fUsed=f;}
+
+ void SetPhi(Double_t f) { fPhi = f; }
+ void SetEta(Double_t f) { fEta = f; }
+
+ void SetXprime(Double_t f) { fXprime = f; }
+ void SetYprime(Double_t f) { fYprime = f; }
+ void SetXprimeerr(Double_t f) { fXprimeerr = f; }
+ void SetYprimeerr(Double_t f) { fYprimeerr = f; }
+
+ void SetXt(Double_t f) { fXt = f; }
+ void SetYt(Double_t f) { fYt = f; }
+ void SetZt(Double_t f) { fZt = f; }
+ void SetXterr(Double_t f) { fXterr = f; }
+ void SetYterr(Double_t f) { fYterr = f; }
+ void SetZterr(Double_t f) { fZterr = f; }
+
+ void SetXv(Double_t f) { fXv = f; }
+ void SetYv(Double_t f) { fYv = f; }
+ void SetZv(Double_t f) { fZv = f; }
+ void SetXverr(Double_t f) { fXverr = f; }
+ void SetYverr(Double_t f) { fYverr = f; }
+ void SetZverr(Double_t f) { fZverr = f; }
+
+ void SetHitNumber(Int_t f) {fHitNumber=f;}
+ void SetTrackNumber(Int_t f) {fTrackNumber=f;}
+ void SetNextHitNumber(Int_t f) {fNextHitNumber=f;}
+
+ void Setup(AliL3Vertex *vertex);// does the usual setup in the right order
+ void SetAngles();// calculate spherical angles and set values
+ void SetIntPoint(const Double_t in_x = 0.,const Double_t in_y = 0.,
+ const Double_t in_z = 0.,const Double_t in_x_err = 0.,
+ const Double_t in_y_err = 0., const Double_t in_z_err = 0.);
+ //-> set interaction point
+ void SetShiftedCoord();// set shifted coordinates
+ void SetAllCoord(const AliL3ConfMapPoint *hit);// set conformal mapping coordinates in respect to given hit
+ void SetConfCoord();// conformal mapping
+
+// ClassDef(AliL3ConfMapPoint, 1) //Conformal mapping hit class.
+};
+
+#endif
--- /dev/null
+
+//Author: Anders Strand Vestbo
+//Author: Uli Frankenfeld
+//Last Modified: 13.12.2000
+
+//____________________________________
+// AliL3ConfMapTrack
+//
+// Track class for conformal mapper
+
+#include "AliL3RootTypes.h"
+#include "AliL3Logging.h"
+#include "AliL3Vertex.h"
+#include "AliL3ConfMapPoint.h"
+#include "AliL3ConfMapFit.h"
+#include "AliL3ConfMapTrack.h"
+#include <math.h>
+
+ClassImp(AliL3ConfMapTrack)
+
+
+AliL3ConfMapTrack::AliL3ConfMapTrack()
+{
+ //Constructor
+
+ fChiSq[0] = 0.;
+ fChiSq[1] = 0.;
+
+}
+
+AliL3ConfMapTrack::~AliL3ConfMapTrack()
+{
+
+}
+
+void AliL3ConfMapTrack::DeleteCandidate()
+{
+ //Deletes this track by resetting all its parameters. Does not delete
+ //the object itself.
+
+ AliL3ConfMapPoint *curHit = (AliL3ConfMapPoint*)firstHit;
+ AliL3ConfMapPoint *nextHit;
+
+ while(curHit != 0)
+ {
+ nextHit = (AliL3ConfMapPoint*)curHit->nextTrackHit;
+ curHit->nextTrackHit = 0;
+ curHit = nextHit;
+ }
+
+ UInt_t *hit_numbers = GetHitNumbers();
+ for(Int_t i=0; i<GetNHits(); i++)
+ {
+ //fHitNumbers[i] = 0;
+ hit_numbers[i]=0;
+ }
+
+ SetRadius(0.);
+ SetCenterX(0.);
+ SetCenterY(0.);
+
+ ComesFromMainVertex(false);
+
+ SetNHits(0);
+ SetCharge(0);
+ fChiSq[0] = 0.;
+ fChiSq[1] = 0.;
+}
+
+
+void AliL3ConfMapTrack::SetProperties(Bool_t usage)
+{
+ //Set the hits to this track to 'usage'
+
+ for(StartLoop(); LoopDone(); GetNextHit())
+ {
+ AliL3ConfMapPoint *p = (AliL3ConfMapPoint*)currentHit;
+ p->SetUsage(usage);
+ }
+ return;
+}
+
+void AliL3ConfMapTrack::Reset()
+{
+ //Resets the fit parameters of this track.
+
+ //xy-plane
+ s11Xy = 0;
+ s12Xy = 0;
+ s22Xy = 0;
+ g1Xy = 0;
+ g2Xy = 0;
+ fChiSq[0] = 0.;
+
+ //sz-plane
+ s11Sz = 0;
+ s12Sz = 0;
+ s22Sz = 0;
+ g1Sz = 0;
+ g2Sz = 0;
+ fChiSq[1] = 0;
+ SetLength(0);
+
+
+}
+
+void AliL3ConfMapTrack::UpdateParam(AliL3ConfMapPoint *thisHit)
+{
+ //Function to update fit parameters of track
+ //Also, it updates the hit pointers.
+
+
+ //Increment the number of hits assigned to this track:
+
+ //fNHits++;
+ Int_t nhits = GetNHits();
+ nhits++;
+ SetNHits(nhits); //SetNHits(nhits++);
+
+ //Set the hit pointers:
+ //if(fNHits == 1)
+ if(GetNHits()==1)
+ firstHit = thisHit;
+ else
+ ((AliL3ConfMapPoint*)lastHit)->nextTrackHit = thisHit;
+ lastHit = thisHit;
+
+
+ s11Xy = s11Xy + thisHit->GetXYWeight() ;
+ s12Xy = s12Xy + thisHit->GetXYWeight() * thisHit->GetXprime() ;
+ s22Xy = s22Xy + thisHit->GetXYWeight() * pow((thisHit->GetXprime()),2) ;
+ g1Xy = g1Xy + thisHit->GetXYWeight() * thisHit->GetYprime() ;
+ g2Xy = g2Xy + thisHit->GetXYWeight() * thisHit->GetXprime() * thisHit->GetYprime() ;
+
+ ddXy = s11Xy * s22Xy - pow((s12Xy),2) ;
+ if ( ddXy != 0 )
+ {
+ a1Xy = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
+ a2Xy = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
+ }
+
+ // Now in the sz plane
+ s11Sz = s11Sz + thisHit->GetZWeight() ;
+ s12Sz = s12Sz + thisHit->GetZWeight() * thisHit->GetS() ;
+ s22Sz = s22Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetS() ;
+ g1Sz = g1Sz + thisHit->GetZWeight() * thisHit->GetZ() ;
+ g2Sz = g2Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetZ() ;
+
+
+ ddSz = s11Sz * s22Sz - s12Sz * s12Sz ;
+ if ( ddSz != 0 ) {
+ a1Sz = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
+ a2Sz = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
+ }
+
+}
+
+
+void AliL3ConfMapTrack::Fill(AliL3Vertex *vertex,Double_t max_Dca)
+{
+ //Fill track variables with or without fit.
+
+ //fRadius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
+ Double_t radius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
+ SetRadius(radius);
+
+ //fPt = (Double_t)(BFACT * bField * fRadius);
+ Double_t pt = (Double_t)(BFACT * bField * GetRadius());
+ SetPt(pt);
+
+ if(GetPt() > max_Dca) //go for fit of helix in real space
+ {
+ AliL3ConfMapFit *fit = new AliL3ConfMapFit(this,vertex);
+ fit->FitHelix();
+ UpdateToFirstPoint();
+
+ delete fit;
+ }
+ else if(GetPt() == 0)
+ LOG(AliL3Log::kError,"AliL3ConfMapTrack::Fill","Tracks")<<AliL3Log::kDec<<
+ "Found track with Pt=0!!!"<<ENDLOG;
+ else
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapTrack::Fill","Tracks")<<AliL3Log::kDec<<
+ "Track with pt<max_Dca :"<<GetPt()<<ENDLOG;
+ }
+
+}
+
+void AliL3ConfMapTrack::UpdateToFirstPoint()
+{
+ //Update track parameters to the innermost point on the track.
+ //Basically it justs calculates the intersection of the track, and a cylinder
+ //with radius = r(innermost point). Then the parameters are updated to this point.
+ //Should be called after the helixfit (in FillTracks).
+
+ //AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)fPoints->Last();
+ AliL3ConfMapPoint *lHit = (AliL3ConfMapPoint*)lastHit;
+ Double_t radius = sqrt(lHit->GetX()*lHit->GetX()+lHit->GetY()*lHit->GetY());
+
+ //Get the track parameters
+
+ Double_t tPhi0 = GetPsi() + GetCharge() * 0.5 * pi / fabs(GetCharge()) ;
+ Double_t x0 = GetR0() * cos(GetPhi0()) ;
+ Double_t y0 = GetR0() * sin(GetPhi0()) ;
+ Double_t rc = fabs(GetPt()) / ( BFACT * bField ) ;
+ Double_t xc = x0 - rc * cos(tPhi0) ;
+ Double_t yc = y0 - rc * sin(tPhi0) ;
+
+ //Check helix and cylinder intersect
+
+ Double_t fac1 = xc*xc + yc*yc ;
+ Double_t sfac = sqrt( fac1 ) ;
+
+ if ( fabs(sfac-rc) > radius || fabs(sfac+rc) < radius ) {
+ LOG(AliL3Log::kError,"AliL3ConfMapTrack::UpdateToLastPoint","Tracks")<<AliL3Log::kDec<<
+ "Track does not intersect"<<ENDLOG;
+ return;
+ }
+
+ //Find intersection
+
+ Double_t fac2 = ( radius*radius + fac1 - rc*rc) / (2.00 * radius * sfac ) ;
+ Double_t phi = atan2(yc,xc) + GetCharge()*acos(fac2) ;
+ Double_t td = atan2(radius*sin(phi) - yc,radius*cos(phi) - xc) ;
+
+ //Intersection in z
+
+ if ( td < 0 ) td = td + 2. * pi ;
+ Double_t deltat = fmod((-GetCharge()*td + GetCharge()*tPhi0),2*pi) ;
+ if ( deltat < 0. ) deltat += 2. * pi ;
+ if ( deltat > 2.*pi ) deltat -= 2. * pi ;
+ Double_t z = GetZ0() + rc * GetTgl() * deltat ;
+
+
+ Double_t xExtra = radius * cos(phi) ;
+ Double_t yExtra = radius * sin(phi) ;
+
+ Double_t tPhi = atan2(yExtra-yc,xExtra-xc);
+
+ //if ( tPhi < 0 ) tPhi += 2. * M_PI ;
+
+ Double_t tPsi = tPhi - GetCharge() * 0.5 * pi / fabs(GetCharge()) ;
+ if ( tPsi > 2. * pi ) tPsi -= 2. * pi ;
+ if ( tPsi < 0. ) tPsi += 2. * pi ;
+
+ //And finally, update the track parameters
+
+ SetCenterX(xc);
+ SetCenterY(yc);
+ SetR0(radius);
+ SetPhi0(phi);
+ SetZ0(z);
+ SetPsi(tPsi);
+}
+
+Int_t AliL3ConfMapTrack::GetMCLabel()
+{
+ //For evaluation study.
+ //Returns the MCtrackID of the belonging clusters.
+ //If MCLabel < 0, means that track is fake.
+
+ return 0;
+ /*
+ Int_t num_of_clusters = GetNumberOfPoints();
+ S *s=new S[num_of_clusters];
+ Int_t i;
+ for (i=0; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
+
+ Int_t lab=123456789;
+ for (i=0; i<num_of_clusters; i++) {
+ AliL3ConfMapPoint *c=(AliL3ConfMapPoint*)fPoints->UncheckedAt(i);
+ lab=fabs(c->fMCTrackID[0]);
+ Int_t j;
+ for (j=0; j<num_of_clusters; j++)
+ if (s[j].lab==lab || s[j].max==0) break;
+ s[j].lab=lab;
+ s[j].max++;
+ }
+
+ Int_t max=0;
+ for (i=0; i<num_of_clusters; i++)
+ if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
+
+ delete[] s;
+
+ for (i=0; i<num_of_clusters; i++) {
+ AliL3ConfMapPoint *c=(AliL3ConfMapPoint*)fPoints->UncheckedAt(i);
+ if (fabs(c->fMCTrackID[1]) == lab ||
+ fabs(c->fMCTrackID[2]) == lab ) max++;
+ }
+
+ //check if more than 10% of the clusters are incorrectly assigned (fake track):
+
+ if (1.-Float_t(max)/num_of_clusters > 0.10)
+ {
+ return -lab;
+ }
+ Int_t tail=Int_t(0.08*174);
+ if (num_of_clusters < tail) return lab;
+
+ max=0;
+ for (i=1; i<=tail; i++) {
+ AliL3ConfMapPoint *c = (AliL3ConfMapPoint*)fPoints->UncheckedAt(num_of_clusters-i);
+ if (lab == fabs(c->fMCTrackID[0]) ||
+ lab == fabs(c->fMCTrackID[1]) ||
+ lab == fabs(c->fMCTrackID[2])) max++;
+ }
+ if (max < Int_t(0.5*tail))
+ {
+ //printf("Wrong innermost clusters\n");
+ return -lab;
+ }
+ return lab;
+ */
+}
+
--- /dev/null
+#ifndef ALIL3_ConfMapTrack
+#define ALIL3_ConfMapTrack
+
+#include <string.h>
+
+#include "AliL3Track.h"
+
+#include "AliL3RootTypes.h"
+#include "AliL3ConfMapPoint.h"
+
+class AliL3Vertex;
+
+class AliL3ConfMapTrack :public AliL3Track {
+
+ private:
+
+
+ public:
+
+ AliL3ConfMapTrack();
+ virtual ~AliL3ConfMapTrack();
+ void Fill(AliL3Vertex *vertex,Double_t max_Dca);
+ void UpdateToFirstPoint();
+ void Reset();
+ void UpdateParam(AliL3ConfMapPoint *hit);
+ void DeleteCandidate();
+
+ void StartLoop() {currentHit = firstHit;} //!
+ void GetNextHit() {currentHit = ((AliL3ConfMapPoint*)currentHit)->nextTrackHit;} //!
+ Int_t LoopDone() {return currentHit != 0;} //!
+ AliL3ConfMapPoint *currentHit; //!
+ AliL3ConfMapPoint *lastHit; //!
+ AliL3ConfMapPoint *firstHit; //!
+
+
+ // getter
+ Double_t const *GetChiSq() const { return fChiSq;}
+ Int_t GetMCLabel();
+
+ // setter
+ void SetChiSq1(Double_t f) {fChiSq[0]=f;}
+ void SetChiSq2(Double_t f) {fChiSq[1]=f;}
+ void SetProperties(Bool_t fUsage);
+
+ Double_t fChiSq[2];
+
+ //fit parameters. Bad naming convention, i know...
+ Double_t s11Xy ;
+ Double_t s12Xy ;
+ Double_t s22Xy ;
+ Double_t g1Xy ;
+ Double_t g2Xy ;
+ Double_t s11Sz ;
+ Double_t s12Sz ;
+ Double_t s22Sz ;
+ Double_t g1Sz ;
+ Double_t g2Sz ;
+
+ Double_t ddXy, a1Xy, a2Xy ; /*fit par in xy */
+ Double_t ddSz, a1Sz, a2Sz ; /*fit par in sz */
+
+ ClassDef(AliL3ConfMapTrack,1) //Conformal mapping track class
+};
+
+#endif
+
--- /dev/null
+
+//Author: Anders Strand Vestbo
+//Last Modified: 15.12.2000
+
+#include <iostream.h>
+#include <time.h>
+#include <math.h>
+#include "AliL3ConfMapper.h"
+
+#include "AliL3Logging.h"
+#include "AliL3Transform.h"
+#include "AliL3Vertex.h"
+#include "AliL3ConfMapTrack.h"
+#include "AliL3ConfMapPoint.h"
+#include "AliL3TrackArray.h"
+
+//
+//AliL3ConfMapper
+//
+//Conformal mapping base class
+
+ClassImp(AliL3ConfMapper)
+
+Double_t AliL3ConfMapper::pi=3.14159265358979323846;
+Double_t AliL3ConfMapper::twopi=2*pi;
+Double_t AliL3ConfMapper::todeg=180./pi;
+
+AliL3ConfMapper::AliL3ConfMapper()
+{
+ //Default constructor
+ fVertex = NULL;
+ fTrack = NULL;
+ fHit = NULL;
+ fHits = NULL;
+ fVolume = NULL;
+ fRow = NULL;
+ fBench = (Bool_t)true;
+ fParamSet = (Bool_t)false;
+ fVertexConstraint = (Bool_t)true;
+}
+
+
+AliL3ConfMapper::~AliL3ConfMapper()
+{
+ // Destructor.
+
+ if(fVolume) {
+ delete [] fVolume;
+ }
+ if(fRow) {
+ delete [] fRow;
+ }
+ if(fHits) {
+ delete [] (Byte_t *)fHits;
+ }
+ if(fHit) {
+ delete [] fHit;
+ }
+ if(fTrack) {
+ delete fTrack;
+ }
+
+}
+
+void AliL3ConfMapper::InitSector(Int_t sector,Int_t *rowrange,Float_t *etarange)
+{
+ //Initialize tracker for tracking in a given sector.
+ //Resets track and hit arrays.
+ //Here it is also possible to specify a subsector, by defining
+ //rowrange[0]=innermost row;
+ //rowrange[1]=outermostrow;
+ //Finally you can specify etaslices to save time (assuming a good seed from TRD...)
+
+ if(fHit)
+ {
+ delete [] fHit;
+ }
+
+ if(fHits) {
+ delete [] (Byte_t *)fHits;
+ }
+
+ if(fTrack)
+ {
+ delete fTrack;
+ }
+
+ //Define tracking area:
+ if(rowrange)
+ {
+ fRowMin = rowrange[0];
+ fRowMax = rowrange[1];
+ }
+ else //complete sector
+ {
+ fRowMin = 0;
+ fRowMax = 173;
+ }
+ if(etarange)
+ {
+ fEtaMin = etarange[0];
+ fEtaMax = etarange[1];
+ }
+ else
+ {
+ fEtaMin = 0;
+ fEtaMax = sector < 18 ? 0.9 : -0.9;
+ }
+
+ //Set the angles to sector 2:
+ fPhiMin = -1.*10/todeg;//fParam->GetAngle(sector) - 10/todeg;
+ fPhiMax = 10/todeg;//fParam->GetAngle(sector) + 10/todeg;
+
+ //rotation angles for sector 2:
+ //cos: 0.766044 sin: 0.642788
+
+ Int_t max_num_of_tracks = 3000;
+ Int_t max_num_of_hits = 90000;
+// Int_t max_num_of_hits = 20000;
+// Int_t max_num_of_tracks = 2000;
+
+ fHits= (AliL3ConfMapPoint **) new Byte_t[sizeof(AliL3ConfMapPoint *)*max_num_of_hits];
+ fHit = new AliL3ConfMapPoint[max_num_of_hits];
+ for(Int_t i=0;i<max_num_of_hits;i++){
+ fHits[i]=&(fHit[i]);
+ }
+ fTrack = new AliL3TrackArray("AliL3ConfMapTrack",max_num_of_tracks);
+
+ nTracks=0;
+ fClustersUnused = 0;
+
+ fNumRowSegment = fRowMax - fRowMin; //number of rows to be considered by tracker
+
+}
+
+
+
+Bool_t AliL3ConfMapper::ReadHits(UInt_t count, AliL3SpacePointData* hits )
+{
+ AliL3ConfMapPoint *thisHit = &(fHit[0]);
+ Int_t nhit=(Int_t)count;
+ for (Int_t i=0;i<nhit;i++){
+
+// AliL3ConfMapPoint *thisHit = &(fHit[i]);
+// AliL3ConfMapPoint *thisHit = fHits[i];
+ Int_t slice = (hits[i].fID>>25) & 0x7f;
+ thisHit->SetHitNumber(hits[i].fID);
+ thisHit->SetPadRow(hits[i].fPadRow);
+ thisHit->SetSector(slice);
+ thisHit->SetX(hits[i].fX);
+ thisHit->SetY(hits[i].fY);
+ thisHit->SetZ(hits[i].fZ);
+ thisHit->SetXerr(sqrt(hits[i].fXYErr));
+ thisHit->SetYerr(sqrt(hits[i].fXYErr));
+ thisHit->SetZerr(sqrt(hits[i].fZErr));
+// thisHit->SetXerr(3.16227766016837941e-01);
+// thisHit->SetYerr(3.16227766016837941e-01);
+// thisHit->SetZerr(4.47213595499957928e-01);
+ thisHit++;
+
+// fHits[i]->ReadHits(&(hits[i]));
+// thisHit->ReadHits(&(hits[i]));
+// thisHit++;
+ }
+ fClustersUnused += nhit;
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::ReadHits","#hits")<<AliL3Log::kDec
+ <<"hit_counter: "<<nhit<<" count: "<<count<<ENDLOG;
+
+ return true;
+}
+
+
+void AliL3ConfMapper::SetPointers()
+{
+ //Data organization.
+ //Allocate volumes, set conformal coordinates and pointers.
+ fNumRowSegmentPlusOne = 174;//fNumRowSegment+1;
+ fNumPhiSegmentPlusOne = fNumPhiSegment+1;
+ fNumEtaSegmentPlusOne = fNumEtaSegment+1;
+ fNumPhiEtaSegmentPlusOne = fNumPhiSegmentPlusOne*fNumEtaSegmentPlusOne;
+ fBounds = fNumRowSegmentPlusOne * fNumPhiSegmentPlusOne * fNumEtaSegmentPlusOne;
+
+ //Allocate volumes:
+ if(fVolume) delete [] fVolume;
+ if(fRow) delete [] fRow;
+
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::SetPointers","Memory")<<AliL3Log::kDec<<
+ "Allocating "<<fBounds*sizeof(AliL3ConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::SetPointers","Memory")<<AliL3Log::kDec<<
+ "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliL3ConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
+
+ fVolume = new AliL3ConfMapContainer[fBounds];
+ fRow = new AliL3ConfMapContainer[fNumRowSegmentPlusOne];
+
+ //set volumes to zero:
+ memset(fVolume,0,fBounds*sizeof(AliL3ConfMapContainer));
+ memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliL3ConfMapContainer));
+
+ Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
+ Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
+
+ Int_t volumeIndex;
+ for(Int_t j=0; j<fClustersUnused; j++)
+ {
+
+ //AliL3ConfMapPoint *thisHit = (AliL3ConfMapPoint*)fHit->At(j);
+// AliL3ConfMapPoint *thisHit = &(fHit[j]);
+ AliL3ConfMapPoint *thisHit = fHits[j];
+
+ thisHit->Setup(fVertex);
+
+ Int_t localrow = thisHit->GetPadRow();
+
+ //reset pointers:
+ thisHit->nextVolumeHit=thisHit->nextRowHit=0;
+
+ if(localrow < fRowMin || localrow > fRowMax)
+ continue;
+
+
+ //Get indexes:
+ thisHit->phiIndex=(Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1);
+
+ if(thisHit->phiIndex<1 || thisHit->phiIndex>fNumPhiSegment)
+ {
+ fPhiHitsOutOfRange++;
+ continue;
+ }
+
+ thisHit->etaIndex=(Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1);
+ if(thisHit->etaIndex<1 || thisHit->etaIndex>fNumEtaSegment)
+ {
+ fEtaHitsOutOfRange++;
+ continue;
+ }
+
+ //set volume pointers
+ volumeIndex = localrow*fNumPhiEtaSegmentPlusOne+thisHit->phiIndex*fNumEtaSegmentPlusOne+thisHit->etaIndex;
+ if(fVolume[volumeIndex].first == NULL)
+ fVolume[volumeIndex].first = (void *)thisHit;
+ else
+ ((AliL3ConfMapPoint *)fVolume[volumeIndex].last)->nextVolumeHit=thisHit;
+ fVolume[volumeIndex].last = (void *)thisHit;
+
+
+ //set row pointers
+ if(fRow[localrow].first == NULL)
+ fRow[localrow].first = (void *)thisHit;
+ else
+ ((AliL3ConfMapPoint *)(fRow[localrow].last))->nextRowHit = thisHit;
+ fRow[localrow].last = (void *)thisHit;
+
+ }
+
+}
+
+void AliL3ConfMapper::MainVertexTracking_a()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet)
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+
+ SetPointers();
+ SetVertexConstraint(true);
+}
+
+void AliL3ConfMapper::MainVertexTracking_b()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet)
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+ ClusterLoop();
+}
+
+void AliL3ConfMapper::MainVertexTracking()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet)
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapper::MainVertexTracking","Parameters")<<AliL3Log::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+ Double_t initCpuTime,cpuTime;
+ initCpuTime = CpuTime();
+
+ SetPointers();
+ SetVertexConstraint(true);
+
+ ClusterLoop();
+
+ cpuTime = CpuTime() - initCpuTime;
+ if(fBench)
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::MainVertexTracking","Timing")<<AliL3Log::kDec<<
+ "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+
+ return;
+}
+
+void AliL3ConfMapper::NonVertexTracking()
+{
+ //Tracking with no vertex constraint. This should be called after doing MainVertexTracking,
+ //in order to do tracking on the remaining clusters.
+ //The conformal mapping is now done with respect to the first cluster
+ //assosciated with this track.
+
+ SetVertexConstraint(false);
+ ClusterLoop();
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::NonVertexTracking","ntracks")<<AliL3Log::kDec<<
+ "Number of nonvertex tracks found: "<<nTracks-fMainVertexTracks<<ENDLOG;
+
+ return;
+}
+
+void AliL3ConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,
+ Double_t maxphi,Double_t maxeta)
+{
+ //Settings for main vertex tracking. The cuts are:
+ //TrackletLength: #hits on segment, before trying to build a track
+ //TrackLength: Minimum hits on a track
+ //RowScopeTracklet: Row search range for segments
+ //RowScopeTrack: Row search range for tracks
+
+ SetTrackletLength(trackletlength,(Bool_t)true);
+ SetRowScopeTracklet(rowscopetracklet, (Bool_t) true);
+ SetRowScopeTrack(rowscopetrack, (Bool_t) true);
+ SetMinPoints(tracklength,(Bool_t)true);
+ fMaxPhi=maxphi;
+ fMaxEta=maxeta;
+
+}
+
+void AliL3ConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack)
+{
+ SetTrackletLength(trackletlength,(Bool_t)false);
+ SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
+ SetRowScopeTrack(rowscopetrack, (Bool_t)false);
+ SetMinPoints(tracklength,(Bool_t)false);
+}
+
+void AliL3ConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Int_t trackChi2Cut,Int_t maxdist)
+{
+ //Settings for tracks. The cuts are:
+ //HitChi2Cut: Maximum hit chi2
+ //goodHitChi2: Chi2 to stop look for next hit
+ //trackChi2Cut: Maximum track chi2
+ //maxdist: Maximum distance between two clusters when forming segments
+
+ fHitChi2Cut = hitChi2Cut;
+ fGoodHitChi2 = goodHitChi2;
+ fTrackChi2Cut = trackChi2Cut;
+ fMaxDist = maxdist;
+}
+
+void AliL3ConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vertex_constraint)
+{
+ //Sets cuts of tracklets. Right now this is only:
+ //maxangle: Maximum angle when forming segments (if trackletlength > 2)
+
+ fGoodDist=goodDist;
+ SetMaxAngleTracklet(maxangle, vertex_constraint);
+}
+
+void AliL3ConfMapper::ClusterLoop()
+{
+ //Loop over hits, starting at outermost padrow, and trying to build segments.
+
+ Int_t row_segm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
+ AliL3ConfMapPoint *hit;
+
+ //Loop over rows, and try to create tracks from the hits.
+ //Starts at the outermost row, and loops as long as a track can be build, due to length.
+
+ for(row_segm = fRowMax; row_segm >= lastrow; row_segm--)
+ {
+ if(fRow[row_segm].first && ((AliL3ConfMapPoint*)fRow[row_segm].first)->GetPadRow() < fRowMin + 1)
+ break;
+ for(hit = (AliL3ConfMapPoint*)fRow[row_segm].first; hit!=0; hit=hit->nextRowHit)
+ {
+ if(hit->GetUsage() == true)
+ continue;
+ else
+ CreateTrack(hit);
+ }
+ }
+
+ return;
+}
+
+
+void AliL3ConfMapper::CreateTrack(AliL3ConfMapPoint *hit)
+{
+ //Tries to create a track from the initial hit given by ClusterLoop()
+
+ AliL3ConfMapPoint *closest_hit = NULL;
+ AliL3ConfMapTrack *track = NULL;
+
+ Int_t point;
+ Int_t tracks = nTracks;
+ nTracks++;
+
+ track = (AliL3ConfMapTrack*)fTrack->NextTrack();
+
+ //reset hit parameters:
+ track->Reset();
+
+ UInt_t *trackhitnumber = track->GetHitNumbers();
+
+ //set conformal coordinates if we are looking for non vertex tracks
+ if(!fVertexConstraint)
+ {
+ hit->SetAllCoord(hit);
+ }
+
+ //fill fit parameters of initial track:
+ track->UpdateParam(hit); //here the number of hits is incremented.
+ trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber();
+
+ Double_t dx,dy;
+ //create tracklets:
+
+ for(point=1; point<fTrackletLength[fVertexConstraint]; point++)
+ {
+ if((closest_hit = GetNextNeighbor(hit)))
+ {//closest hit exist
+
+ // Calculate track length in sz plane
+ dx = ((AliL3ConfMapPoint*)closest_hit)->GetX() - ((AliL3ConfMapPoint*)hit)->GetX();
+ dy = ((AliL3ConfMapPoint*)closest_hit)->GetY() - ((AliL3ConfMapPoint*)hit)->GetY();
+ //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ;
+ Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy );
+ track->SetLength(length);
+
+ //closest_hit->SetS(track->fLength);
+ closest_hit->SetS(track->GetLength());
+
+ //update fit parameters
+ track->UpdateParam(closest_hit);
+ trackhitnumber[track->GetNumberOfPoints()-1] = closest_hit->GetHitNumber();
+
+ hit = closest_hit;
+ }
+ else
+ {
+ //closest hit does not exist:
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ nTracks--;
+ point = fTrackletLength[fVertexConstraint];
+ }
+ }
+
+ //tracklet is long enough to be extended to a track
+ if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
+ {
+
+ track->SetProperties(true);
+
+ if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
+ {//proof if the first points seem to be a beginning of a track
+
+ track->SetProperties(false);
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ nTracks--;
+ }
+
+ else//good tracklet ->proceed, follow the trackfit
+ {
+ tracks++;
+
+ //define variables to keep the total chi:
+ Double_t xyChi2 = track->fChiSq[0];
+ Double_t szChi2 = track->fChiSq[1];
+
+ for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
+ {
+ track->fChiSq[0] = fHitChi2Cut;
+ closest_hit = GetNextNeighbor((AliL3ConfMapPoint*)track->lastHit,track);
+
+ if(closest_hit)
+ {
+
+ //keep total chi:
+ Double_t lxyChi2 = track->fChiSq[0]-track->fChiSq[1];
+ xyChi2 += lxyChi2;
+ closest_hit->xyChi2 = lxyChi2;
+
+ //update track length:
+ //track->fLength = closest_hit->GetS();
+ track->SetLength(closest_hit->GetS());
+ szChi2 += track->fChiSq[1];
+ closest_hit->szChi2 = track->fChiSq[1];
+
+ track->UpdateParam(closest_hit);
+ trackhitnumber[track->GetNumberOfPoints()-1] = closest_hit->GetHitNumber();
+
+ //add closest hit to track
+ closest_hit->SetUsage(true);
+ closest_hit->SetTrackNumber(tracks-1);
+
+ }//closest_hit
+
+ else
+ {
+ //closest hit does not exist
+ point = fNumRowSegment; //continue with next hit in segment
+ }//else
+
+ }//create tracks
+
+ //store track chi2:
+ track->fChiSq[0] = xyChi2;
+ track->fChiSq[1] = szChi2;
+ Double_t normalized_chi2 = (track->fChiSq[0]+track->fChiSq[1])/track->GetNumberOfPoints();
+
+ //remove tracks with not enough points already now
+ if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalized_chi2 > fTrackChi2Cut)
+ {
+ track->SetProperties(false);
+ nTracks--;
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ tracks--;
+ }
+
+ else
+ {
+ fClustersUnused -= track->GetNumberOfPoints();
+ track->ComesFromMainVertex(fVertexConstraint);
+ //mark track as main vertex track or not
+ track->SetSector(2); //only needed for testing purposes.
+ track->SetRowRange(fRowMin,fRowMax);
+
+ if(fVertexConstraint)
+ fMainVertexTracks++;
+ }
+
+ }//good tracklet
+
+ }
+
+ return;
+}
+
+AliL3ConfMapPoint *AliL3ConfMapper::GetNextNeighbor(AliL3ConfMapPoint *start_hit,
+ AliL3ConfMapTrack *track)
+{
+ //When forming segments: Finds closest hit to input hit
+ //When forming tracks: Find closest hit to track fit.
+
+ Double_t dist,closest_dist = fMaxDist;
+
+ AliL3ConfMapPoint *hit = NULL;
+ AliL3ConfMapPoint *closest_hit = NULL;
+
+ Int_t sub_row_segm;
+ Int_t sub_phi_segm;
+ Int_t sub_eta_segm;
+ Int_t volumeIndex;
+ Int_t test_hit;
+
+ Int_t max_row = start_hit->GetPadRow()-1;
+ Int_t min_row;
+
+ if(track) //finding hit close to trackfit
+ {
+ min_row = start_hit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
+ }
+ else
+ {
+ min_row = start_hit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
+ }
+
+ //make a smart loop
+ Int_t loop_eta[9] = {0,0,0,-1,-1,-1,1,1,1};
+ Int_t loop_phi[9] = {0,-1,1,0,-1,1,0,-1,1};
+
+ if(min_row < fRowMin)
+ min_row = fRowMin;
+ if(max_row < fRowMin)
+ return 0; //reached the last padrow under consideration
+
+ else
+ {
+ //loop over sub rows
+ for(sub_row_segm=max_row; sub_row_segm>=min_row; sub_row_segm--)
+ {
+ //loop over subsegments, in the order defined above.
+ for(Int_t i=0; i<9; i++)
+ {
+ sub_phi_segm = start_hit->phiIndex + loop_phi[i];
+
+ if(sub_phi_segm<0)
+ sub_phi_segm += fNumPhiSegment;
+
+ else if(sub_phi_segm >=fNumPhiSegment)
+ sub_phi_segm -= fNumPhiSegment;
+
+ //loop over sub eta segments
+
+ sub_eta_segm = start_hit->etaIndex + loop_eta[i];
+
+ if(sub_eta_segm < 0 || sub_eta_segm >=fNumEtaSegment)
+ continue;//segment exceeds bounds->skip it
+
+ //loop over hits in this sub segment:
+ volumeIndex= sub_row_segm*fNumPhiEtaSegmentPlusOne +
+ sub_phi_segm*fNumEtaSegmentPlusOne + sub_eta_segm;
+
+ if(volumeIndex<0)
+ {//debugging
+ LOG(AliL3Log::kError,"AliL3ConfMapper::GetNextNeighbor","Memory")<<AliL3Log::kDec<<
+ "VolumeIndex error "<<volumeIndex<<ENDLOG;
+ }
+
+ for(hit = (AliL3ConfMapPoint*)fVolume[volumeIndex].first;
+ hit!=0; hit = hit->nextVolumeHit)
+ {
+
+ if(!hit->GetUsage())
+ {//hit was not used before
+
+ //set conformal mapping if looking for nonvertex tracks:
+ if(!fVertexConstraint)
+ {
+ hit->SetAllCoord(start_hit);
+ }
+
+ if(track)//track search - look for nearest neighbor to extrapolated track
+ {
+ if(!VerifyRange(start_hit,hit))
+ continue;
+
+ test_hit = EvaluateHit(start_hit,hit,track);
+
+ if(test_hit == 0)//chi2 not good enough, keep looking
+ continue;
+ else if(test_hit==2)//chi2 good enough, return it
+ return hit;
+ else
+ closest_hit = hit;//chi2 acceptable, but keep looking
+
+ }//track search
+
+ else //tracklet search, look for nearest neighbor
+ {
+
+ if((dist=CalcDistance(start_hit,hit)) < closest_dist)
+ {
+ if(!VerifyRange(start_hit,hit))
+ continue;
+ closest_dist = dist;
+ closest_hit = hit;
+
+ //if this hit is good enough, return it:
+ if(closest_dist < fGoodDist)
+ return closest_hit;
+ }
+ else
+ continue;//sub hit was farther away than a hit before
+
+ }//tracklet search
+
+ }//hit not used before
+
+ else continue; //sub hit was used before
+
+ }//loop over hits in sub segment
+
+ }//loop over sub segments
+
+ }//loop over subrows
+
+ }//else
+
+ //closest hit found:
+ if(closest_hit)// && closest_dist < mMaxDist)
+ return closest_hit;
+ else
+ return 0;
+}
+
+Int_t AliL3ConfMapper::EvaluateHit(AliL3ConfMapPoint *start_hit,AliL3ConfMapPoint *hit,AliL3ConfMapTrack *track)
+{
+ //Check if space point gives a fit with acceptable chi2.
+
+ Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
+ temp = (track->a2Xy*hit->GetXprime()-hit->GetYprime()+track->a1Xy);
+ dxy = temp*temp/(track->a2Xy*track->a2Xy + 1.);
+
+ //Calculate chi2
+ lchi2 = (dxy*hit->GetXYWeight());
+
+ if(lchi2 > track->fChiSq[0])//chi2 was worse than before.
+ return 0;
+
+ //calculate s and the distance hit-line
+ dx = start_hit->GetX()-hit->GetX();
+ dy = start_hit->GetY()-hit->GetY();
+ //slocal = track->fLength+sqrt(dx*dx+dy*dy);
+ slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
+
+ temp = (track->a2Sz*slocal-hit->GetZ()+track->a1Sz);
+ dsz = temp*temp/(track->a2Sz*track->a2Sz+1);
+
+ //calculate chi2
+ lszChi2 = dsz*hit->GetZWeight();
+ lchi2 += lszChi2;
+
+
+ //check whether chi2 is better than previous one:
+ if(lchi2 < track->fChiSq[0])
+ {
+ track->fChiSq[0] = lchi2;
+ track->fChiSq[1] = lszChi2;
+
+ hit->SetS(slocal);
+
+ //if chi2 good enough, stop here:
+ if(lchi2 < fGoodHitChi2)
+ return 2;
+
+ return 1;
+ }
+
+ return 0;
+
+}
+
+Double_t AliL3ConfMapper::CalcDistance(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const
+{
+ //Return distance between two clusters, defined by Pablo
+
+ Double_t phi_diff = fabs( hit1->GetPhi() - hit2->GetPhi() );
+ if (phi_diff > pi) phi_diff = twopi - phi_diff;
+
+ return todeg*fabs(hit1->GetPadRow() - hit2->GetPadRow()) * (phi_diff + fabs( hit1->GetEta() - hit2->GetEta() ));
+}
+
+Bool_t AliL3ConfMapper::VerifyRange(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const
+{
+ //Check if the hit are within reasonable range in phi and eta
+ Double_t dphi,deta;//maxphi=0.1,maxeta=0.1;
+ dphi = fabs(hit1->GetPhi() - hit2->GetPhi());
+ if(dphi > pi) dphi = fabs(twopi - dphi);
+ if(dphi > fMaxPhi) return false;
+
+ deta = fabs(hit1->GetEta() - hit2->GetEta());
+ if(deta > fMaxEta) return false;
+
+ return true;
+
+}
+
+Double_t AliL3ConfMapper::TrackletAngle(const AliL3ConfMapTrack *track,Int_t n) const
+{
+ // Returns the angle 'between' the last three points (started at point number n) on this track.
+
+ return 0;
+ /*
+ Double_t x1[2];
+ Double_t x2[2];
+ Double_t angle1,angle2;
+ TObjArray *hits = track->GetHits();
+
+ if (n > track->GetNumberOfPoints()) {
+ n = track->GetNumberOfPoints();
+ }
+
+ if (n<3)
+ return 0;
+
+
+ x1[0] = ((AliL3ConfMapPoint *)hits->At(n-2))->GetX() - ((AliL3ConfMapPoint *)hits->At(n-3))->GetX();
+ x1[1] = ((AliL3ConfMapPoint *)hits->At(n-2))->GetY() - ((AliL3ConfMapPoint *)hits->At(n-3))->GetY();
+
+ x2[0] = ((AliL3ConfMapPoint *)hits->At(n-1))->GetX() - ((AliL3ConfMapPoint *)hits->At(n-2))->GetX();
+ x2[1] = ((AliL3ConfMapPoint *)hits->At(n-1))->GetY() - ((AliL3ConfMapPoint *)hits->At(n-2))->GetY();
+
+ angle1 = atan2(x1[1],x1[0]);
+ angle2 = atan2(x2[1],x1[0]);
+ return fabs(angle1-angle2);
+ */
+}
+
+Int_t AliL3ConfMapper::FillTracks()
+{
+ //Fill track parameters. Which basically means do a fit of helix in real space,
+ //which should be done in order to get nice tracks.
+
+ Int_t num_of_tracks = nTracks;
+ LOG(AliL3Log::kInformational,"AliL3ConfMapper::FillTracks","nTracks")<<AliL3Log::kDec<<
+ "Number of found tracks: "<<nTracks<<ENDLOG;
+
+ if(nTracks == 0)
+ {
+ LOG(AliL3Log::kError,"AliL3ConfMapper::FillTracks","nTracks")<<AliL3Log::kDec<<
+ "No tracks found!!"<<ENDLOG;
+ return 0;
+ }
+
+ // fTrack->Sort();
+ for(int i=0; i<num_of_tracks; i++)
+ {
+ AliL3ConfMapTrack *track = (AliL3ConfMapTrack*)fTrack->GetTrack(i);
+ track->Fill(fVertex,fMaxDca);
+ }
+ return 1;
+
+}
+
+Double_t AliL3ConfMapper::CpuTime()
+{
+ //Return the Cputime in seconds.
+
+ return (Double_t)(clock()) / CLOCKS_PER_SEC;
+}
--- /dev/null
+#ifndef ALIL3_ConfMapper
+#define ALIL3_ConfMapper
+
+#include "AliL3RootTypes.h"
+
+#include "AliL3SpacePointData.h"
+
+class AliL3ConfMapPoint;
+class AliL3ConfMapTrack;
+class AliL3Vertex;
+class AliL3TrackArray;
+
+struct AliL3ConfMapContainer
+{
+ void *first;
+ void *last;
+};
+
+class AliL3ConfMapper {
+
+ private:
+
+ Bool_t fBench; //run-time measurements)
+
+ Int_t nTracks; //number of tracks build.
+
+ // AliTPCParam *fParam;
+ AliL3Vertex *fVertex; //!
+ Bool_t fParamSet;
+ Bool_t fVertexFinder; //Include vertexfinding or not (latter case vertex=(0,0,0))
+
+ AliL3ConfMapPoint **fHits; //!
+ AliL3ConfMapPoint *fHit; //!
+ AliL3TrackArray *fTrack; //!
+ Double_t fMaxDca; //cut value for momentum fit
+
+ AliL3ConfMapContainer *fVolume; //! Segment volume
+ AliL3ConfMapContainer *fRow; //! Row volume
+
+ //Number of cells (segments)
+ Int_t fNumRowSegment; // Total number of padrows
+ Int_t fNumPhiSegment; // number of phi segments
+ Int_t fNumEtaSegment; // number of eta segments
+ Int_t fNumRowSegmentPlusOne;
+ Int_t fNumPhiSegmentPlusOne;
+ Int_t fNumEtaSegmentPlusOne;
+ Int_t fNumPhiEtaSegmentPlusOne;
+ Int_t fBounds;
+ Int_t fPhiHitsOutOfRange;
+ Int_t fEtaHitsOutOfRange;
+
+ //tracking range:
+ Float_t fPhiMin; //MinPhi angle to consider
+ Float_t fPhiMax; //MaxPhi angle to consider
+ Float_t fEtaMin; //MinEta to consider
+ Float_t fEtaMax; //MaxEta to consider
+ Int_t fRowMin; //Minimum row to consider
+ Int_t fRowMax; //Maximum row to consider
+
+ Bool_t fVertexConstraint; //vertex constraint (true or false)
+ Int_t fTrackletLength[2]; //minimal length of tracks
+ Int_t fRowScopeTracklet[2]; //number of row segments to look for the next point of a tracklet
+ Int_t fRowScopeTrack[2]; //number of row segments to look for the next point of a track
+ Int_t fMinPoints[2]; //minimum number of points on one track
+
+ // Cuts
+ Double_t fMaxAngleTracklet[2]; //limit of angle between to pieces of a tracklet
+ Int_t fMaxDist; //maximum distance between two hits
+ Double_t fHitChi2Cut; //Maximum hit chi2
+ Double_t fGoodHitChi2; //Chi2 to stop looking for next hit
+ Double_t fTrackChi2Cut; //Maximum track chi2
+ Double_t fGoodDist; //In segment building, distance consider good enough
+ Double_t fMaxPhi;
+ Double_t fMaxEta;
+
+ // Tracking informtion
+ Int_t fMainVertexTracks; //number of tracks coming from the main vertex
+ Int_t fClustersUnused; //number of unused clusters
+
+ static Double_t todeg;
+ static Double_t pi;
+ static Double_t twopi;
+
+ //setter:
+ void SetMinPoints(Int_t f,Bool_t vertex_constraint) {fMinPoints[(Int_t)vertex_constraint] = f; }
+ void SetVertexConstraint(Bool_t f) {fVertexConstraint =f;}
+
+ void SetTrackletLength(Int_t f,Bool_t vert) {fTrackletLength[(Int_t)vert]=f;}
+ void SetRowScopeTrack(Int_t f, Bool_t vertex_constraint) { fRowScopeTrack[(Int_t)vertex_constraint] = f; } // sets one row scope for tracks
+ void SetRowScopeTracklet(Int_t f, Bool_t vertex_constraint) { fRowScopeTracklet[(Int_t)vertex_constraint] = f; } // sets one row scope for tracklets
+ void SetMaxAngleTracklet(Double_t f, Bool_t vertex_constraint) { fMaxAngleTracklet[(Int_t)vertex_constraint] = f; } // sets one angle cut
+
+ void SetPointers();
+ Double_t CpuTime();
+
+ public:
+
+ AliL3ConfMapper();
+ // AliL3ConfMapper(AliTPCParam *param,AliL3Vertex *vertex,Bool_t bench=(Bool_t)false);
+ virtual ~AliL3ConfMapper();
+
+ void InitSector(Int_t sector,Int_t *rowrange=0,Float_t *etarange=0);
+ void SetVertex(AliL3Vertex *vertex){fVertex = vertex;}
+ void MainVertexTracking_a();
+ void MainVertexTracking_b();
+ void MainVertexTracking();
+ void NonVertexTracking();
+ void MainVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,Double_t maxphi=0.1,Double_t maxeta=0.1);
+ void NonVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack);
+ Bool_t ReadHits(UInt_t count, AliL3SpacePointData* hits );
+ void ClusterLoop();
+ void CreateTrack(AliL3ConfMapPoint *hit);
+ AliL3ConfMapPoint *GetNextNeighbor(AliL3ConfMapPoint *start_hit,AliL3ConfMapTrack *track=NULL);
+ Int_t EvaluateHit(AliL3ConfMapPoint *start_hit,AliL3ConfMapPoint *hit,AliL3ConfMapTrack *track);
+
+ Double_t CalcDistance(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const;
+ Double_t TrackletAngle(const AliL3ConfMapTrack *track,Int_t n=3) const;
+ Bool_t VerifyRange(const AliL3ConfMapPoint *hit1,const AliL3ConfMapPoint *hit2) const;
+ Int_t FillTracks();
+
+ //getters
+ Int_t GetNumberOfTracks() {return nTracks;}
+ AliL3TrackArray *GetTracks() {return fTrack;}
+ Double_t GetMaxDca() const {return fMaxDca;}
+ AliL3Vertex* GetVertex() const
+ {
+ return fVertex;
+ }
+
+ //setters
+ void SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Int_t trackChi2Cut, Int_t maxdist);
+ void SetTrackletCuts(Double_t maxangle,Double_t goodDist,Bool_t vertex_constraint); //Set cut of tracklet for the given vertex_constraint
+ void SetNSegments(Int_t f,Int_t g) {fNumPhiSegment=f,fNumEtaSegment=g;} //Set number of subvolumes (#segments in (phi,eta)
+ void SetParamDone(Bool_t f) {fParamSet = (Bool_t)f;}
+ void SetMaxDca(Double_t f) {fMaxDca = f;}
+
+ ClassDef(AliL3ConfMapper,1) //Base class for conformal mapping tracking
+};
+
+#endif
--- /dev/null
+#ifndef _ALIL3DEFS_H_
+#define _ALIL3DEFS_H_
+
+#include "AliL3RootTypes.h"
+
+const Int_t NRows[5][2] = {{ 0, 45},{46,77},{78,109},{110,141},{142,173}};
+const Double_t Pi = 3.14159265358979323846;
+const Double_t ToRad = Pi/180.;
+
+
+#endif /* _ALIL3DEFS_H_ */
--- /dev/null
+#ifndef _DIGITDATA_H_
+#define _DIGITDATA_H_
+
+#include "AliL3RootTypes.h"
+
+struct AliL3DigitData
+{
+ UShort_t fCharge;
+ UChar_t fPad;
+ UShort_t fTime;
+};
+typedef struct AliL3DigitData AliL3DigitData;
+
+struct AliL3DigitRowData
+{
+ UInt_t fNDigit;
+ UInt_t fRow;
+ AliL3DigitData fDigitData[0];
+};
+typedef struct AliL3DigitRowData AliL3DigitRowData;
+
+struct AliL3RandomDigitData{
+ UChar_t fRow;
+ UShort_t fCharge;
+ UChar_t fPad;
+ UShort_t fTime;
+};
+typedef struct AliL3RandomDigitData AliL3RandomDigitData;
+#endif /* _DIGITDATA_H_ */
--- /dev/null
+//Author: Anders Strand Vestbo
+//Last Modified: 12.01.2001
+
+#include <TCanvas.h>
+#include <TView.h>
+#include <TPolyMarker3D.h>
+#include <TPolyLine3D.h>
+#include <TH2.h>
+#include <TTree.h>
+
+#include "AliSimDigits.h"
+#include "AliTPCParam.h"
+#include "AliL3Transform.h"
+#include "AliL3Track.h"
+#include "AliL3TrackArray.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3FileHandler.h"
+#include "AliL3Logging.h"
+#include "AliL3Display.h"
+
+// AliL3Display
+// Simple display class for the Level3 tracker.
+
+ClassImp(AliL3Display)
+
+AliL3Display::AliL3Display()
+{
+ fGeom = NULL;
+ fTracks = NULL;
+}
+
+AliL3Display::AliL3Display(Int_t *slice)
+{
+ //Ctor. Specify which slices you want to look at.
+
+ TFile *file = new TFile("alice.geom");
+ if(file->IsOpen())
+ LOG(AliL3Log::kError,"AliL3Display::AliL3Display","File Open")
+ <<"Geometry file alice.geom does not exist"<<ENDLOG;
+
+ fGeom = (TGeometry*)file->Get("AliceGeom");
+ fMinSlice = slice[0];
+ fMaxSlice = slice[1];
+
+ file->Close();
+ delete file;
+}
+
+AliL3Display::~AliL3Display()
+{
+
+ if(fTracks)
+ delete fTracks;
+
+}
+
+void AliL3Display::Setup(Char_t *trackfile)
+{
+ //Read in the hit and track information from produced files.
+
+ Char_t fname[256];
+ AliL3FileHandler *clusterfile[36][5];
+ for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+ {
+ for(Int_t p=0; p<5; p++)
+ {
+ clusterfile[s][p] = new AliL3FileHandler();
+ sprintf(fname,"points_%d_%d.raw",s,p);
+ if(!clusterfile[s][p]->SetBinaryInput(fname))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fClusters[s][p] = (AliL3SpacePointData*)clusterfile[s][p]->Allocate();
+ clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+ clusterfile[s][p]->CloseBinaryInput();
+ }
+ }
+
+
+ AliL3FileHandler *tfile = new AliL3FileHandler();
+ if(!tfile->SetBinaryInput(trackfile))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<trackfile<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fTracks = new AliL3TrackArray();
+ tfile->Binary2TrackArray(fTracks);
+ tfile->CloseBinaryInput();
+ delete tfile;
+
+}
+
+void AliL3Display::DisplayTracks(Int_t min_hits)
+{
+ //Display the found tracks.
+
+ TCanvas *c1 = new TCanvas("c1","",700,700);
+ c1->cd();
+ TView *v = new TView(1);
+ v->SetRange(-430,-560,-430,430,560,1710);
+ c1->Clear();
+ c1->SetFillColor(1);
+ c1->SetTheta(90.);
+ c1->SetPhi(0.);
+
+ Int_t ntracks = fTracks->GetNTracks();
+ TPolyLine3D *line = new TPolyLine3D[ntracks];
+ Float_t xcl[174];
+ Float_t ycl[174];
+ Float_t zcl[174];
+
+ for(Int_t j=0; j<ntracks; j++)
+ {
+ AliL3Track *gtrack = fTracks->GetCheckedTrack(j);
+ if(!gtrack) continue;
+ Int_t nHits = gtrack->GetNHits();
+ UInt_t *hitnum = gtrack->GetHitNumbers();
+ if(nHits < min_hits) continue;
+ TPolyMarker3D *pm = new TPolyMarker3D(nHits);
+ for(Int_t h=0; h<nHits; h++)
+ {
+ UInt_t id=hitnum[h];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+
+ AliL3SpacePointData *points = fClusters[slice][patch];
+
+ if(!points) {
+ LOG(AliL3Log::kError,"AliL3Display::DisplayTracks","Clusterarray")
+ <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
+ continue;
+ }
+ if(pos>=fNcl[slice][patch]) {printf("Error \n"); continue;}
+ xcl[h] = points[pos].fX;
+ ycl[h] = points[pos].fY;
+ zcl[h] = points[pos].fZ;
+ pm->SetPoint(h,xcl[h],ycl[h],zcl[h]);
+ }
+ pm->SetMarkerColor(3);
+ pm->Draw();
+ TPolyLine3D *current_line = &(line[j]);
+ current_line = new TPolyLine3D(nHits,xcl,ycl,zcl,"");
+
+ current_line->SetLineColor(4);
+ current_line->Draw("same");
+ }
+
+ fGeom->Draw("same");
+
+ c1->x3d();
+
+}
+
+void AliL3Display::DisplayClusters()
+{
+ //Display all clusters.
+
+ TCanvas *c1 = new TCanvas("c1","",700,700);
+ c1->cd();
+ TView *v = new TView(1);
+ v->SetRange(-430,-560,-430,430,560,1710);
+ c1->Clear();
+ c1->SetFillColor(1);
+ c1->SetTheta(90.);
+ c1->SetPhi(0.);
+
+ for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+ {
+ for(Int_t p=0;p<1;p++)
+ {
+ AliL3SpacePointData *points = fClusters[s][p];
+ if(!points) continue;
+ Int_t npoints = fNcl[s][p];
+ TPolyMarker3D *pm = new TPolyMarker3D(npoints);
+
+ Float_t xyz[3];
+ for(Int_t i=0; i<npoints; i++){
+ xyz[0] = points[i].fX;
+ xyz[1] = points[i].fY;
+ xyz[2] = points[i].fZ;
+
+ pm->SetPoint(i,xyz[0],xyz[1],xyz[2]);
+
+ }
+ pm->SetMarkerColor(2);
+ pm->Draw("");
+ }
+ }
+ fGeom->Draw("same");
+
+ c1->x3d();
+}
+
+
+void AliL3Display::DisplayAll(Int_t min_hits)
+{
+ //Display tracks & all hits.
+
+
+ TCanvas *c1 = new TCanvas("c1","",700,700);
+ c1->cd();
+ TView *v = new TView(1);
+ v->SetRange(-430,-560,-430,430,560,1710);
+ c1->Clear();
+ c1->SetFillColor(1);
+ c1->SetTheta(90.);
+ c1->SetPhi(0.);
+
+ for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+ {
+ for(Int_t p=0;p<1;p++)
+ {
+ AliL3SpacePointData *points = fClusters[s][p];
+ if(!points) continue;
+ Int_t npoints = fNcl[s][p];
+ TPolyMarker3D *pm = new TPolyMarker3D(npoints);
+
+ Float_t xyz[3];
+ for(Int_t i=0; i<npoints; i++){
+ xyz[0] = points[i].fX;
+ xyz[1] = points[i].fY;
+ xyz[2] = points[i].fZ;
+
+ pm->SetPoint(i,xyz[0],xyz[1],xyz[2]);
+
+ }
+ pm->SetMarkerColor(2);
+ pm->Draw("");
+ }
+ }
+
+ Int_t ntracks = fTracks->GetNTracks();
+ TPolyLine3D *line = new TPolyLine3D[ntracks];
+ Float_t xcl[174];
+ Float_t ycl[174];
+ Float_t zcl[174];
+
+
+ for(Int_t j=0; j<ntracks; j++)
+ {
+ AliL3Track *gtrack = fTracks->GetCheckedTrack(j);
+ if(!gtrack) continue;
+ Int_t nHits = gtrack->GetNHits();
+ UInt_t *hitnum = gtrack->GetHitNumbers();
+ if(nHits < min_hits) continue;
+ TPolyMarker3D *pm = new TPolyMarker3D(nHits);
+ for(Int_t h=0; h<nHits; h++)
+ {
+ UInt_t id=hitnum[h];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+
+ AliL3SpacePointData *points = fClusters[slice][patch];
+
+ if(!points) {
+ LOG(AliL3Log::kError,"AliL3Display::DisplayTracks","Clusterarray")
+ <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
+ continue;
+ }
+ if(pos>=fNcl[slice][patch]) {printf("Error \n"); continue;}
+ xcl[h] = points[pos].fX;
+ ycl[h] = points[pos].fY;
+ zcl[h] = points[pos].fZ;
+ pm->SetPoint(h,xcl[h],ycl[h],zcl[h]);
+ }
+ pm->SetMarkerColor(3);
+ pm->Draw();
+ TPolyLine3D *current_line = &(line[j]);
+ current_line = new TPolyLine3D(nHits,xcl,ycl,zcl,"");
+
+ current_line->SetLineColor(4);
+ current_line->Draw("same");
+ }
+
+ fGeom->Draw("same");
+
+ c1->x3d();
+
+}
+
+void AliL3Display::DisplayClusterRow(Int_t slice,Int_t padrow,Char_t *digitsFile)
+{
+ //Display the found clusters on this row together with the raw data.
+
+
+ TFile *file = new TFile(digitsFile);
+ AliTPCParam *param = (AliTPCParam*)file->Get("75x40_100x60");
+ TTree *TD=(TTree*)file->Get("TreeD_75x40_100x60");
+ AliSimDigits da, *digits=&da;
+ TD->GetBranch("Segment")->SetAddress(&digits); //Return pointer to branch segment.
+ AliL3Transform *transform = new AliL3Transform();
+
+ Int_t sector,row;
+ transform->Slice2Sector(slice,padrow,sector,row);
+ Int_t npads = param->GetNPads(sector,row);
+ Int_t ntimes = param->GetMaxTBin();
+ TH2F *histdig = new TH2F("histdig","",npads,0,npads-1,ntimes,0,ntimes-1);
+ TH2F *histfast = new TH2F("histfast","",npads,0,npads-1,ntimes,0,ntimes-1);
+
+ Int_t sectors_by_rows=(Int_t)TD->GetEntries();
+ Int_t i;
+ for (i=0; i<sectors_by_rows; i++) {
+ if (!TD->GetEvent(i)) continue;
+ Int_t sec,ro;
+ param->AdjustSectorRow(digits->GetID(),sec,ro);
+
+ if(sec != sector) continue;
+ if(ro < row) continue;
+ if(ro != row) break;
+ printf("sector %d row %d\n",sec,ro);
+ digits->First();
+ while (digits->Next()) {
+ Int_t it=digits->CurrentRow(), ip=digits->CurrentColumn();
+ Short_t dig = digits->GetDigit(it,ip);
+ if(dig<=param->GetZeroSup()) continue;
+ if(it < param->GetMaxTBin()-1 && it > 0)
+ if(digits->GetDigit(it+1,ip) <= param->GetZeroSup()
+ && digits->GetDigit(it-1,ip) <= param->GetZeroSup())
+ continue;
+
+ histdig->Fill(ip,it,dig);
+ }
+ }
+
+
+ for(Int_t p=0;p<1;p++)
+ {
+ AliL3SpacePointData *points = fClusters[slice][p];
+ if(!points) continue;
+
+ Int_t npoints = fNcl[slice][p];
+ Float_t xyz[3];
+ for(Int_t i=0; i<npoints; i++)
+ {
+ if(points[i].fPadRow != padrow) continue;
+ xyz[0] = points[i].fX;
+ xyz[1] = points[i].fY;
+ xyz[2] = points[i].fZ;
+ transform->Global2Raw(xyz,sector,row);
+ histfast->Fill((Int_t)xyz[1],(Int_t)xyz[2],1);
+
+ }
+
+ }
+
+ TCanvas *c1 = new TCanvas("c1","",2);
+ c1->cd();
+ histdig->Draw();
+
+ histfast->SetMarkerColor(2);
+ histfast->SetMarkerStyle(4);
+
+ histdig->GetXaxis()->SetTitle("Pad");
+ histdig->GetYaxis()->SetTitle("Time");
+ histdig->Draw("hist");
+ histfast->Draw("psame");
+
+}
--- /dev/null
+#ifndef ALIL3_Display
+#define ALIL3_Display
+
+#include <TObject.h>
+#include <TGeometry.h>
+
+class AliL3SpacePointData;
+class AliL3TrackArray;
+
+class AliL3Display : public TObject {
+
+ private:
+ TGeometry *fGeom;
+ AliL3SpacePointData *fClusters[36][5]; //!
+ AliL3TrackArray *fTracks; //!
+ UInt_t fNcl[36][5];
+
+ Int_t fMinSlice;
+ Int_t fMaxSlice;
+
+ public:
+ AliL3Display();
+ AliL3Display(Int_t *slice);
+ virtual ~AliL3Display();
+
+ void Setup(Char_t *trackfile);
+ void DisplayTracks(Int_t min_hits=10);
+ void DisplayAll(Int_t min_hits=10);
+ void DisplayClusters();
+ void DisplayClusterRow(Int_t slice,Int_t padrow,Char_t *digitsFile);
+
+ ClassDef(AliL3Display,1)
+};
+
+#endif
--- /dev/null
+//Author: Anders Strand Vestbo
+//Last Modified: 5.01.2001
+
+#include <stdio.h>
+#include <TFile.h>
+#include <TH1.h>
+#include <TParticle.h>
+#include <TTree.h>
+#include <TClonesArray.h>
+
+#include "AliRun.h"
+#include "AliSimDigits.h"
+#include "AliTPC.h"
+#include "AliTPCClustersArray.h"
+#include "AliTPCClustersRow.h"
+#include "AliTPCcluster.h"
+#include "AliTPCParam.h"
+
+#include "AliL3Transform.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3Track.h"
+#include "AliL3FileHandler.h"
+#include "AliL3TrackArray.h"
+#include "AliL3Evaluate.h"
+#include "AliL3Logging.h"
+
+//AliL3Evaluate
+//Class for tracking evaluation.
+
+ClassImp(AliL3Evaluate)
+
+AliL3Evaluate::AliL3Evaluate()
+{
+ fMCFile = NULL;
+ fTracks = NULL;
+ fMCclusterfile = NULL;
+}
+
+AliL3Evaluate::AliL3Evaluate(Char_t *mcfile,Int_t *slice)
+{
+ //Normal constructor. Input are the rootfile containing the
+ //original MC information of the simulated event.
+
+ fMCFile = new TFile(mcfile,"READ");
+ if(!fMCFile->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::AliL3Evaluation","File Open")
+ <<"Inputfile "<<mcfile<<" does not exist"<<ENDLOG;
+ return;
+ }
+
+ fParam = (AliTPCParam*)fMCFile->Get("75x40_100x60");
+ fTransform = new AliL3Transform();
+
+ fMinSlice = slice[0];
+ fMaxSlice = slice[1];
+
+}
+
+AliL3Evaluate::~AliL3Evaluate()
+{
+ if(fDigitsTree)
+ fDigitsTree->Delete();
+
+
+ /*if(fMCFile)
+ {
+ fMCFile->Close();
+ delete fMCFile;
+ }
+ */
+ if(fTransform)
+ delete fTransform;
+ if(fTracks)
+ delete fTracks;
+ if(fPtRes)
+ delete fPtRes;
+ if(fNGoodTracksPt)
+ delete fNGoodTracksPt;
+ if(fNFoundTracksPt)
+ delete fNFoundTracksPt;
+ if(fNFakeTracksPt)
+ delete fNFakeTracksPt;
+ if(fTrackEffPt)
+ delete fTrackEffPt;
+ if(fFakeTrackEffPt)
+ delete fFakeTrackEffPt;
+ if(fNGoodTracksEta)
+ delete fNGoodTracksEta;
+ if(fNFoundTracksEta)
+ delete fNFoundTracksEta;
+ if(fNFakeTracksEta)
+ delete fNFakeTracksEta;
+ if(fTrackEffEta)
+ delete fTrackEffEta;
+ if(fFakeTrackEffEta)
+ delete fFakeTrackEffEta;
+}
+
+void AliL3Evaluate::Setup(Char_t *trackfile,Char_t *clustfile)
+{
+ //Setup for using the slow simulator.
+ //Read in the hit and track information from produced files.
+
+ fIsSlow = true;
+
+ Char_t fname[256];
+ AliL3FileHandler *clusterfile[36][5];
+ for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+ {
+ for(Int_t p=0; p<5; p++)
+ {
+ clusterfile[s][p] = new AliL3FileHandler();
+ sprintf(fname,"points_%d_%d.raw",s,p);
+ if(!clusterfile[s][p]->SetBinaryInput(fname))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fClusters[s][p] = (AliL3SpacePointData*)clusterfile[s][p]->Allocate();
+ clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+ clusterfile[s][p]->CloseBinaryInput();
+ }
+ }
+
+
+ AliL3FileHandler *tfile = new AliL3FileHandler();
+ if(!tfile->SetBinaryInput(trackfile))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<trackfile<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fTracks = new AliL3TrackArray();
+ tfile->Binary2TrackArray(fTracks);
+ tfile->CloseBinaryInput();
+ delete tfile;
+
+ if(!SetDigitsTree())
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","Digits Tree")
+ <<"Error setting up digits tree"<<ENDLOG;
+ if(!SetMCParticleArray())
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","Particle array")
+ <<"Error setting up particle array"<<ENDLOG;
+
+}
+
+void AliL3Evaluate::SetupFast(Char_t *trackfile,Char_t *clustfile,Char_t *mcClusterfile)
+{
+ //Setup for using the fast simulator.
+
+ fIsSlow = false;
+
+ fMCclusterfile = new TFile(mcClusterfile);
+ if(!fMCclusterfile->IsOpen())
+ LOG(AliL3Log::kError,"AliL3Evaluation::SetupFast","File Open")
+ <<"Inputfile "<<mcClusterfile<<" does not exist"<<ENDLOG;
+
+ Char_t fname[256];
+ AliL3FileHandler *clusterfile[36][5];
+ for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+ {
+ for(Int_t p=0; p<5; p++)
+ {
+ clusterfile[s][p] = new AliL3FileHandler();
+ sprintf(fname,"points_%d_%d.raw",s,p);
+ if(!clusterfile[s][p]->SetBinaryInput(fname))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fClusters[s][p] = (AliL3SpacePointData*)clusterfile[s][p]->Allocate();
+ clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+ clusterfile[s][p]->CloseBinaryInput();
+ }
+ }
+
+
+ AliL3FileHandler *tfile = new AliL3FileHandler();
+ if(!tfile->SetBinaryInput(trackfile))
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
+ <<"Inputfile "<<trackfile<<" does not exist"<<ENDLOG;
+ return;
+ }
+ fTracks = new AliL3TrackArray();
+ tfile->Binary2TrackArray(fTracks);
+ tfile->CloseBinaryInput();
+ delete tfile;
+
+ if(!SetMCParticleArray())
+ LOG(AliL3Log::kError,"AliL3Evaluation::SetupFast","Particle array")
+ <<"Error setting up particle array"<<ENDLOG;
+}
+
+void AliL3Evaluate::CreateHistos(Int_t nbin,Int_t xlow,Int_t xup)
+{
+ //Create the histograms
+
+ fPtRes = new TH1F("fPtRes","Relative Pt resolution",30,-10.,10.);
+ fNGoodTracksPt = new TH1F("fNGoodTracksPt","Good tracks vs pt",nbin,xlow,xup);
+ fNFoundTracksPt = new TH1F("fNFoundTracksPt","Found tracks vs pt",nbin,xlow,xup);
+ fNFakeTracksPt = new TH1F("fNFakeTracksPt","Fake tracks vs pt",nbin,xlow,xup);
+ fTrackEffPt = new TH1F("fTrackEffPt","Tracking efficiency vs pt",nbin,xlow,xup);
+ fFakeTrackEffPt = new TH1F("fFakeTrackEffPt","Efficiency for fake tracks vs pt",nbin,xlow,xup);
+
+ fNGoodTracksEta = new TH1F("fNGoodTracksEta","Good tracks vs eta",20,-50,50);
+ fNFoundTracksEta = new TH1F("fNFoundTracksEta","Found tracks vs eta",20,-50,50);
+ fNFakeTracksEta = new TH1F("fNFakeTracksEta","Fake tracks vs eta",20,-50,50);
+ fTrackEffEta = new TH1F("fTrackEffEta","Tracking efficienct vs eta",20,-50,50);
+ fFakeTrackEffEta = new TH1F("fFakeTrackEffEta","Efficiency for fake tracks vs eta",20,-50,50);
+
+}
+
+Bool_t AliL3Evaluate::SetDigitsTree()
+{
+
+ fMCFile->cd();
+ fDigitsTree = (TTree*)fMCFile->Get("TreeD_75x40_100x60");
+ if(!fDigitsTree) return false;
+ fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
+ for(Int_t i=0; i<fDigitsTree->GetEntries(); i++)
+ {
+ if(!fDigitsTree->GetEvent(i)) continue;
+ Int_t se,ro,slice,slicerow;
+ fParam->AdjustSectorRow(fDigits->GetID(),se,ro);
+ fTransform->Sector2Slice(slice,slicerow,se,ro);
+ fRowid[slice][slicerow] = i;
+ }
+
+ return true;
+}
+
+Bool_t AliL3Evaluate::SetMCParticleArray()
+{
+ fMCFile->cd();
+ AliRun *gAlice = (AliRun*)fMCFile->Get("gAlice");
+ if (!gAlice)
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::SetParticleArray","gAlice")
+ <<"AliRun object non existing on file"<<ENDLOG;
+ return false;
+ }
+
+ gAlice->GetEvent(0);
+ fParticles=gAlice->Particles();
+ return true;
+}
+
+
+TObjArray *AliL3Evaluate::DefineGoodTracks(Int_t slice,Int_t *padrow,Int_t good_number,Int_t *particle_id)
+{
+ //Loop over MC particles, and mark the good ones
+ //(which the tracker should find...)
+
+ Int_t np=fParticles->GetEntriesFast();
+ AliTPC *TPC = (AliTPC*)gAlice->GetDetector("TPC");
+ TPC->SetParam(fParam);
+ Int_t ver = TPC->IsVersion();
+ LOG(AliL3Log::kInformational,"AliL3Evaluate::DefineGoodTracks","TPC version")
+ <<"TPC version "<<ver<<" found on file"<<ENDLOG;
+
+ //Int_t nrow_up=TPC->GetParam()->GetNRowUp();
+ //Int_t nrows=TPC->GetParam()->GetNRowLow()+nrow_up;
+ Int_t zero=TPC->GetParam()->GetZeroSup();
+
+ //Int_t number_of_rows = padrow[1] - padrow[0] + 1;
+
+ Int_t *good = new Int_t[np];
+ for(Int_t ii=0; ii<np; ii++)
+ good[ii] = 0;
+
+ if(ver==1)
+ {
+ if(fIsSlow)
+ LOG(AliL3Log::kError,"AliL3Evaluate::DefineGoodTracks","TPC version")
+ <<"TPC version "<<ver<<" does not match."<<ENDLOG;
+ fMCclusterfile->cd();
+ AliTPCClustersArray carray;
+ carray.Setup(fParam);
+ carray.SetClusterType("AliTPCcluster");
+ Bool_t clusterok = carray.ConnectTree("Segment Tree");
+ if(!clusterok)
+ LOG(AliL3Log::kError,"AliL3Evaluate::DefineGoodTracks","Cluster Array")
+ <<"Error loading clusters from rootfile"<<ENDLOG;
+
+ for(Int_t i=padrow[0]; i<=padrow[1]; i++)
+ {
+ Int_t sec,row,sl,lr;
+ AliSegmentID *s = carray.LoadEntry(i);
+ fParam->AdjustSectorRow(s->GetID(),sec,row);
+ fTransform->Sector2Slice(sl,lr,sec,row);
+
+ if(sl != slice) {carray.ClearRow(sec,row); continue;}
+ if(lr != i) {carray.ClearRow(sec,row); continue;}
+ AliTPCClustersRow *cRow = carray.GetRow(sec,row);
+ for(Int_t j=0; j<cRow->GetArray()->GetEntriesFast(); j++)
+ {
+ AliTPCcluster *cluster=(AliTPCcluster*)(*cRow)[j];
+ Int_t lab=cluster->GetLabel(0);
+ if(lab<0) continue;
+ lab=TMath::Abs(lab);
+ good[lab]++;
+ }
+ if(carray.GetRow(sec,row))
+ carray.ClearRow(sec,row);
+ }
+ }
+ else if(ver==2)
+ {
+ if(!fIsSlow)
+ LOG(AliL3Log::kError,"AliL3Evaluate::DefineGoodTracks","TPC version")
+ <<"TPC version "<<ver<<" does not match."<<ENDLOG;
+ Int_t *count = new Int_t[np]; //np number of particles.
+ Int_t i;
+ for (i=0; i<np; i++) count[i]=0;
+ for (i=padrow[0]; i<=padrow[1]; i++) {
+ Int_t index = fRowid[slice][i];
+ if (!fDigitsTree->GetEvent(index)) continue;
+ Int_t sec,row;
+ fParam->AdjustSectorRow(fDigits->GetID(),sec,row);
+ fDigits->First();
+ while (fDigits->Next()) {
+ Int_t it=fDigits->CurrentRow(), ip=fDigits->CurrentColumn();
+ Short_t dig = fDigits->GetDigit(it,ip);
+ Int_t idx0=fDigits->GetTrackID(it,ip,0);
+ Int_t idx1=fDigits->GetTrackID(it,ip,1);
+ Int_t idx2=fDigits->GetTrackID(it,ip,2);
+ if (idx0>=0 && dig>=zero) count[idx0]+=1;
+ if (idx1>=0 && dig>=zero) count[idx1]+=1;
+ if (idx2>=0 && dig>=zero) count[idx2]+=1;
+ }
+ for (Int_t j=0; j<np; j++) {
+ if (count[j]>1) {//at least two digits at this padrow
+ good[j]++;
+ }
+ count[j]=0;
+ }
+ }
+ delete[] count;
+ }
+ else
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluation::FillEffHistos","TPC version")
+ <<"No valid TPC version found"<<ENDLOG;
+ return 0;
+ }
+
+ Float_t torad=TMath::Pi()/180;
+
+ Float_t phi_min = slice*20 - 10;
+ Float_t phi_max = slice*20 + 10;
+ TObjArray *good_part = new TObjArray();
+
+ for(Int_t i=0; i<fParticles->GetEntriesFast(); i++)
+ {
+ TParticle *p = (TParticle*)fParticles->UncheckedAt(i);
+ if(p->GetFirstMother()>0) continue; //secondary particle
+ if(good[i] < good_number) {continue;}
+
+ Double_t ptg=p->Pt(),pxg=p->Px(),pyg=p->Py(),pzg=p->Pz();
+ Double_t phi_part = TMath::ATan2(pyg,pxg);
+ if (phi_part < 0) phi_part += 2*TMath::Pi();
+
+
+ if(phi_part < phi_min*torad || phi_part > phi_max*torad) {continue;}
+ if(ptg<0.100) continue;
+ if(fabs(pzg/ptg)>0.999) {continue;}
+ Int_t entries = good_part->GetEntriesFast();
+ good_part->AddLast(p);
+ particle_id[entries] = i;
+ }
+ delete [] good;
+ return good_part;
+}
+
+void AliL3Evaluate::EvaluatePatch(Int_t slice,Int_t patch,Int_t min_points,Int_t good_number)
+{
+ //Make efficiency plots for tracking on patch level (before any merging).
+
+ Int_t row[5][2] = {{ 0, 45},{46,77},{78,109},{110,141},{142,173}};
+ Int_t *particle_id = new Int_t[fParticles->GetEntriesFast()];
+ TObjArray *good_particles = DefineGoodTracks(slice,row[patch],good_number,particle_id);
+ SetMinPoints(min_points);
+ AssignIDs();
+ FillEffHistos(good_particles,particle_id);
+ delete good_particles;
+ delete [] particle_id;
+}
+
+void AliL3Evaluate::EvaluateSlice(Int_t slice,Int_t min_points,Int_t good_number)
+{
+ //Make efficiency plots for tracking on a slice (after merging).
+ //min_points = minimum points on track to be considered for evaluation
+ //good_number = minimum hits (padrows) produced by simulated track for consideration.
+
+ Int_t row[174] = {0,173};
+ Int_t *particle_id = new Int_t[fParticles->GetEntriesFast()];
+ TObjArray *good_particles = DefineGoodTracks(slice,row,good_number,particle_id);
+ SetMinPoints(min_points);
+ AssignIDs();
+ FillEffHistos(good_particles,particle_id);
+ delete good_particles;
+ delete [] particle_id;
+}
+
+void AliL3Evaluate::EvaluateGlobal()
+{
+ //Make efficiency plots for tracking on several slices.
+ /*
+ Int_t row[174] = {0,173};
+ TObjArray *good_particles = DefineGoodTracks(slice,row,good_number);
+ FillEffHistos(good_particles);
+ delete good_particles;
+ */
+}
+
+void AliL3Evaluate::FillEffHistos(TObjArray *good_particles,Int_t *particle_id)
+{
+ //Fill the efficiency histograms.
+
+
+ CreateHistos();
+
+ for(Int_t i=0; i<good_particles->GetEntriesFast(); i++)
+ {
+ TParticle *p = (TParticle*)good_particles->UncheckedAt(i);
+ Double_t ptg=p->Pt(),pzg=p->Pz();
+ Float_t dipangle=TMath::ATan2(pzg,ptg)*180./TMath::Pi();
+ fNGoodTracksPt->Fill(ptg);
+ fNGoodTracksEta->Fill(dipangle);
+ Int_t found = 0;
+ for(Int_t k=0; k<fTracks->GetNTracks(); k++)
+ {
+ AliL3Track *track = fTracks->GetCheckedTrack(k);
+ if(!track) continue;
+ Int_t nHits = track->GetNumberOfPoints();
+ if(nHits < fMinPointsOnTrack) break;
+
+ Int_t tracklabel;
+ tracklabel = track->GetMCid();
+
+ if(TMath::Abs(tracklabel) != particle_id[i]) continue;
+ found=1;
+ if(tracklabel == particle_id[i]) {fNFoundTracksPt->Fill(ptg); fNFoundTracksEta->Fill(dipangle);}
+ else {fNFakeTracksPt->Fill(ptg); fNFakeTracksEta->Fill(dipangle);}
+ Float_t pt=track->GetPt();
+ fPtRes->Fill((pt-ptg)/ptg*100.);
+ break;
+
+ }
+ }
+
+
+ Stat_t ngood=fNGoodTracksPt->GetEntries();
+ Stat_t nfound=fNFoundTracksPt->GetEntries();
+ Stat_t nfake=fNFakeTracksPt->GetEntries();
+
+ LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
+ <<AliL3Log::kDec<<"There was "<<ngood<<" generated good tracks"<<ENDLOG;
+ LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
+ <<AliL3Log::kDec<<"Found "<<nfound<<" tracks"<<ENDLOG;
+ LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
+ <<AliL3Log::kDec<<"Integral efficiency is about "<<nfound/ngood*100<<ENDLOG;
+ LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
+ <<AliL3Log::kDec<<"Fake tracks relative is about "<<nfake/ngood*100<<ENDLOG;
+
+ fNFoundTracksPt->Sumw2(); fNGoodTracksPt->Sumw2();
+ fTrackEffPt->Divide(fNFoundTracksPt,fNGoodTracksPt,1,1.,"b");
+ fFakeTrackEffPt->Divide(fNFakeTracksPt,fNGoodTracksPt,1,1.,"b");
+ fTrackEffPt->SetMaximum(1.4);
+ fTrackEffPt->SetXTitle("P_{T} [GeV]");
+ fTrackEffPt->SetLineWidth(2);
+ fFakeTrackEffPt->SetFillStyle(3013);
+ fTrackEffPt->SetLineColor(4);
+ fFakeTrackEffPt->SetFillColor(2);
+
+ fNFoundTracksEta->Sumw2(); fNGoodTracksEta->Sumw2();
+ fTrackEffEta->Divide(fNFoundTracksEta,fNGoodTracksEta,1,1.,"b");
+ fFakeTrackEffEta->Divide(fNFakeTracksEta,fNGoodTracksEta,1,1.,"b");
+ fTrackEffEta->SetMaximum(1.4);
+ fTrackEffEta->SetXTitle("#lambda [degrees]");
+ fTrackEffEta->SetLineWidth(2);
+ fFakeTrackEffEta->SetFillStyle(3013);
+ fTrackEffEta->SetLineColor(4);
+ fFakeTrackEffEta->SetFillColor(2);
+
+}
+
+void AliL3Evaluate::AssignIDs()
+{
+ //Assign MC id to the tracks.
+
+ UInt_t *index=0,tmp_ind=0;
+ Int_t *pID=0,npoints=0;
+
+ if(!fIsSlow)
+ {
+ pID = GetFastIDs(tmp_ind,npoints);
+ index = (UInt_t*)tmp_ind;
+ }
+
+ fTracks->QSort();
+ LOG(AliL3Log::kDebug,"AliL3Evaluate::AssignIDs","Track Loop")
+ <<"Assigning MC id to the found tracks...."<<ENDLOG;
+ for(Int_t i=0; i<fTracks->GetNTracks(); i++)
+ {
+ AliL3Track *track = (AliL3Track*)fTracks->GetCheckedTrack(i);
+ if(!track)
+ {
+ LOG(AliL3Log::kWarning,"AliL3Evaluate::AssignIDs","Track Loop")
+ <<AliL3Log::kDec<<"No track in track array, index "<<i<<ENDLOG;
+ continue;
+ }
+ if(track->GetNumberOfPoints() < fMinPointsOnTrack) break;
+ Int_t tID;
+ if(!fIsSlow)
+ tID = GetMCTrackLabel(track,index,pID,npoints);
+ else
+ tID = GetMCTrackLabel(track);
+ track->SetMCid(tID);
+ printf("track %i id %d\n",i,tID);
+ }
+
+ if(!fIsSlow)
+ {
+ delete [] pID;
+ delete [] index;
+ }
+
+}
+
+
+struct S {Int_t lab; Int_t max;};
+Int_t AliL3Evaluate::GetMCTrackLabel(AliL3Track *track,UInt_t *index,Int_t *pID,Int_t npoints)
+{
+ //Returns the MCtrackID of the belonging clusters.
+ //If MCLabel < 0, means that track is fake.
+ //Fake track means that more than 10 percent of clusters are assigned incorrectly.
+
+ Int_t num_of_clusters = track->GetNumberOfPoints();
+ S *s=new S[num_of_clusters];
+ Int_t i;
+ for (i=0; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
+ UInt_t *hitnum = track->GetHitNumbers();
+ UInt_t id;
+
+ Int_t **trackID;
+
+ if(fIsSlow)
+ trackID = GetClusterIDs(track);
+ else
+ trackID = GetClusterIDs(track,index,pID,npoints);
+
+
+ Int_t lab=123456789;
+ for (i=0; i<num_of_clusters; i++)
+ {
+ //Tricks to get the clusters belonging to this track:
+ id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+
+ AliL3SpacePointData *points = fClusters[slice][patch];
+
+ if(!points)
+ continue;
+
+ if(pos>=fNcl[slice][patch])
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray")
+ <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
+ continue;
+ }
+
+ //Get the label of the cluster:
+ //printf("label %d %d %d\n",trackID[i][0],trackID[i][1],trackID[i][2]);
+ lab=abs(trackID[i][0]);
+ Int_t j;
+ for (j=0; j<num_of_clusters; j++)
+ if (s[j].lab==lab || s[j].max==0) break;
+ s[j].lab=lab;
+ s[j].max++;
+ }
+
+ Int_t max=0;
+ for (i=0; i<num_of_clusters; i++)
+ if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
+
+ delete[] s;
+
+ for (i=0; i<num_of_clusters; i++)
+ {
+ id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+
+ AliL3SpacePointData *points = fClusters[slice][patch];
+
+ if(!points)
+ continue;
+
+ if(pos>=fNcl[slice][patch])
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray")
+ <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
+ continue;
+ }
+
+ if (abs(trackID[i][1]) == lab ||
+ abs(trackID[i][2]) == lab ) max++;
+ }
+
+ //check if more than 10% of the clusters are incorrectly assigned (fake track):
+ if (1.-Float_t(max)/num_of_clusters > 0.10)
+ {
+ return -lab;
+ }
+
+ delete [] trackID;
+ return lab;
+}
+
+
+Int_t **AliL3Evaluate::GetClusterIDs(AliL3Track *track,UInt_t *index,Int_t *pID,Int_t npoints)
+{
+ //Return the MC information of all clusters belonging to track.
+
+ Int_t num_of_clusters = track->GetNumberOfPoints();
+ Int_t **trackID = new Int_t*[num_of_clusters];
+
+ UInt_t *hitnum = track->GetHitNumbers();
+ UInt_t id;
+
+
+ Float_t xyz[3];
+ Int_t sector,padrow;
+ for(Int_t i=0; i<num_of_clusters; i++)
+ {
+ id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+
+ AliL3SpacePointData *points = fClusters[slice][patch];
+
+ if(!points)
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::GetClusterIDs","Clusterarray")
+ <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
+ continue;
+ }
+ if(pos>=fNcl[slice][patch])
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::GetClusterIDs","Clusterarray")
+ <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
+ continue;
+ }
+
+ xyz[0] = points[pos].fX;
+ xyz[1] = points[pos].fY;
+ xyz[2] = points[pos].fZ;
+ //sector = points[pos].fSector;
+ padrow = points[pos].fPadRow;
+ Int_t se,ro;
+ fTransform->Slice2Sector(slice,padrow,se,ro);
+ fTransform->Global2Raw(xyz,se,ro);
+
+ if(fIsSlow)
+ {
+ Int_t p = fRowid[slice][padrow];
+
+ if(!fDigitsTree->GetEvent(p))
+ LOG(AliL3Log::kError,"AliL3Evaluate::GetClusterIDs","Digits Tree")
+ <<"Error reading digits tree"<<ENDLOG;
+
+ trackID[i] = new Int_t[3];
+ trackID[i][0] = fDigits->GetTrackID((Int_t)xyz[2],(Int_t)xyz[1],0);
+ trackID[i][1] = fDigits->GetTrackID((Int_t)xyz[2],(Int_t)xyz[1],1);
+ trackID[i][2] = fDigits->GetTrackID((Int_t)xyz[2],(Int_t)xyz[1],2);
+ }
+ else
+ {
+ Int_t tmp_pid=0;
+ for(Int_t ii=0; ii<npoints; ii++)
+ {
+ tmp_pid = pID[ii];
+ if(index[ii] == id) break;
+ }
+ trackID[i] = new Int_t[3];
+ trackID[i][0] = tmp_pid;
+ trackID[i][1] = -1;
+ trackID[i][2] = -1;
+ }
+ }
+ return trackID;
+}
+
+Int_t *AliL3Evaluate::GetFastIDs(UInt_t &tmp_ind,Int_t &npoints)
+{
+ //Get the MC id of space points in case of using the fast simulator.
+
+ FILE *infile = fopen("point_mc.dat","r");
+ if(!infile) return 0;
+ Int_t hitid,hitmc,i;
+
+ for(i=0; ; i++)
+ if(fscanf(infile,"%d %d",&hitid,&hitmc)==EOF) break;
+ npoints = i;
+ rewind(infile);
+ Int_t *pID = new Int_t[npoints];
+ UInt_t *ind = new UInt_t[npoints];
+ tmp_ind = (UInt_t)ind;
+
+ for(i=0; i<npoints; i++)
+ {
+ if(fscanf(infile,"%d %d",&hitid,&hitmc)==EOF) break;
+ pID[i] = hitmc;
+ ind[i] = hitid;
+ }
+ fclose(infile);
+
+ return pID;
+
+}
+
+void AliL3Evaluate::Write2File(Char_t *outputfile)
+{
+ //Write histograms to file:
+
+ TFile *of = new TFile(outputfile,"RECREATE");
+ if(!of->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliL3Evaluate::Write2File","File Open")
+ <<"Problems opening rootfile"<<ENDLOG;
+ return;
+ }
+
+ of->cd();
+ fPtRes->Write();
+ fNGoodTracksPt->Write();
+ fNFoundTracksPt->Write();
+ fNFakeTracksPt->Write();
+ fTrackEffPt->Write();
+ fFakeTrackEffPt->Write();
+ fNGoodTracksEta->Write();
+ fNFoundTracksEta->Write();
+ fNFakeTracksEta->Write();
+ fTrackEffEta->Write();
+ fFakeTrackEffEta->Write();
+
+ of->Close();
+ delete of;
+
+}
+
--- /dev/null
+#ifndef ALIL3_Evaluate
+#define ALIL3_Evaluate
+
+#include <TObject.h>
+#include <TH1.h>
+#include <TTree.h>
+#include "AliSimDigits.h"
+
+class AliL3Track;
+class TClonesArray;
+class TFile;
+class AliL3TrackArray;
+class AliL3SpacePointData;
+class TH1F;
+class AliL3Transform;
+class AliTPCParam;
+class TTree;
+class AliSimDigits;
+class TObjArray;
+
+class AliL3Evaluate : public TObject {
+
+ private:
+
+ TFile *fMCFile;
+ TFile *fMCclusterfile; //If you run the fast simulator.
+ TClonesArray *fParticles;
+ AliL3TrackArray *fTracks; //!
+ AliTPCParam *fParam;
+ AliL3SpacePointData *fClusters[36][5]; //!
+ AliL3Transform *fTransform; //!
+ AliSimDigits *fDigits;
+ TTree *fDigitsTree;
+ Int_t fMinSlice;
+ Int_t fMaxSlice;
+ UInt_t fNcl[36][5];
+ Int_t fRowid[36][174];
+ Int_t fMinPointsOnTrack; //Minimum points on track to be considered.
+ Bool_t fIsSlow;
+ Int_t fNFastPoints;
+ UInt_t fMcIndex;
+ Int_t fMcId;
+
+ //Histograms
+ TH1F *fPtRes;
+ TH1F *fNGoodTracksPt;
+ TH1F *fNFoundTracksPt;
+ TH1F *fNFakeTracksPt;
+ TH1F *fTrackEffPt;
+ TH1F *fFakeTrackEffPt;
+ TH1F *fNGoodTracksEta;
+ TH1F *fNFoundTracksEta;
+ TH1F *fNFakeTracksEta;
+ TH1F *fTrackEffEta;
+ TH1F *fFakeTrackEffEta;
+
+ void FillEffHistos(TObjArray *good_particles,Int_t *particle_id);
+ void AssignIDs();
+ Bool_t SetDigitsTree();
+ Bool_t SetMCParticleArray();
+ TObjArray *DefineGoodTracks(Int_t slice,Int_t *padrow,Int_t good_number,Int_t *particle_id);
+ Int_t GetMCTrackLabel(AliL3Track *track,UInt_t *index=0,Int_t *pID=0,Int_t npoints=0);
+ Int_t **GetClusterIDs(AliL3Track *track,UInt_t *index=0,Int_t *pID=0,Int_t npoints=0);
+ Int_t *GetFastIDs(UInt_t &tmp_ind,Int_t &npoints);
+
+ public:
+ AliL3Evaluate();
+ AliL3Evaluate(Char_t *mcfile,Int_t *slice);
+
+ virtual ~AliL3Evaluate();
+
+ void Setup(Char_t *trackfile,Char_t *clustfile);
+ void SetupFast(Char_t *trackfile,Char_t *clustfile,Char_t *mcClusterfile);
+ void CreateHistos(Int_t nbin=20,Int_t xlow=0,Int_t xup=4);
+ void EvaluatePatch(Int_t slice,Int_t patch,Int_t min_points,Int_t good_number);
+ void EvaluateSlice(Int_t slice,Int_t min_points,Int_t good_number);
+ void EvaluateGlobal();
+ void Write2File(Char_t *outputfile);
+
+ TH1F *GetTrackEffPt() {return fTrackEffPt;}
+ TH1F *GetTrackEffEta() {return fTrackEffEta;}
+ TH1F *GetPtRes() {return fPtRes;}
+
+ void SetMinPoints(Int_t f) {fMinPointsOnTrack = f;}
+
+ ClassDef(AliL3Evaluate,1)
+};
+
+#endif
--- /dev/null
+
+//Author: Uli Frankenfeld
+//Last Modified: 17.12.2000
+
+#include <math.h>
+#include <iostream.h>
+#include <TFile.h>
+#include <TTree.h>
+#include <stdio.h>
+
+#include "AliL3Transform.h"
+#include "AliL3Logging.h"
+#include "AliL3MemHandler.h"
+#include "AliL3FileHandler.h"
+
+#include "AliTPCClustersArray.h"
+#include "AliTPCcluster.h"
+#include "AliTPCClustersRow.h"
+#include "AliTPCParam.h"
+#include "AliSimDigits.h"
+
+#include "AliL3DigitData.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3TrackArray.h"
+//_____________________________________________________________
+//
+// The L3 Binary File handler
+//
+
+ClassImp(AliL3FileHandler)
+
+AliL3FileHandler::AliL3FileHandler(){
+ //Default constructor
+ fInAli = 0;
+ fParam = 0;
+ fTransformer = 0;
+ fMC =0;
+}
+
+
+AliL3FileHandler::~AliL3FileHandler(){
+ //Destructor
+ if(fTransformer) delete fTransformer;
+ if(fMC) CloseMCOutput();
+}
+
+Bool_t AliL3FileHandler::SetMCOutput(char *name){
+ fMC = fopen(name,"w");
+ if(!fMC){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::SetMCOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+Bool_t AliL3FileHandler::SetMCOutput(FILE *file){
+ fMC = file;
+ if(!fMC){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::SetMCOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+void AliL3FileHandler::CloseMCOutput(){
+ if(!fMC){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::CloseMCOutPut","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ fclose(fMC);
+ fMC =0;
+}
+
+Bool_t AliL3FileHandler::SetAliInput(){
+ if(!fInAli->IsOpen()){
+ LOG(AliL3Log::kError,"AliL3FileHandler::SetAliInput","File Open")
+ <<"Ali File "<<fInAli->GetName()<<" does not exist"<<ENDLOG;
+ return kFALSE;
+ }
+ fParam = (AliTPCParam*)fInAli->Get("75x40_100x60");
+ if(!fParam){
+ LOG(AliL3Log::kError,"AliL3FileHandler::SetAliInput","File Open")
+ <<"No AliTPCParam 75x40_100x60 in File "<<fInAli->GetName()<<ENDLOG;
+ return kFALSE;
+ }
+ fTransformer = new AliL3Transform();
+ return kTRUE;
+}
+
+Bool_t AliL3FileHandler::SetAliInput(char *name){
+ fInAli= new TFile(name,"READ");
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::SetAliInput","File Open")
+ <<"Pointer to TFile = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return SetAliInput();
+}
+
+Bool_t AliL3FileHandler::SetAliInput(TFile *file){
+ fInAli=file;
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::SetAliInput","File Open")
+ <<"Pointer to TFile = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return SetAliInput();
+}
+
+void AliL3FileHandler::CloseAliInput(){
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::CloseAliInput","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ if(fInAli->IsOpen()) fInAli->Close();
+ delete fInAli;
+ fInAli = 0;
+}
+
+Bool_t AliL3FileHandler::IsDigit(){
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::IsDigit","File")
+ <<"Pointer to TFile = 0x0 "<<ENDLOG;
+ return kTRUE; //may you are use binary input which is Digits!!
+ }
+ TTree *t=(TTree*)fInAli->Get("TreeD_75x40_100x60");
+ if(t){
+ LOG(AliL3Log::kInformational,"AliL3FileHandler::IsDigit","File Type")
+ <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
+ return kTRUE;
+ }
+ else{
+ LOG(AliL3Log::kInformational,"AliL3FileHandler::IsDigit","File Type")
+ <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
+ return kFALSE;
+ }
+}
+
+///////////////////////////////////////// Digit IO
+Bool_t AliL3FileHandler::AliDigits2Binary(){
+ Bool_t out = kTRUE;
+ UInt_t nrow;
+ AliL3DigitRowData* data = AliDigits2Memory(nrow);
+ out = Memory2Binary(nrow,data);
+ Free();
+ return out;
+}
+
+
+Bool_t AliL3FileHandler::AliDigits2CompBinary(){
+ Bool_t out = kTRUE;
+ UInt_t ndigits=0;
+ AliL3DigitRowData* digits = AliDigits2Memory(ndigits);
+ out = Memory2CompBinary(ndigits,digits);
+ Free();
+ return out;
+}
+
+
+AliL3DigitRowData * AliL3FileHandler::AliDigits2Memory(UInt_t & nrow){
+ AliL3DigitRowData *data = 0;
+ nrow=0;
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::AliDigits2Memory","File")
+ <<"No Input avalible: no object TFile"<<ENDLOG;
+ return 0;
+ }
+ if(!fInAli->IsOpen()){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::AliDigits2Memory","File")
+ <<"No Input avalible: TFile not opend"<<ENDLOG;
+ return 0;
+ }
+
+ TDirectory *savedir = gDirectory;
+ fInAli->cd();
+ TTree *t=(TTree*)fInAli->Get("TreeD_75x40_100x60");
+ if(!t){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::AliDigits2Binary","AliRoot")
+ <<"No Digit Tree inside!"<<ENDLOG;
+ return 0;
+ }
+ AliSimDigits digarr, *dummy=&digarr;
+ t->GetBranch("Segment")->SetAddress(&dummy);
+ UShort_t dig;
+ Int_t time,pad,sector,row;
+ Int_t nrows=0;
+ Int_t ndigitcount=0;
+ Int_t entries = (Int_t)t->GetEntries();
+ Int_t ndigits[entries];
+ Int_t lslice,lrow;
+ for(Int_t n=0; n<t->GetEntries(); n++)
+ {
+ t->GetEvent(n);
+ fParam->AdjustSectorRow(digarr.GetID(),sector,row);
+ fTransformer->Sector2Slice(lslice,lrow,sector,row);
+ if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
+// if(fSlice != lslice) continue;
+
+ Float_t xyz[3];
+ ndigits[lrow] = 0;
+ digarr.First();
+ do {
+ time=digarr.CurrentRow();
+ pad=digarr.CurrentColumn();
+ dig = digarr.GetDigit(time,pad);
+ if(dig<=fParam->GetZeroSup()) continue;
+ if(time < fParam->GetMaxTBin()-1 && time > 0)
+ if(digarr.GetDigit(time+1,pad) <= fParam->GetZeroSup()
+ && digarr.GetDigit(time-1,pad) <= fParam->GetZeroSup())
+ continue;
+
+ fTransformer->Raw2Local(xyz,sector,row,pad,time);
+ if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ continue;
+
+ ndigits[lrow]++; //for this row only
+ ndigitcount++; //total number of digits to be published
+
+ } while (digarr.Next());
+
+ nrows++;
+ }
+ Int_t size = sizeof(AliL3DigitData)*ndigitcount
+ + nrows*sizeof(AliL3DigitRowData);
+
+ LOG(AliL3Log::kDebug,"AliL3FileHandler::AliDigits2Memory","Digits")
+ <<AliL3Log::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+
+ data=(AliL3DigitRowData*) Allocate(size);
+ nrow = (UInt_t)nrows;
+ AliL3DigitRowData *tempPt = data;
+ for(Int_t n=0; n<t->GetEntries(); n++)
+ {
+ t->GetEvent(n);
+
+ Float_t xyz[3];
+ fParam->AdjustSectorRow(digarr.GetID(),sector,row);
+ fTransformer->Sector2Slice(lslice,lrow,sector,row);
+// if(fSlice != lslice) continue;
+ if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
+ tempPt->fRow = lrow;
+ tempPt->fNDigit = ndigits[lrow];
+
+ Int_t localcount=0;
+ digarr.First();
+ do {
+ dig=digarr.CurrentDigit();
+ if (dig<=fParam->GetZeroSup()) continue;
+ time=digarr.CurrentRow();
+ pad=digarr.CurrentColumn();
+ if(time < fParam->GetMaxTBin()-1 && time > 0)
+ if(digarr.GetDigit(time-1,pad) <= fParam->GetZeroSup() &&
+ digarr.GetDigit(time+1,pad) <= fParam->GetZeroSup()) continue;
+
+ //Exclude data outside cone:
+ fTransformer->Raw2Local(xyz,sector,row,pad,time);
+ if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ continue;
+
+ if(localcount >= ndigits[lrow])
+ LOG(AliL3Log::kFatal,"AliL3FileHandler::AliDigits2Binary","Memory")
+ <<AliL3Log::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+ <<ndigits[lrow]<<ENDLOG;
+
+ tempPt->fDigitData[localcount].fCharge=dig;
+ tempPt->fDigitData[localcount].fPad=pad;
+ tempPt->fDigitData[localcount].fTime=time;
+ localcount++;
+ } while (digarr.Next());
+
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliL3DigitRowData)
+ + ndigits[lrow]*sizeof(AliL3DigitData);
+ tmp += size;
+ tempPt = (AliL3DigitRowData*)tmp;
+ }
+ savedir->cd();
+ return data;
+}
+
+///////////////////////////////////////// Point IO
+Bool_t AliL3FileHandler::AliPoints2Binary(){
+ Bool_t out = kTRUE;
+ UInt_t npoint;
+ AliL3SpacePointData *data = AliPoints2Memory(npoint);
+ out = Memory2Binary(npoint,data);
+ Free();
+ return out;
+}
+
+AliL3SpacePointData * AliL3FileHandler::AliPoints2Memory(UInt_t & npoint){
+ AliL3SpacePointData *data = 0;
+ npoint=0;
+ if(!fInAli){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::AliPoints2Memory","File")
+ <<"No Input avalible: no object TFile"<<ENDLOG;
+ return 0;
+ }
+ if(!fInAli->IsOpen()){
+ LOG(AliL3Log::kWarning,"AliL3FileHandler::AliPoints2Memory","File")
+ <<"No Input avalible: TFile not opend"<<ENDLOG;
+ return 0;
+ }
+ TDirectory *savedir = gDirectory;
+ fInAli->cd();
+
+ AliTPCClustersArray carray;
+ carray.Setup(fParam);
+ carray.SetClusterType("AliTPCcluster");
+ Bool_t clusterok = carray.ConnectTree("Segment Tree");
+ if(!clusterok) return 0;
+
+ AliTPCClustersRow ** clusterrow =
+ new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
+ Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
+ Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
+ Int_t sum=0;
+
+ Int_t lslice,lrow;
+ for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
+ AliSegmentID *s = carray.LoadEntry(i);
+ Int_t sector,row;
+ fParam->AdjustSectorRow(s->GetID(),sector,row);
+ rows[i] = row;
+ sects[i] = sector;
+ clusterrow[i] = 0;
+ fTransformer->Sector2Slice(lslice,lrow,sector,row);
+ if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
+ clusterrow[i] = carray.GetRow(sector,row);
+ if(clusterrow[i])
+ sum+=clusterrow[i]->GetArray()->GetEntriesFast();
+ }
+ UInt_t size = sum*sizeof(AliL3SpacePointData);
+
+ LOG(AliL3Log::kDebug,"AliL3FileHandler::AliPoints2Memory","File")
+ <<AliL3Log::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
+
+ data = (AliL3SpacePointData *) Allocate(size);
+ npoint = sum;
+ UInt_t n=0;
+ for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
+ if(!clusterrow[i]) continue;
+ Int_t row = rows[i];
+ Int_t sector = sects[i];
+ fTransformer->Sector2Slice(lslice,lrow,sector,row);
+ Int_t entries_in_row = clusterrow[i]->GetArray()->GetEntriesFast();
+ for(Int_t j = 0;j<entries_in_row;j++){
+ AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
+ data[n].fZ = c->GetZ();
+ data[n].fY = c->GetY();
+ data[n].fX = fParam->GetPadRowRadii(sector,row);
+ data[n].fID = n+((fSlice&0x7f)<<25)+((fPatch&0x7)<<22);//uli
+ data[n].fPadRow = lrow;
+ data[n].fXYErr = c->GetSigmaY2();
+ data[n].fZErr = c->GetSigmaZ2();
+ if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
+ n++;
+ }
+ }
+ for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
+ Int_t row = rows[i];
+ Int_t sector = sects[i];
+ if(carray.GetRow(sector,row))
+ carray.ClearRow(sector,row);
+ }
+
+ delete [] clusterrow;
+ delete [] rows;
+ delete [] sects;
+ savedir->cd();
+
+ return data;
+}
+
--- /dev/null
+#ifndef ALIL3FILEHANDLER_H
+#define ALIL3FILEHANDLER_H
+
+#include "AliTPCParam.h"
+#include "AliL3MemHandler.h"
+#include <TObject.h>
+#include <TFile.h>
+#include <stdio.h>
+class AliL3SpacePointData;
+class AliL3DigitRowData;
+class AliL3TrackSegmentData;
+class AliL3TrackArray;
+
+class AliL3FileHandler:public AliL3MemHandler{
+ private:
+ TFile *fInAli;
+ AliTPCParam *fParam;
+ AliL3Transform *fTransformer;//!
+ Bool_t SetAliInput();
+
+ FILE *fMC;//!
+
+ public:
+ AliL3FileHandler();
+ virtual ~AliL3FileHandler();
+// void Init(Int_t s,Int_t p,Int_t* row){fSlice=s;fPatch=p;fRowMin=row[0];fRowMax=row[1];}
+
+ Int_t GetRowMin(){return fRowMin;}
+ Int_t GetRowMax(){return fRowMax;}
+ Int_t GetSlice(){return fSlice;}
+ Int_t GetPatch(){return fPatch;}
+
+ Bool_t SetAliInput(char *name);
+ Bool_t SetAliInput(TFile *file);
+ void CloseAliInput();
+ Bool_t IsDigit();
+
+ Bool_t SetMCOutput(char *name);
+ Bool_t SetMCOutput(FILE *file);
+ void CloseMCOutput();
+
+ //Digit IO
+ Bool_t AliDigits2Binary();
+ AliL3DigitRowData *AliDigits2Memory(UInt_t & nrow); //Allocates Memory
+ Bool_t AliDigits2CompBinary();
+
+ //Point IO
+ Bool_t AliPoints2Binary();
+ AliL3SpacePointData *AliPoints2Memory(UInt_t & npoint);//Allocates Memory
+
+ ClassDef(AliL3FileHandler,1) // Level3
+};
+
+#endif
--- /dev/null
+
+//Author: Uli Frankenfeld
+//Last Modified: 06.12.2000
+
+#include <math.h>
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3GlobalMerger.h"
+#include "AliL3Track.h"
+#include "AliL3Transform.h"
+#include "AliL3TrackArray.h"
+//_____________________________________________________________
+//
+// The L3 Slice merger
+//
+
+ClassImp(AliL3GlobalMerger)
+
+AliL3GlobalMerger::AliL3GlobalMerger(){
+ //Default constructor
+ Is2Global(kTRUE);
+ SetParameter(2,2,0.001,0.05,0.1);
+}
+
+
+AliL3GlobalMerger::AliL3GlobalMerger(Int_t first,Int_t last):AliL3Merger(last-first+1){
+ //Constructor.
+ fNSlices = last-first+1;
+ fFirst = first;
+ fLast = last;
+ Is2Global(kTRUE);
+ SetParameter(2,2,0.001,0.1,0.4);
+}
+
+AliL3GlobalMerger::~AliL3GlobalMerger(){
+ //Destructor
+}
+
+void AliL3GlobalMerger::InitSlice(Int_t slice){
+ //
+ // Select Sector The following FillTracks call will
+ // fill this Sector
+ //
+ fSlice = slice;
+ fCurrentTracks = fSlice - fFirst;
+}
+
+void AliL3GlobalMerger::SlowMerge(){
+ void* ntuple=GetNtuple();
+ AliL3Track *track[2];
+ AliL3TrackArray *tout = GetOutTracks();
+ if(fNSlices<2){
+ LOG(AliL3Log::kWarning,"AliL3GlobalMerger::SlowMerge","Slice Number")
+ <<"Need more than one Slice!"<<ENDLOG;
+ return;
+ }
+ for(Int_t i=0; i<fNSlices-1; i++){
+ Int_t slice = fFirst + i;
+ AliL3TrackArray *ttt0=GetInTracks(i);
+ AliL3TrackArray *ttt1=GetInTracks(i+1);
+ Float_t angle = PI/18.; //10 degrees -> the border of the slices
+ fTransformer->Local2GlobalAngle(&angle,slice);
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++){
+ AliL3Track *track0=ttt0->GetTrack(s0);
+ track0->CalculateHelix();
+ track0->CalculateEdgePoint(angle);
+ if(!track0->IsPoint()) ttt0->Remove(s0);
+ }
+// ttt0->Compress();
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++){
+ AliL3Track *track1=ttt1->GetTrack(s1);
+ track1->CalculateHelix();
+ track1->CalculateEdgePoint(angle);
+ if(!track1->IsPoint()) ttt1->Remove(s1);
+ }
+// ttt1->Compress();
+ Bool_t merge = kTRUE;
+ while(merge){
+ Int_t min0=-1,min1=-1;
+ Double_t min=10;
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++){
+ AliL3Track *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ if(!track0->CalculateEdgePoint(angle)) continue;
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++){
+ AliL3Track *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ if(!track1->CalculateEdgePoint(angle)) continue;
+ Double_t diff = TrackDiff(track0,track1);
+ if(diff>=0&&diff<min){
+ min=diff;
+ min0=s0;
+ min1=s1;
+ }
+ }
+ }
+ if(min0>=0&&min1>=0){
+ AliL3Track *track0=ttt0->GetTrack(min0);
+ AliL3Track *track1=ttt1->GetTrack(min1);
+ track[0] = track0;
+ track[1] = track1;
+ SortGlobalTracks(track,2);
+ MultiMerge(tout,track,2);
+ track0->CalculateEdgePoint(angle);
+ track1->CalculateEdgePoint(angle);
+ track0->CalculateReferencePoint(angle);
+ track1->CalculateReferencePoint(angle);
+ PrintDiff(track0,track1);
+ FillNtuple(ntuple,track0,track1);
+ ttt0->Remove(min0);
+ ttt1->Remove(min1);
+// ttt0->Compress();
+// ttt1->Compress();
+ }
+ else merge = kFALSE;
+ }
+ LOG(AliL3Log::kInformational,"AliL3GlobalMerger::SlowMerge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "<<tout->GetNTracks()<<ENDLOG;
+ }
+ WriteNtuple("ntuple_s.root",ntuple);
+}
+
+void AliL3GlobalMerger::Merge(){
+ AliL3Track *track[2];
+ AliL3TrackArray *tout = GetOutTracks();
+ if(fNSlices<2){
+ LOG(AliL3Log::kWarning,"AliL3GlobalMerger::Merge","Slice Number")
+ <<"Need more than one Slice!"<<ENDLOG;
+ return;
+ }
+ for(Int_t i=0; i<fNSlices-1; i++){
+ Int_t slice = fFirst + i;
+ AliL3TrackArray *ttt0=GetInTracks(i);
+ AliL3TrackArray *ttt1=GetInTracks(i+1);
+ Float_t angle = PI/18.; //10 degrees -> the border of the slices
+ fTransformer->Local2GlobalAngle(&angle,slice);
+ if(i==0)
+ ttt0->QSort();
+ ttt1->QSort();
+ Bool_t *ismatched0 = new Bool_t[ttt0->GetNTracks()];
+ Bool_t *ismatched1 = new Bool_t[ttt1->GetNTracks()];
+ Int_t n0=0,n1=0;
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++){
+ ismatched0[s0]=kFALSE;
+ AliL3Track *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ track0->CalculateHelix();
+ track0->CalculateEdgePoint(angle);
+ if(track0->IsPoint()) {n0++;track0->CalculateReferencePoint(angle);}
+ }
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++){
+ ismatched1[s1]=kFALSE;
+ AliL3Track *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ track1->CalculateHelix();
+ track1->CalculateEdgePoint(angle);
+ if(track1->IsPoint()) {n1++;track1->CalculateReferencePoint(angle);}
+ }
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++){
+ AliL3Track *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ if(!track0->IsPoint()) continue;
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++){
+ if(ismatched1[s1]) continue;
+ AliL3Track *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ if(!track1->IsPoint()) continue;
+ if(IsRTrack(track0,track1)){
+ track[0] = track0;
+ track[1] = track1;
+ SortGlobalTracks(track,2);
+ MultiMerge(tout,track,2);
+ ismatched0[s0]=kTRUE;
+ ismatched1[s1]=kTRUE;
+ ttt0->Remove(s0);
+ ttt1->Remove(s1);
+ }
+ }
+ }
+ LOG(AliL3Log::kInformational,"AliL3GlobalMerger::Merge","Result")
+ <<AliL3Log::kDec<<"slice0: "<<n0<<" slice1: "<<n1
+ <<" Merged Tracks: "<<tout->GetNTracks()<<ENDLOG;
+ }
+}
--- /dev/null
+#ifndef ALIL3_GLOBALMERGER_H
+#define ALIL3_GLOBALMERGER_H
+
+#ifndef __CINT__
+#include "AliL3Merger.h"
+#endif
+
+class AliL3GlobalMerger : public AliL3Merger{
+
+ private:
+ Int_t fNSlices;
+ Int_t fFirst;
+ Int_t fLast;
+
+ public:
+ AliL3GlobalMerger();
+ AliL3GlobalMerger(Int_t first,Int_t last);
+ virtual ~AliL3GlobalMerger();
+
+ void InitSlice(Int_t slice);
+ void SlowMerge();
+ void Merge(); //Loop over tracks from different sectors
+
+ ClassDef(AliL3GlobalMerger,1)
+};
+
+#endif
--- /dev/null
+
+#include <math.h>
+
+#include "AliL3Transform.h"
+#include "AliL3Defs.h"
+#include "AliL3HoughTrack.h"
+
+ClassImp(AliL3HoughTrack)
+
+
+AliL3HoughTrack::AliL3HoughTrack()
+{
+ //Constructor
+
+ fWeight = 0;
+ fMinDist=0;
+ fTransform = new AliL3Transform();
+ fDLine = 0;
+ fPsiLine = 0;
+ fIsHelix = true;
+}
+
+
+AliL3HoughTrack::~AliL3HoughTrack()
+{
+ //Destructor
+ if(fTransform)
+ delete fTransform;
+}
+
+void AliL3HoughTrack::Set(AliL3Track *track)
+{
+
+ AliL3HoughTrack *tpt = (AliL3HoughTrack*)track;
+
+ fWeight = tpt->GetWeight();
+ fDLine = tpt->GetDLine();
+ fPsiLine = tpt->GetPsiLine();
+ SetNHits(tpt->GetWeight());
+ SetRowRange(tpt->GetFirstRow(),tpt->GetLastRow());
+ fIsHelix = false;
+
+
+}
+
+void AliL3HoughTrack::SetTrackParameters(Double_t kappa,Double_t phi,Int_t weight)
+{
+
+ fWeight = weight;
+ fMinDist = 100000;
+ SetKappa(kappa);
+ SetPhi0(phi);
+ Double_t pt = fabs(BFACT*bField/kappa);
+ SetPt(pt);
+ Double_t radius = 1/fabs(kappa);
+ SetRadius(radius);
+
+ //set nhits for sorting.
+ SetNHits(weight);
+
+ SetCharge(copysign(1,kappa));
+ Double_t charge = -1.*kappa;
+ Double_t trackPhi0 = GetPhi0() + charge*0.5*Pi/fabs(charge);
+
+ //The first point on track is origo:
+ Double_t x0=0;
+ Double_t y0=0;
+
+ Double_t xc = x0 - GetRadius() * cos(trackPhi0) ;
+ Double_t yc = y0 - GetRadius() * sin(trackPhi0) ;
+ SetCenterX(xc);
+ SetCenterY(yc);
+ fIsHelix = true;
+}
+
+void AliL3HoughTrack::SetLineParameters(Double_t psi,Double_t D,Int_t weight,Int_t *rowrange,Int_t ref_row)
+{
+ //Initialize a track piece, not yet a track
+ //Used in case of straight line transformation
+
+ //Transform line parameters to coordinate system of slice:
+
+ D = D + fTransform->Row2X(ref_row)*cos(psi);
+
+ fDLine = D;
+ fPsiLine = psi;
+ fWeight = weight;
+ SetNHits(weight);
+ SetRowRange(rowrange[0],rowrange[1]);
+ fIsHelix = false;
+
+}
+
+void AliL3HoughTrack::SetBestMCid(Int_t mcid,Double_t min_dist)
+{
+
+ if(min_dist < fMinDist)
+ {
+ fMinDist = min_dist;
+ SetMCid(mcid);
+ }
+
+}
+
+void AliL3HoughTrack::GetLineCrossingPoint(Int_t padrow,Double_t *xy)
+{
+
+
+ if(fIsHelix)
+ {
+ printf("AliL3HoughTrack::GetLineCrossingPoint : Track is not a line\n");
+ return;
+ }
+
+ Double_t xhit = fTransform->Row2X(padrow);
+ Double_t a = -1/tan(fPsiLine);
+ Double_t b = fDLine/sin(fPsiLine);
+
+ Double_t yhit = a*xhit + b;
+ xy[0] = xhit;
+ xy[1] = yhit;
+
+}
+
+Double_t AliL3HoughTrack::GetCrossingAngle(Int_t padrow)
+{
+ //Calculate the crossing angle between track and given padrow.
+
+ if(!fIsHelix)
+ {
+ printf("AliL3HoughTrack::GetCrossingAngle : Track is not a helix\n");
+ return 0;
+ }
+
+ if(!IsLocal())
+ {
+ printf("Track is not given in local coordinates\n");
+ return 0;
+ }
+
+ Float_t xyz[3];
+ if(!GetCrossingPoint(padrow,xyz))
+ printf("AliL3HoughTrack::GetCrossingPoint : Track does not cross line!!\n");
+
+
+ //Convert center of curvature to local coordinates:
+ //Float_t xyz_coc[3] = {GetCenterX(),GetCenterY(),0};
+ //fTransform->Global2Local(xyz_coc,slice);
+
+ //Take the dot product of the tangent vector of the track, and
+ //vector perpendicular to the padrow.
+
+ Double_t tangent[2];
+ //tangent[1] = (xyz[0] - xyz_coc[0])/GetRadius();
+ //tangent[0] = -1.*(xyz[1] - xyz_coc[1])/GetRadius();
+ tangent[1] = (xyz[0] - GetCenterX())/GetRadius();
+ tangent[0] = -1.*(xyz[1] - GetCenterY())/GetRadius();
+
+ Double_t perp_padrow[2] = {1,0}; //locally in slice
+
+ Double_t cos_beta = fabs(tangent[0]*perp_padrow[0] + tangent[1]*perp_padrow[1]);
+ return acos(cos_beta);
+
+}
+
+Bool_t AliL3HoughTrack::GetCrossingPoint(Int_t padrow,Float_t *xyz)
+{
+ //Assumes the track is given in local coordinates
+
+ if(!fIsHelix)
+ {
+ printf("AliL3HoughTrack::GetCrossingPoint : Track is not a helix\n");
+ return 0;
+ }
+
+
+ if(!IsLocal())
+ {
+ printf("GetCrossingPoint: Track is given on global coordinates\n");
+ return false;
+ }
+
+ Double_t xHit = fTransform->Row2X(padrow);
+
+ //xyz[0] = fTransform->Row2X(padrow);
+ xyz[0] = xHit;
+ Double_t aa = (xHit - GetCenterX())*(xHit - GetCenterX());
+ Double_t r2 = GetRadius()*GetRadius();
+ if(aa > r2)
+ return false;
+
+ Double_t aa2 = sqrt(r2 - aa);
+ Double_t y1 = GetCenterY() + aa2;
+ Double_t y2 = GetCenterY() - aa2;
+ xyz[1] = y1;
+ if(fabs(y2) < fabs(y1)) xyz[1] = y2;
+ xyz[2] = 0; //only consider transverse plane
+
+ return true;
+}
+
+
+Bool_t AliL3HoughTrack::GetCrossingPoint(Int_t slice,Int_t padrow,Float_t *xyz)
+{
+ //Calculate the crossing point in transverse plane of this track and given
+ //padrow (y = a*x + b). Point is given in local coordinates in slice.
+ //Assumes the track is given in global coordinates.
+
+ if(!fIsHelix)
+ {
+ printf("AliL3HoughTrack::GetCrossingPoint : Track is not a helix\n");
+ return 0;
+ }
+
+
+ if(IsLocal())
+ {
+ printf("GetCrossingPoint: Track is given in local coordintes!!!\n");
+ return false;
+ }
+
+ Double_t padrowradii = fTransform->Row2X(padrow);
+
+
+ Float_t rotation_angle = (slice*20)*ToRad;
+
+ Float_t cs,sn;
+ cs = cos(rotation_angle);
+ sn = sin(rotation_angle);
+
+ Double_t a = -1.*cs/sn;
+ Double_t b = padrowradii/sn;
+
+ Double_t ycPrime = GetCenterY() - b ;
+ Double_t aa = ( 1. + a * a ) ;
+ Double_t bb = -2. * ( GetCenterX() + a * ycPrime ) ;
+ Double_t cc = ( GetCenterX() * GetCenterX() + ycPrime * ycPrime - GetRadius() * GetRadius() ) ;
+
+ Double_t racine = bb * bb - 4. * aa * cc ;
+ if ( racine < 0 ) return false ;
+ Double_t rootRacine = sqrt(racine) ;
+
+ Double_t oneOverA = 1./aa;
+//
+// First solution
+//
+ Double_t x1 = 0.5 * oneOverA * ( -1. * bb + rootRacine ) ;
+ Double_t y1 = a * x1 + b ;
+ Double_t r1 = sqrt(x1*x1+y1*y1);
+//
+// Second solution
+//
+ Double_t x2 = 0.5 * oneOverA * ( -1. * bb - rootRacine ) ;
+ Double_t y2 = a * x2 + b ;
+ Double_t r2 = sqrt(x2*x2+y2*y2);
+//
+// Choose close to (0,0)
+//
+ Double_t xHit ;
+ Double_t yHit ;
+ if ( r1 < r2 ) {
+ xHit = x1 ;
+ yHit = y1 ;
+ }
+ else {
+ xHit = x2 ;
+ yHit = y2 ;
+ }
+
+ xyz[0] = xHit;
+ xyz[1] = yHit;
+ xyz[2] = 0;
+
+ fTransform->Global2Local(xyz,slice);
+
+ return true;
+}
--- /dev/null
+#ifndef ALIL3_HOUGH_Track
+#define ALIL3_HOUGH_Track
+
+#include "AliL3Track.h"
+
+class AliL3Transform;
+
+class AliL3HoughTrack : public AliL3Track {
+
+ private:
+
+ AliL3Transform *fTransform; //!
+ Double_t fMinDist;
+ Int_t fWeight;
+
+ Double_t fDLine;
+ Double_t fPsiLine;
+
+ Bool_t fIsHelix;
+
+ public:
+ AliL3HoughTrack();
+ virtual ~AliL3HoughTrack();
+
+ void Set(AliL3Track *track);
+
+ void SetTrackParameters(Double_t kappa,Double_t phi,Int_t weight);
+ void SetLineParameters(Double_t psi,Double_t D,Int_t weight,Int_t *rowrange,Int_t ref_row);
+ Int_t GetWeight() {return fWeight;}
+ Double_t GetPsiLine() {return fPsiLine;}
+ Double_t GetDLine() {return fDLine;}
+
+ void GetLineCrossingPoint(Int_t padrow,Double_t *xy);
+ Double_t GetCrossingAngle(Int_t padrow);
+ Bool_t GetCrossingPoint(Int_t slice,Int_t padrow,Float_t *xyz);
+ Bool_t GetCrossingPoint(Int_t padrow,Float_t *xyz);
+
+ void SetBestMCid(Int_t f,Double_t min_dist);
+ void SetDLine(Double_t f) {fDLine=f;}
+ void SetPsiLine(Double_t f) {fPsiLine=f;}
+
+ ClassDef(AliL3HoughTrack,1)
+
+};
+
+#endif
--- /dev/null
+
+//Author: Uli Frankenfeld
+//Last Modified: 06.12.2000
+
+#include <math.h>
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3InterMerger.h"
+#include "AliL3Track.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3Transform.h"
+#include "AliL3TrackArray.h"
+
+//_____________________________________________________________
+//
+// The L3 track segment merger
+//
+
+ClassImp(AliL3InterMerger)
+
+AliL3InterMerger::AliL3InterMerger():AliL3Merger(1){
+ //Default constructor
+ Is2Global(kFALSE);
+ SetParameter(2,2,.3,.3,.3);
+ fRowMax = fRowMin = 0;
+}
+
+
+AliL3InterMerger::~AliL3InterMerger(){
+ //Destructor
+
+}
+
+void AliL3InterMerger::SlowMerge(){
+ Int_t nrow= fRowMax-fRowMin+1;
+ void *ntuple=GetNtuple();
+ AliL3TrackArray * tracks = GetInTracks(0);
+ const Int_t kNIn =tracks->GetNTracks();
+ AliL3Track *tr[2];
+ Bool_t merge = kTRUE;
+ for(Int_t in=0;in<kNIn;in++)
+ tracks->GetCheckedTrack(in)->CalculateHelix();
+ while(merge){
+ Int_t inmin=-1,outmin=-1;
+ Double_t min=10;
+ for(Int_t out=0;out<kNIn;out++){
+ AliL3Track *outertrack=tracks->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ if(in==out) continue;
+ AliL3Track *innertrack=tracks->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+ Double_t diff = TrackDiff(innertrack,outertrack);
+
+ if(diff>=0&&diff<min){
+ min=diff;
+ inmin=in;
+ outmin=out;
+ }
+ }
+ }
+ if(inmin>=0&&outmin>=0){
+ AliL3Track *outertrack=tracks->GetTrack(outmin);
+ AliL3Track *innertrack=tracks->GetTrack(inmin);
+ tr[0]=innertrack;
+ tr[1]=outertrack;
+ SortTracks(tr,2);
+ MultiMerge(tracks,tr,2);
+ outertrack->CalculatePoint(tr[0]->GetLastPointX());
+ innertrack->CalculatePoint(tr[0]->GetLastPointX());
+ PrintDiff(innertrack,outertrack);
+ FillNtuple(ntuple,innertrack,outertrack);
+ tracks->Remove(outmin);
+ tracks->Remove(inmin);
+ }
+ else merge = kFALSE;
+ }
+ LOG(AliL3Log::kInformational,"AliL3InterMerger::SlowMerge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "<<tracks->GetNTracks()-kNIn<<ENDLOG;
+
+ char name[256];
+ sprintf(name,"ntuple_i_%d.root",fPatch);
+ WriteNtuple(name,ntuple);
+}
+
+void AliL3InterMerger::MMerge(){
+ while(Merge());
+ GetOutTracks()->AddTracks(GetInTracks(0));
+}
+
+Int_t AliL3InterMerger::Merge(){
+ Int_t nrow= fRowMax-fRowMin+1;
+ Double_t xval =fTransformer->Row2X((fRowMax+fRowMin)/2);
+ AliL3TrackArray * tracks = GetInTracks(0);
+ const Int_t kNIn =tracks->GetNTracks();
+ AliL3Track *tr[2];
+ for(Int_t in=0;in<kNIn;in++){
+ AliL3Track *t = tracks->GetCheckedTrack(in);
+ if(t){
+ t->CalculateHelix();
+ t->CalculatePoint(xval);
+ }
+ }
+ for(Int_t out=0;out<kNIn;out++){
+ AliL3Track *outertrack=tracks->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ if(in==out) continue;
+ AliL3Track *innertrack=tracks->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+ if(IsTrack(innertrack,outertrack)){
+ tr[0]=innertrack;
+ tr[1]=outertrack;
+ SortTracks(tr,2);
+ if(tr[0]->GetLastPointX()<tr[1]->GetFirstPointX()){
+ MultiMerge(tracks,tr,2);
+ tracks->Remove(out);
+ tracks->Remove(in);
+ break;
+ }
+ }
+ }
+ }
+ Int_t nmerged = tracks->GetNTracks()-kNIn;
+ LOG(AliL3Log::kInformational,"AliL3InterMerger::Merge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "<<nmerged<<ENDLOG;
+ //add in tracks
+// GetOutTracks()->AddTracks(GetInTracks(0));
+
+ return nmerged;
+}
+
+
--- /dev/null
+#ifndef ALIL3INTERMERGER_H
+#define ALIL3INTERMERGER_H
+
+#ifndef __CINT__
+#include "AliL3Merger.h"
+#endif
+
+class AliL3InterMerger : public AliL3Merger {
+
+ private:
+ Int_t fPatch;
+ Int_t fRowMin;
+ Int_t fRowMax;
+ public:
+ AliL3InterMerger();
+ virtual ~AliL3InterMerger();
+
+ void Init(Int_t *row,Int_t p){fRowMin=row[0];fRowMax=row[1];fPatch=p;}
+ void SlowMerge();
+ Int_t Merge();
+ void MMerge(); //Loop over tracks from different subsectors
+
+ ClassDef(AliL3InterMerger,1)
+};
+
+#endif
--- /dev/null
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliL3Benchmark;
+#pragma link C++ class AliL3DigitRowData;
+#pragma link C++ class AliL3DigitData;
+#pragma link C++ class AliL3SpacePointData;
+#pragma link C++ class AliL3ConfMapper;
+#pragma link C++ class AliL3ConfMapPoint;
+#pragma link C++ class AliL3Vertex;
+#pragma link C++ class AliL3VertexFinder;
+#pragma link C++ class AliL3VertexArray;
+#pragma link C++ class AliL3Track;
+#pragma link C++ class AliL3HoughTrack;
+#pragma link C++ class AliL3ConfMapTrack;
+#pragma link C++ class AliL3ConfMapFit;
+#pragma link C++ class AliL3Transform;
+#pragma link C++ class AliL3Merger;
+#pragma link C++ class AliL3TrackMerger;
+#pragma link C++ class AliL3GlobalMerger;
+#pragma link C++ class AliL3InterMerger;
+#pragma link C++ class AliLevel3;
+#pragma link C++ class AliL3ClustFinder;
+#pragma link C++ class AliL3TrackArray;
+#pragma link C++ class AliL3Logger;
+#pragma link C++ class AliL3MemHandler;
+#pragma link C++ class AliL3FileHandler;
+#pragma link C++ class AliL3Evaluate;
+#pragma link C++ class AliL3Display;
+
+
+#endif
+
--- /dev/null
+#include "AliL3Logging.h"
+#ifdef use_logging
+#include "AliL3Logger.h"
+#include <fstream.h>
+
+int AliL3Logger::kAll= AliL3Log::kAll;
+int AliL3Logger::kDebug = AliL3Log::kDebug;
+int AliL3Logger::kInformational = AliL3Log::kInformational;
+int AliL3Logger::kWarning = AliL3Log::kWarning;
+int AliL3Logger::kError = AliL3Log::kError;
+int AliL3Logger::kFatal = AliL3Log::kFatal;
+
+AliL3Logger::AliL3Logger(){
+ gLogLevel=AliL3Log::kAll;
+ dn = so = se = sm =0;
+}
+AliL3Logger::~AliL3Logger(){
+ if(dn) {gLog.DelServer(dn);delete dn;}
+ if(so) {gLog.DelServer(so);delete so;}
+ if(se) {gLog.DelServer(se);delete se;}
+ if(sm) {gLog.DelServer(sm);delete sm;}
+ if(of) {of->close();delete of;}
+}
+void AliL3Logger::Set(int l){gLogLevel |=l;}
+void AliL3Logger::UnSet(int l){gLogLevel &=(~l);}
+void AliL3Logger::UseDevNull(){
+ if(dn) return;
+ dn = new AliL3DevNullLogServer();
+ gLog.AddServer(dn);
+}
+void AliL3Logger::UseStdout(){
+ if(so)return;
+ so = new AliL3StdoutLogServer();
+ gLog.AddServer(so);
+}
+void AliL3Logger::UseStderr(){
+ if(se) return;
+ se = new AliL3StderrLogServer();
+ gLog.AddServer(se);
+}
+
+void AliL3Logger::UseStream(char *name){
+ if(sm) return;
+// static ofstream of;
+ if(of) of->close();
+ delete of;
+ of =0;
+ of = new ofstream();
+ of->open(name);
+ sm = new AliL3StreamLogServer(*of);
+ gLog.AddServer(sm);
+}
+void AliL3Logger::NotUseDevNull(){
+ if(dn) {gLog.DelServer(dn);delete dn;dn=0;}
+}
+void AliL3Logger::NotUseStdout(){
+ if(so) {gLog.DelServer(so);delete so;so=0;}
+}
+void AliL3Logger::NotUseStderr(){
+ if(se) {gLog.DelServer(se);delete se;se=0;}
+}
+
+void AliL3Logger::NotUseStream(){
+ if(sm) {gLog.DelServer(sm);delete sm;sm=0;}
+ if(of) {of->close();delete of;of=0;}
+}
+
+#endif
+
--- /dev/null
+class MLUCLogServer;
+class ofstream;
+
+class AliL3Logger{
+ public:
+ static int kAll;
+ static int kDebug;
+ static int kInformational;
+ static int kWarning;
+ static int kError;
+ static int kFatal;
+ AliL3Logger();
+ ~AliL3Logger();
+ void Set(int l);
+ void UnSet(int l);
+ void UseDevNull();
+ void UseStdout();
+ void UseStderr();
+ void UseStream(char *name="AliLevel3.log");
+ void NotUseDevNull();
+ void NotUseStdout();
+ void NotUseStderr();
+ void NotUseStream();
+ private:
+ MLUCLogServer *dn;
+ MLUCLogServer *so;
+ MLUCLogServer *se;
+ MLUCLogServer *sm;
+ ofstream *of;
+};
+
+
--- /dev/null
+#ifndef ALIL3LOGGING_H
+#define ALIL3LOGGING_H
+
+#define use_logging
+
+#ifdef use_logging
+
+#include "/heim/franken/lib/MLUC/include/MLUCLog.hpp"
+#include "/heim/franken/lib/MLUC/include/MLUCLogServer.hpp"
+
+typedef MLUCLog AliL3Log;
+typedef MLUCLogServer AliL3LogServer;
+typedef MLUCDevNullLogServer AliL3DevNullLogServer;
+typedef MLUCStdoutLogServer AliL3StdoutLogServer;
+typedef MLUCStderrLogServer AliL3StderrLogServer;
+typedef MLUCStreamLogServer AliL3StreamLogServer;
+
+#else
+#include <iostream.h>
+class AliL3Log{
+ public:
+ enum TLogLevel { kNone = 0, kDebug= 0x01, kInformational = 0x02, kWarning = 0x04, kError = 0x08 , kFatal = 0x10, kPrimary = 0x80, kAll = 0x9F };
+ enum TLogCmd { kEnd, kPrec, kHex, kDec };
+};
+
+#define LOG( lvl, origin, keyword ) cerr
+
+#define ENDLOG endl
+
+#endif
+#endif // ALIL3LOGGING_H
+
+
--- /dev/null
+//Author: Uli Frankenfeld
+//Last Modified: 17.12.2000
+
+#include <math.h>
+#include <time.h>
+#include <iostream.h>
+#include <stdio.h>
+
+#include "AliL3MemHandler.h"
+#include "AliL3Transform.h"
+#include "AliL3Logging.h"
+
+#include "AliL3DigitData.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3TrackArray.h"
+//_____________________________________________________________
+//
+// The L3 Binary File handler
+//
+
+ClassImp(AliL3MemHandler)
+
+AliL3MemHandler::AliL3MemHandler(){
+ //Default constructor
+ fPt = 0;
+ fSize =0;
+ fInBinary = 0;
+ fOutBinary = 0;
+ fNRandom = 0;
+ Int_t r[2]={0,0};
+ Init(0,0,r);
+ IsRandom = kFALSE;
+ fDigits = 0;
+ fDPt =0;
+ fNGenerate = 0;
+ fNUsed = 0;
+ fNDigits = 0;
+
+ Int_t row[2] = {0,173};
+ Init(0,0,row);
+ ResetROI();
+}
+
+
+AliL3MemHandler::~AliL3MemHandler(){
+ //Destructor
+ if(fPt) delete[] fPt;
+ if(fDigits) delete [] fDigits;
+ if(fDPt) delete [] fDPt;
+}
+
+void AliL3MemHandler::ResetROI(){
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ fEtaMinTimeBin[i] = 0;
+ fEtaMaxTimeBin[i] = 445;
+ }
+}
+
+
+void AliL3MemHandler::SetROI(Float_t *eta,Int_t *slice){
+ if(eta[1]==0)
+ {
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::SetROI","Eta Values")
+ <<"Bad ROI parameters. IDIOT! "<<ENDLOG;
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ fEtaMinTimeBin[i]=0;
+ fEtaMaxTimeBin[i]=0;
+ }
+ return;
+ }
+
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ Int_t sector,row;
+ Float_t xyz[3];
+
+ Float_t thetamax = 2*atan(exp(-1.*eta[1]));
+
+ xyz[0] = fTransformer->Row2X(i);
+ xyz[1]=0;
+ xyz[2] = xyz[0]/tan(thetamax);
+ fTransformer->Slice2Sector(fSlice,i,sector,row);
+ fTransformer->Local2Raw(xyz,sector,row);
+
+ fEtaMinTimeBin[i] = (Int_t)xyz[2];
+
+ if(eta[0]==0)
+ fEtaMaxTimeBin[i] = 445;
+ else
+ {
+ Float_t thetamin = 2*atan(exp(-1.*eta[0]));
+ xyz[0] = fTransformer->Row2X(i);
+ xyz[1] = fTransformer->GetMaxY(i);
+ Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
+ xyz[2] = radii/tan(thetamin);
+ fTransformer->Local2Raw(xyz,sector,row);
+ fEtaMaxTimeBin[i] = (Int_t)xyz[2];
+ }
+ }
+
+}
+
+Bool_t AliL3MemHandler::SetBinaryInput(char *name){
+ fInBinary = fopen(name,"r");
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryInput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::SetBinaryInput(FILE *file){
+ fInBinary = file;
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryInput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+void AliL3MemHandler::CloseBinaryInput(){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CloseBinaryInput","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ fclose(fInBinary);
+ fInBinary =0;
+}
+
+Bool_t AliL3MemHandler::SetBinaryOutput(char *name){
+ fOutBinary = fopen(name,"w");
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::SetBinaryOutput(FILE *file){
+ fOutBinary = file;
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+void AliL3MemHandler::CloseBinaryOutput(){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CloseBinaryOutPut","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ fclose(fOutBinary);
+ fOutBinary =0;
+}
+
+
+UInt_t AliL3MemHandler::GetFileSize(){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::GetFileSize","File")
+ <<"No Input File"<<ENDLOG;
+ return 0;
+ }
+ fseek(fInBinary,0,SEEK_END);
+ UInt_t size = (UInt_t) ftell(fInBinary);
+ rewind(fInBinary);
+ return size;
+}
+
+Byte_t *AliL3MemHandler::Allocate(){
+ return Allocate(GetFileSize());
+}
+
+Byte_t *AliL3MemHandler::Allocate(AliL3TrackArray *array){
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Allocate","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ return Allocate(array->GetOutSize());
+}
+
+Byte_t *AliL3MemHandler::Allocate(UInt_t size){
+ if(fPt){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Allocate","Memory")
+ <<"Delete Memory"<<ENDLOG;
+ Free();
+ }
+ fPt = new Byte_t[size];
+ fSize = size;
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Allocate","Memory")
+ <<AliL3Log::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
+ return fPt;
+}
+
+void AliL3MemHandler::Free(){
+ if(!fPt){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Free","Memory")
+ <<"No Memory allocated - can't Free"<<ENDLOG;
+ return;
+ }
+ delete[] fPt;
+ fPt = 0;
+ fSize =0;
+}
+
+///////////////////////////////////////// Random
+void AliL3MemHandler::SetRandomSeed(){
+ time_t *tp=0;
+ SetRandomSeed(time(tp));
+}
+
+void AliL3MemHandler::SetRandomCluster(Int_t maxnumber){
+ IsRandom = kTRUE;
+ fNRandom = maxnumber;
+ fNDigits = 0;
+ if(fDigits) delete [] fDigits;
+ fDigits = new AliL3RandomDigitData[fNRandom*9];
+ if(fDPt) delete [] fDPt;
+ fDPt = (AliL3RandomDigitData **)new Int_t[fNRandom*9];
+}
+
+void AliL3MemHandler::QSort(AliL3RandomDigitData **a, Int_t first, Int_t last){
+
+ // Sort array of AliL3RandomDigitData pointers using a quicksort algorithm.
+ // Uses CompareDigits() to compare objects.
+ // Thanks to Root!
+
+ static AliL3RandomDigitData *tmp;
+ static int i; // "static" to save stack space
+ int j;
+
+ while (last - first > 1) {
+ i = first;
+ j = last;
+ for (;;) {
+ while (++i < last && CompareDigits(a[i], a[first]) < 0)
+ ;
+ while (--j > first && CompareDigits(a[j], a[first]) > 0)
+ ;
+ if (i >= j)
+ break;
+
+ tmp = a[i];
+ a[i] = a[j];
+ a[j] = tmp;
+ }
+ if (j == first) {
+ ++first;
+ continue;
+ }
+ tmp = a[first];
+ a[first] = a[j];
+ a[j] = tmp;
+ if (j - first < last - (j + 1)) {
+ QSort(a, first, j);
+ first = j + 1; // QSort(j + 1, last);
+ } else {
+ QSort(a, j + 1, last);
+ last = j; // QSort(first, j);
+ }
+ }
+}
+
+UInt_t AliL3MemHandler::GetRandomSize(){
+ Int_t nrandom = 0;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t npad=fTransformer->GetNPads(r);
+ nrandom += Int_t (fNGenerate * ((Double_t) npad/141.));
+ }
+ return 9 * nrandom * sizeof(AliL3DigitData);
+}
+
+void AliL3MemHandler::Generate(Int_t row){
+ if(!IsRandom) return;
+ ResetRandom();
+ fNDigits = 0;
+ Int_t npad=fTransformer->GetNPads(row);
+ Int_t ntime = fEtaMaxTimeBin[row] - fEtaMinTimeBin[row];
+ Int_t nrandom = Int_t (fNGenerate * ((Double_t) npad/141.) *
+ (Double_t) ntime/(Double_t) fTransformer->GetNTimeBins() );
+
+ for(Int_t n=0;n<nrandom;n++){
+ Int_t pad = (int)((float)rand()/RAND_MAX*npad);
+ Int_t time =(int)((float)rand()/RAND_MAX*ntime+fEtaMinTimeBin[row] );
+ Int_t charge = (int)((float)rand()/RAND_MAX*1023);
+ DigitizePoint(row,pad,time,charge);
+ }
+ QSort(fDPt,0,fNDigits);
+// for(Int_t d=0;d<fNDigits;d++)
+// fprintf(stderr,"%d %d %d %d\n",fDPt[d]->fRow,fDPt[d]->fPad,
+// fDPt[d]->fTime,fDPt[d]->fCharge);
+}
+
+
+void AliL3MemHandler::DigitizePoint(Int_t row, Int_t pad,
+ Int_t time,Int_t charge){
+ for(Int_t j=-1;j<2;j++){
+ for(Int_t k=-1;k<2;k++){
+ Int_t dcharge = charge;
+ if(j) dcharge /=2;
+ if(k) dcharge /=2;
+ if(dcharge<10) continue;
+ Int_t dpad = j + pad;
+ Int_t dtime = k + time;
+
+ if(dpad<0||dpad>=fTransformer->GetNPads(row)) continue;
+ if(dtime<0||dtime>=fTransformer->GetNTimeBins()) continue;
+
+ fDigits[fNDigits].fCharge = dcharge;
+ fDigits[fNDigits].fRow = row;
+ fDigits[fNDigits].fPad = dpad;
+ fDigits[fNDigits].fTime = dtime;
+ fDPt[fNDigits] = &fDigits[fNDigits];
+ fNDigits++;
+ }
+ }
+}
+
+///////////////////////////////////////// Digit IO
+Bool_t AliL3MemHandler::Memory2Binary(UInt_t nrow,AliL3DigitRowData *data){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ AliL3DigitRowData *row_pt = data;
+ Int_t outsize = 0;
+ for(UInt_t i=0;i<nrow;i++){
+ Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit
+ + sizeof(AliL3DigitRowData);
+ outsize += size;
+ fwrite(row_pt,size,1,fOutBinary);
+ Byte_t *byte_pt =(Byte_t *) row_pt;
+ byte_pt += size;
+ row_pt = (AliL3DigitRowData *) byte_pt;
+ }
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Memory2Binary","Memory")
+ <<AliL3Log::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+ <<nrow<<" Rows)"<<ENDLOG;
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Binary2Memory(UInt_t & nrow,AliL3DigitRowData *data){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ rewind(fInBinary);
+ AliL3DigitRowData *row_pt = data;
+ UInt_t rowcount = 0;
+ Int_t outsize =0;
+ while(!feof(fInBinary)){
+ Byte_t *byte_pt =(Byte_t *) row_pt;
+
+ if(fread(row_pt,sizeof(AliL3DigitRowData),1,fInBinary)!=1) break;
+ byte_pt += sizeof(AliL3DigitRowData);
+ outsize += sizeof(AliL3DigitRowData);
+
+ Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit;
+
+ if(fread(byte_pt,size,1,fInBinary)!=1) break;
+ byte_pt += size;
+ outsize += size;
+
+ row_pt = (AliL3DigitRowData *) byte_pt;
+ rowcount++;
+ }
+ nrow= rowcount;
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","Memory")
+ <<AliL3Log::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+ <<rowcount<<" Rows)"<<ENDLOG;
+ return kTRUE;
+}
+
+void AliL3MemHandler::AddData(AliL3DigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge){
+ data[ndata].fPad = pad;
+ data[ndata].fTime = time;
+ data[ndata].fCharge = charge;
+ ndata++;
+}
+
+void AliL3MemHandler::AddRandom(AliL3DigitData *data, UInt_t & ndata){
+ data[ndata].fPad = fDPt[fNUsed]->fPad;
+ data[ndata].fTime = fDPt[fNUsed]->fTime;
+ data[ndata].fCharge = fDPt[fNUsed]->fCharge;
+ ndata++;
+ fNUsed++;
+}
+
+void AliL3MemHandler::MergeDataRandom(AliL3DigitData *data, UInt_t & ndata,
+ UInt_t row, UShort_t pad, UShort_t time, UShort_t charge){
+// AddData(data,ndata,row,pad,time,charge);
+ data[ndata].fPad = pad;
+ data[ndata].fTime = time;
+ data[ndata].fCharge = charge;
+ while(ComparePoints(row,pad,time)==0){
+ Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge;
+ if(charge>1023) ch = 1023;
+ data[ndata].fCharge = ch;
+ fNUsed++;
+ }
+ ndata++;
+}
+
+void AliL3MemHandler::AddDataRandom(AliL3DigitData *data, UInt_t & ndata,
+ UInt_t row, UShort_t pad, UShort_t time, UShort_t charge){
+ Int_t action;
+ while((action=ComparePoints(row,pad,time))==1){
+ AddRandom(data,ndata);
+ }
+ if(action==0){
+ MergeDataRandom(data,ndata,row,pad,time,charge);
+ }
+ if(action<0){
+ AddData(data,ndata,row,pad,time,charge);
+ }
+}
+
+void AliL3MemHandler::Write(UInt_t *comp, UInt_t & index,
+ UInt_t & subindex, UShort_t value){
+ UInt_t shift[3] = {0,10,20};
+ comp[index] |= (value&0x03ff)<<shift[subindex];
+ if(subindex == 2){
+ subindex = 0;
+ index++;
+ }
+ else subindex++;
+}
+
+UShort_t AliL3MemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex){
+ UInt_t shift[3] = {0,10,20};
+ UShort_t value = (comp[index]>>shift[subindex])&0x03ff;
+ if(subindex == 2){
+ subindex = 0;
+ index++;
+ }
+ else subindex++;
+
+ return value;
+}
+
+UShort_t AliL3MemHandler::Test(UInt_t *comp,
+ UInt_t index, UInt_t subindex){
+ UInt_t shift[3] = {0,10,20};
+ return (comp[index]>>shift[subindex])&0x03ff;
+}
+
+Int_t AliL3MemHandler::Memory2CompMemory(UInt_t nrow,
+ AliL3DigitRowData *data,UInt_t *comp){
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2CompMemory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2CompMemory","Memory")
+ <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ AliL3DigitRowData *row_pt = data;
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UShort_t value = row_pt->fRow;
+ Write(comp,index,subindex,value);
+ UShort_t maxpad=0;
+ UShort_t npad=0;
+ Int_t ddd[1000];
+ for(Int_t d=0;d<200;d++) ddd[d]=0;
+ for(UInt_t dig=0;dig<row_pt->fNDigit;dig++){
+ if(row_pt->fDigitData[dig].fPad <200){
+ ddd[row_pt->fDigitData[dig].fPad]++;
+ }
+ }
+ for(Int_t d=0;d<200;d++){
+ if(ddd[d]){
+ npad++;
+ maxpad =d;
+ }
+ }
+ Write(comp,index,subindex,npad);
+ UInt_t digit=0;
+ for(UShort_t pad=0;pad <= maxpad;pad++){
+ if(digit>=row_pt->fNDigit || row_pt->fDigitData[digit].fPad != pad)
+ continue;
+ Write(comp,index,subindex,pad);
+// write zero if time != 0
+ if(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
+ if(row_pt->fDigitData[digit].fTime>0){
+ Write(comp,index,subindex,0);
+ Write(comp,index,subindex,row_pt->fDigitData[digit].fTime);
+ }
+ }
+ while(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
+ UShort_t charge = row_pt->fDigitData[digit].fCharge;
+ if(charge>=1024){
+ charge=1023;
+ }
+ Write(comp,index,subindex,charge);
+ if(digit+1<row_pt->fNDigit&&row_pt->fDigitData[digit+1].fPad == pad){
+ if(row_pt->fDigitData[digit].fTime +1 !=
+ row_pt->fDigitData[digit+1].fTime){
+ Write(comp,index,subindex,0);
+ UShort_t nzero = row_pt->fDigitData[digit+1].fTime -
+ (row_pt->fDigitData[digit].fTime +1);
+ Write(comp,index,subindex,nzero);
+ }
+ }
+ digit++;
+ }
+ Write(comp,index,subindex,0);
+ Write(comp,index,subindex,0);
+ }
+
+ Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
+ sizeof(AliL3DigitRowData);
+ Byte_t *byte_pt =(Byte_t *) row_pt;
+ byte_pt += size;
+ row_pt = (AliL3DigitRowData *) byte_pt;
+ }
+ while(subindex)
+ Write(comp,index,subindex,0);
+ return index * sizeof(UInt_t);
+}
+
+Int_t AliL3MemHandler::CompMemory2Memory(UInt_t nrow,
+ AliL3DigitRowData *data,UInt_t *comp){
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2Memory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2Memory","Memory")
+ <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ Int_t outsize=0;
+
+ AliL3DigitRowData *row_pt = data;
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UInt_t ndigit=0;
+ UInt_t row =Read(comp,index,subindex);
+ row_pt->fRow=row;
+ Generate(row);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ UShort_t charge;
+ UShort_t time =0;
+ UShort_t pad = Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if( (time = Read(comp,index,subindex)) == 0 ){
+ continue;
+ }
+ }
+ for(;;){
+ while( (charge=Read(comp,index,subindex)) != 0){
+ if(time>=fEtaMinTimeBin[row]&&time<=fEtaMaxTimeBin[row])
+// AddData(row_pt->fDigitData,ndigit,row,pad,time,charge);
+ AddDataRandom(row_pt->fDigitData,ndigit,row,pad,time,charge);
+ time++;
+ }
+ UShort_t tshift = Read(comp,index,subindex);
+ if(tshift ==0) break;
+ time += tshift;
+ }
+ }
+ row_pt->fNDigit = ndigit;
+ Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
+ sizeof(AliL3DigitRowData);
+ Byte_t *byte_pt =(Byte_t *) row_pt;
+ byte_pt += size;
+ outsize += size;
+ row_pt = (AliL3DigitRowData *) byte_pt;
+ }
+ return outsize;
+}
+
+UInt_t AliL3MemHandler::GetCompMemorySize(UInt_t nrow,AliL3DigitRowData *data){
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::GetCompMemorySize","Memory")
+ <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ AliL3DigitRowData *row_pt = data;
+ UInt_t index=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ index++;
+ UShort_t maxpad=0;
+ UShort_t npad=0;
+ Int_t ddd[1000];
+ for(Int_t d=0;d<200;d++) ddd[d]=0;
+ for(UInt_t dig=0;dig<row_pt->fNDigit;dig++){
+ if(row_pt->fDigitData[dig].fPad <200){
+ ddd[row_pt->fDigitData[dig].fPad]++;
+ }
+ }
+ for(Int_t d=0;d<200;d++){
+ if(ddd[d]){
+ npad++;
+ maxpad =d;
+ }
+ }
+ index++;
+ UInt_t digit=0;
+ for(UShort_t pad=0;pad <= maxpad;pad++){
+ if(digit>=row_pt->fNDigit || row_pt->fDigitData[digit].fPad != pad)
+ continue;
+ index++;
+// write zero if time != 0
+ if(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
+ if(row_pt->fDigitData[digit].fTime>0){
+ index++;
+ index++;
+ }
+ }
+ while(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
+ index++;
+ if(digit+1<row_pt->fNDigit&&row_pt->fDigitData[digit+1].fPad == pad){
+ if(row_pt->fDigitData[digit].fTime +1 !=
+ row_pt->fDigitData[digit+1].fTime){
+ index++;
+ index++;
+ }
+ }
+ digit++;
+ }
+ index++;
+ index++;
+ }
+
+ Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
+ sizeof(AliL3DigitRowData);
+ Byte_t *byte_pt =(Byte_t *) row_pt;
+ byte_pt += size;
+ row_pt = (AliL3DigitRowData *) byte_pt;
+ }
+ while(index%3)
+ index++;
+ return (index/3) * sizeof(UInt_t);
+}
+
+UInt_t AliL3MemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp){
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::GetMemorySize","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ Int_t outsize=0;
+
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UInt_t ndigit=0;
+ Read(comp,index,subindex);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if(Read(comp,index,subindex)== 0) continue;
+ }
+ for(;;){
+ while(Read(comp,index,subindex)!=0) ndigit++;
+ if(Read(comp,index,subindex)==0) break;
+ }
+ }
+ Int_t size = sizeof(AliL3DigitData) * ndigit+
+ sizeof(AliL3DigitRowData);
+ outsize += size;
+ }
+
+ return outsize;
+}
+
+UInt_t AliL3MemHandler::GetNRow(UInt_t *comp,UInt_t size){
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::GetNRow","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ size = size /4;
+ UInt_t nrow=0;
+ UInt_t index=0;
+ UInt_t subindex=0;
+ while(index+1<size){
+ nrow++;
+ UInt_t ndigit=0;
+ Read(comp,index,subindex);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if(Read(comp,index,subindex)==0)continue;
+ }
+ for(;;){
+ while(Read(comp,index,subindex)!=0) ndigit++;
+ if(Read(comp,index,subindex)==0) break;
+ }
+ }
+ }
+ if(index+1==size)
+ if(subindex<2)
+ if(Read(comp,index,subindex)!=0) nrow++;
+
+ return nrow;
+}
+
+Bool_t AliL3MemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
+ UInt_t size){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(size==0)
+ size=GetMemorySize(nrow,comp);
+ if(!size){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","Memory")
+ <<"Memory size = 0 "<<ENDLOG;
+ return kFALSE;
+ }
+ UInt_t length = size/sizeof(UInt_t);
+ fwrite(&length,sizeof(UInt_t),1,fOutBinary);
+ fwrite(comp,size,1,fOutBinary);
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompBinary2CompMemory","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!comp){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::CompBinary2CompMemory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ rewind(fInBinary);
+ UInt_t length;
+ if(fread(&length,sizeof(UInt_t),1,fInBinary)!=1) return kFALSE;
+ UInt_t size = length*sizeof(UInt_t);
+ if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
+ // now find the number of dig
+ nrow = GetNRow(comp,size);
+ return kTRUE;
+}
+
+AliL3DigitRowData *AliL3MemHandler::CompBinary2Memory(UInt_t & nrow){
+ AliL3MemHandler * handler = new AliL3MemHandler();
+ handler->SetBinaryInput(fInBinary);
+ UInt_t *comp =(UInt_t *)handler->Allocate();
+ handler->CompBinary2CompMemory(nrow,comp);
+ UInt_t size = GetMemorySize(nrow,comp);
+ AliL3DigitRowData *data = (AliL3DigitRowData *)Allocate(size);
+ CompMemory2Memory(nrow,data,comp);
+ handler->Free();
+ delete handler;
+ return data;
+}
+
+Bool_t AliL3MemHandler::Memory2CompBinary(UInt_t nrow,AliL3DigitRowData *data){
+ Bool_t out = kTRUE;
+ AliL3MemHandler * handler = new AliL3MemHandler();
+ UInt_t size = GetCompMemorySize(nrow,data);
+ UInt_t *comp =(UInt_t *)handler->Allocate(size);
+ Memory2CompMemory(nrow,data,comp);
+ CompMemory2CompBinary(nrow,comp,size);
+ handler->Free();
+ delete handler;
+ return out;
+}
+
+
+///////////////////////////////////////// Point IO
+Bool_t AliL3MemHandler::Memory2Binary(UInt_t npoint,AliL3SpacePointData *data){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ UInt_t size = npoint*sizeof(AliL3SpacePointData);
+ fwrite(data,size,1,fOutBinary);
+
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Transform(UInt_t npoint,AliL3SpacePointData *data,
+ Int_t slice, AliL3Transform* trans){
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Transform","Memory")
+ <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!trans){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Transform","Object")
+ <<"Pointer to AliL3Transform = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ for(UInt_t i=0;i<npoint;i++){
+ Float_t xyz[3];
+ xyz[0] = data[i].fX;
+ xyz[1] = data[i].fY;
+ xyz[2] = data[i].fZ;
+ trans->Local2Global(xyz,slice);
+ data[i].fX = xyz[0];
+ data[i].fY = xyz[1];
+ data[i].fZ = xyz[2];
+ }
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Binary2Memory(UInt_t & npoint,AliL3SpacePointData *data){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ Int_t size = GetFileSize();
+/*
+ UInt_t size,slice,patch,row[2];
+ AliL3EventDataTypeRoot datatype;
+ UInt_t node;
+ if(fread(&datatype,sizeof(AliL3EventDataTypeRoot),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&node,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&size,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&slice,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&patch,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(row,2*sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+*/
+ npoint = size/sizeof(AliL3SpacePointData);
+ if(fread(data,size,1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(size%sizeof(AliL3SpacePointData)){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File Size")
+ <<"File Size wrong "<<ENDLOG;
+ return kFALSE;
+ }
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","File")
+ <<AliL3Log::kDec<<"Wrote "<<size<<" Bytes to Memory"<<ENDLOG;
+ return kTRUE;
+}
+
+///////////////////////////////////////// Track IO
+Bool_t AliL3MemHandler::Memory2Binary(UInt_t ntrack,AliL3TrackSegmentData *data){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliL3TrackSegmentData *track_pt = data;
+ for(UInt_t i=0;i<ntrack;i++){
+ Int_t size=sizeof(AliL3TrackSegmentData)+track_pt->fNPoints*sizeof(UInt_t);
+ fwrite(track_pt,size,1,fOutBinary);
+ Byte_t *byte_pt = (Byte_t*) track_pt;
+ byte_pt += size;
+ track_pt = (AliL3TrackSegmentData*) byte_pt;
+ }
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Memory2Binary","File")
+ <<AliL3Log::kDec<<"Wrote "<<ntrack<<" Tracks to File"<<ENDLOG;
+
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Binary2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ ntrack=0;
+ AliL3TrackSegmentData *track_pt = data;
+ rewind(fInBinary);
+/*
+ UInt_t size,slice,patch,row[2];
+ AliL3EventDataTypeRoot datatype;
+ UInt_t node;
+ if(fread(&datatype,sizeof(AliL3EventDataTypeRoot),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&node,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&size,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&slice,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(&patch,sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(fread(row,2*sizeof(UInt_t),1,fInBinary)!=1){
+ LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+*/
+ while(!feof(fInBinary)){
+ if(fread(track_pt,sizeof(AliL3TrackSegmentData),1,fInBinary)!=1) break;
+ Int_t size=track_pt->fNPoints*sizeof(UInt_t);
+ if(fread(track_pt->fPointIDs,size,1,fInBinary)!=1) break;
+ Byte_t *byte_pt = (Byte_t*) track_pt;
+ byte_pt += sizeof(AliL3TrackSegmentData)+size;
+ track_pt = (AliL3TrackSegmentData*) byte_pt;
+ ntrack++;
+ }
+ LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","File")
+ <<AliL3Log::kDec<<"Wrote "<<ntrack<<" Tracks to Memory"<<ENDLOG;
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::TrackArray2Binary(AliL3TrackArray *array){
+ if(!fOutBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Binary","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliL3TrackSegmentData *data = (AliL3TrackSegmentData *)Allocate(array);
+ UInt_t ntrack;
+ TrackArray2Memory(ntrack,data,array);
+ Memory2Binary(ntrack,data);
+ Free();
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Binary2TrackArray(AliL3TrackArray *array){
+ if(!fInBinary){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2TrackArray","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2TrackArray","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliL3TrackSegmentData *data = (AliL3TrackSegmentData *)Allocate();
+ UInt_t ntrack;
+ Binary2Memory(ntrack,data);
+ Memory2TrackArray(ntrack,data,array);
+ Free();
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::TrackArray2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array){
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Memory","Memory")
+ <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Memory","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ array->WriteTracks(ntrack,data);
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array){
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ array->FillTracks(ntrack,data);
+ return kTRUE;
+}
+
+Bool_t AliL3MemHandler::Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array,Int_t slice, AliL3Transform* trans){
+ if(!data){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!trans){
+ LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Object")
+ <<"Pointer to AliL3Transform = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ array->FillTracks(ntrack,data,slice,trans);
+ return kTRUE;
+}
+
--- /dev/null
+#ifndef ALIL3MEMHANDLER_H
+#define ALIL3MEMHANDLER_H
+
+#include "AliL3RootTypes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "AliL3DigitData.h"
+#include "AliL3Transform.h"
+class AliL3SpacePointData;
+class AliL3DigitRowData;
+class AliL3TrackSegmentData;
+class AliL3TrackArray;
+class AliL3RandomPointData;
+
+class AliL3MemHandler{
+ private:
+ AliL3Transform *fTransformer;//!
+ FILE *fInBinary;//!
+ FILE *fOutBinary;//!
+ Byte_t *fPt;//!
+ UInt_t fSize;
+
+ AliL3RandomDigitData **fDPt;//!
+ AliL3RandomDigitData *fDigits;//!
+ Bool_t IsRandom;
+ Int_t fNRandom;
+ Int_t fNGenerate;
+ Int_t fNUsed;
+ Int_t fNDigits;
+
+ void Write(UInt_t *comp, UInt_t & index, UInt_t & subindex, UShort_t value);
+ UShort_t Read(UInt_t *comp, UInt_t & index, UInt_t & subindex);
+ UShort_t Test(UInt_t *comp, UInt_t index, UInt_t subindex);
+
+ void DigitizePoint(Int_t row,Int_t pad, Int_t time,Int_t charge);
+ void QSort(AliL3RandomDigitData **a, Int_t first, Int_t last);
+ Int_t ComparePoints(UInt_t row,UShort_t pad,UShort_t time);
+ Int_t CompareDigits(AliL3RandomDigitData *a,AliL3RandomDigitData *b);
+ void AddData(AliL3DigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+ void AddRandom(AliL3DigitData *data,UInt_t & ndata);
+ void MergeDataRandom(AliL3DigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+ void AddDataRandom(AliL3DigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+
+ protected:
+ Int_t fRowMin;
+ Int_t fRowMax;
+ Int_t fSlice;
+ Int_t fPatch;
+
+ Int_t fEtaMinTimeBin[174];
+ Int_t fEtaMaxTimeBin[174];
+
+
+ public:
+ AliL3MemHandler();
+ virtual ~AliL3MemHandler();
+
+ void Reset(){CloseBinaryInput();CloseBinaryOutput();Free();}
+ void Init(AliL3Transform *t){fTransformer = t;}
+ void Init(Int_t s,Int_t p,Int_t* row){fSlice=s;fPatch=p;fRowMin=row[0];fRowMax=row[1]; ResetROI();}
+
+ Bool_t SetBinaryInput(char *name);
+ Bool_t SetBinaryInput(FILE *file);
+ void CloseBinaryInput();
+
+ Bool_t SetBinaryOutput(char *name);
+ Bool_t SetBinaryOutput(FILE *file);
+ void CloseBinaryOutput();
+
+ //Random cluster
+ void SetRandomCluster(Int_t maxnumber);
+ void SetRandomSeed(UInt_t seed){srand(seed);}
+ void SetRandomSeed();
+
+ void ResetRandom(){fNDigits = 0; fNUsed = 0;}
+ void Generate(Int_t row);
+ void SetNGenerate(Int_t number){(number>fNRandom)?fNGenerate=fNRandom:fNGenerate = number;}
+
+ void SetROI(Float_t *eta,Int_t *slice);
+ void ResetROI();
+
+ //Digit IO
+ Bool_t Memory2Binary(UInt_t nrow,AliL3DigitRowData *data);
+ Bool_t Binary2Memory(UInt_t & nrow,AliL3DigitRowData *data);
+
+ Int_t Memory2CompMemory(UInt_t nrow,AliL3DigitRowData *data,UInt_t *comp);
+ Int_t CompMemory2Memory(UInt_t nrow,AliL3DigitRowData *data,UInt_t *comp);
+ Bool_t CompMemory2CompBinary(UInt_t nrow,UInt_t *comp, UInt_t size=0);
+ Bool_t CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp);
+
+ AliL3DigitRowData *CompBinary2Memory(UInt_t & nrow);
+ Bool_t Memory2CompBinary(UInt_t nrow,AliL3DigitRowData *data);
+ UInt_t GetNRow(UInt_t *comp,UInt_t size);
+
+ //Point IO
+ Bool_t Memory2Binary(UInt_t npoint,AliL3SpacePointData *data);
+ Bool_t Binary2Memory(UInt_t & npoint,AliL3SpacePointData *data);
+ Bool_t Transform(UInt_t npoint,AliL3SpacePointData *data,
+ Int_t slice, AliL3Transform* trans);
+
+ //Track IO
+ Bool_t Memory2Binary(UInt_t ntrack,AliL3TrackSegmentData *data);
+ Bool_t Binary2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data);
+ Bool_t TrackArray2Binary(AliL3TrackArray *array);
+ Bool_t Binary2TrackArray(AliL3TrackArray *array);
+ Bool_t TrackArray2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data,
+ AliL3TrackArray *array);
+ Bool_t Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,
+ AliL3TrackArray *array);
+ Bool_t Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,
+ AliL3TrackArray *array,Int_t slice, AliL3Transform* trans);
+
+ //Memory Allocation
+ UInt_t GetAllocatedSize(){return fSize;}
+ UInt_t GetFileSize();
+ UInt_t GetMemorySize(UInt_t nrow,UInt_t *comp);
+ UInt_t GetCompMemorySize(UInt_t nrow,AliL3DigitRowData *data);
+ UInt_t GetRandomSize();
+
+ Byte_t *Allocate(UInt_t size);
+ Byte_t *Allocate(); // allocate size of Binary Input File
+ Byte_t *Allocate(AliL3TrackArray *array);
+ void Free();
+
+ ClassDef(AliL3MemHandler,1)
+};
+
+inline Int_t AliL3MemHandler::ComparePoints(UInt_t row,UShort_t pad,UShort_t time){
+ if(fNUsed>=fNDigits) return -2;
+
+ if(pad==fDPt[fNUsed]->fPad&&time==fDPt[fNUsed]->fTime) return 0;
+
+ if(pad<fDPt[fNUsed]->fPad) return -1;
+ if(pad==fDPt[fNUsed]->fPad&&time<fDPt[fNUsed]->fTime) return -1;
+
+ return 1;
+}
+
+inline Int_t AliL3MemHandler::CompareDigits(AliL3RandomDigitData *a,AliL3RandomDigitData *b){
+ if(a->fPad==b->fPad && a->fTime == b->fTime) return 0;
+
+ if(a->fPad<b->fPad) return -1;
+ if(a->fPad==b->fPad && a->fTime<b->fTime) return -1;
+
+ return 1;
+}
+
+#endif
--- /dev/null
+
+//Author: Uli Frankenfeld
+//Last Modified: 06.12.2000
+
+#include "AliL3Logging.h"
+#include <math.h>
+#include <iostream.h>
+#include "AliL3Merger.h"
+#include "AliL3Track.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3Transform.h"
+#include "AliL3TrackArray.h"
+
+#ifdef use_root //use root ntuple for slow merge
+#include <TNtuple.h>
+#include <TTree.h>
+#include <TFile.h>
+#endif
+//_____________________________________________________________
+//
+// The L3 merger base class
+//
+
+ClassImp(AliL3Merger)
+
+AliL3Merger::AliL3Merger(){
+ //Default constructor
+ fTransformer= 0;
+ SetArray(0);
+}
+
+
+AliL3Merger::AliL3Merger(Int_t ntrackarrays){
+ //Constructor.
+ SetArray(ntrackarrays);
+ fCurrentTracks=0;
+}
+
+AliL3Merger::~AliL3Merger(){
+ //Destructor
+ DeleteArray();
+}
+
+void AliL3Merger::DeleteArray(){
+ for(Int_t i=0; i<fNIn;i++)
+ delete fInTrack[i];
+ delete[] (Byte_t*) fInTrack;
+ delete fOutTrack;
+}
+
+void AliL3Merger::SetArray(Int_t nin){
+ fNIn = nin;
+ fInTrack = (AliL3TrackArray **) new Byte_t[fNIn*sizeof(AliL3TrackArray *)];
+ for(Int_t i=0; i<fNIn;i++){
+ fInTrack[i] = new AliL3TrackArray();
+ }
+ fOutTrack= new AliL3TrackArray();
+}
+
+void AliL3Merger::Reset(){
+ for(Int_t i=0; i<fNIn;i++){
+ fInTrack[i]->Reset();
+ }
+ fOutTrack->Reset();
+}
+
+void AliL3Merger::FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr){
+ //Read tracks from shared memory (or memory)
+ AliL3TrackArray *destination = GetInTracks(fCurrentTracks);
+ if(Is2Global())
+ destination->FillTracks(ntracks, tr, fSlice, fTransformer);
+ else
+ destination->FillTracks(ntracks, tr);
+}
+
+void AliL3Merger::AddAllTracks(){
+ for(Int_t i=0; i<GetNIn();i++){
+ AliL3TrackArray *in = GetInTracks(i);
+ AliL3TrackArray *out = GetOutTracks();
+ out->AddTracks(in);
+ }
+}
+
+void AliL3Merger::SortGlobalTracks(AliL3Track **tracks, Int_t ntrack){
+ AliL3Track **tmp = new AliL3Track*[ntrack];
+ for(Int_t i=0;i<ntrack;i++) tmp[i] = tracks[i];
+ Int_t *t = new Int_t[ntrack];
+ for(Int_t i=0;i<ntrack;i++) t[i]=-1;
+
+ for(Int_t j=0;j<ntrack;j++){
+ Double_t minr=300;
+ Int_t mini=0;
+ for(Int_t i=0;i<ntrack;i++){
+ if(!tracks[i]) continue;
+ Double_t rr=pow(tracks[i]->GetFirstPointX(),2)+pow(tracks[i]->GetFirstPointY(),2);
+ Double_t r=sqrt(rr);
+ if(r<minr){
+ minr=r;
+ mini=i;
+ }
+ }
+ t[j]=mini;
+ tracks[mini]=0;
+ }
+ for(Int_t i=0;i<ntrack;i++) tracks[i] = tmp[t[i]];
+ delete[] t;
+ delete[] tmp;
+}
+
+
+void AliL3Merger::SortTracks(AliL3Track **tracks, Int_t ntrack){
+ AliL3Track **tmp = new AliL3Track*[ntrack];
+ for(Int_t i=0;i<ntrack;i++) tmp[i] = tracks[i];
+ Int_t *t = new Int_t[ntrack];
+ for(Int_t i=0;i<ntrack;i++) t[i]=-1;
+
+ for(Int_t j=0;j<ntrack;j++){
+ Double_t minx=300;
+ Int_t mini=0;
+ for(Int_t i=0;i<ntrack;i++){
+ if(!tracks[i]) continue;
+ if(tracks[i]->GetFirstPointX()<minx){
+ minx=tracks[i]->GetFirstPointX();
+ mini=i;
+ }
+ }
+ t[j]=mini;
+ tracks[mini]=0;
+ }
+ for(Int_t i=0;i<ntrack;i++) tracks[i] = tmp[t[i]];
+ delete[] t;
+ delete[] tmp;
+}
+
+void AliL3Merger::AddTrack(AliL3TrackArray *mergedtrack,AliL3Track *track){
+ AliL3Track *t[1];
+ t[0] = track;
+ MultiMerge(mergedtrack,t,1);
+}
+
+AliL3Track * AliL3Merger::MergeTracks(AliL3TrackArray *mergedtrack,AliL3Track *t0,AliL3Track *t1){
+ AliL3Track *t[2];
+ t[0] = t0;
+ t[1] = t1;
+ SortTracks(t,2);
+ return MultiMerge(mergedtrack,t,2);
+}
+
+AliL3Track * AliL3Merger::MultiMerge(AliL3TrackArray *mergedtracks,AliL3Track **tracks, Int_t ntrack){
+// merge the tracks!!
+
+//check npoints
+ Int_t nps = 0;
+ for(Int_t i=0;i<ntrack;i++){
+ nps+=tracks[i]->GetNHits();
+ }
+ if(nps>174){
+ LOG(AliL3Log::kWarning,"AliL3Merger::MultiMerge","Adding Points")
+ <<AliL3Log::kDec<<"Too many Points: "<<nps<<ENDLOG;
+ return 0;
+ }
+
+ //create new track
+ AliL3Track *newtrack = mergedtracks->NextTrack();
+ //copy points
+ UInt_t nn[174];
+ nps = 0;
+
+// for(Int_t i=0;i<ntrack;i++){
+ for(Int_t i=ntrack-1;i>=0;i--){
+ memcpy(&nn[nps],tracks[i]->GetHitNumbers(),tracks[i]->GetNHits()*sizeof(UInt_t));
+ nps+=tracks[i]->GetNHits();
+ }
+ AliL3Track *tpf=tracks[0];
+ AliL3Track *tpl=tracks[ntrack-1];
+
+ newtrack->SetNHits(nps);
+ newtrack->SetHits(nps,nn);
+ newtrack->SetFirstPoint(tpf->GetFirstPointX(),tpf->GetFirstPointY(),tpf->GetFirstPointZ());
+ newtrack->SetLastPoint(tpl->GetLastPointX(),tpl->GetLastPointY(),tpl->GetLastPointZ());
+ newtrack->SetPt(tpf->GetPt());
+ newtrack->SetPsi(tpf->GetPsi());
+ newtrack->SetTgl(tpf->GetTgl());
+ newtrack->SetCharge(tpf->GetCharge());
+ return newtrack;
+}
+
+void* AliL3Merger::GetNtuple(char *varlist){
+#ifdef use_root
+ TNtuple* nt = new TNtuple("ntuple","ntuple",varlist);
+ return (void*) nt;
+#else
+ return 0;
+#endif
+}
+
+void* AliL3Merger::GetNtuple(){
+#ifdef use_root
+ TNtuple* nt = new TNtuple("ntuple","ntuple",
+ "dx:dy:dz:dk:dpsi:dtgl:dq:disx:disy:disz:dis:n0:n1:diff:drx:dry:drz");
+ return (void*) nt;
+#else
+ return 0;
+#endif
+}
+
+Bool_t AliL3Merger::WriteNtuple(char *filename, void* nt){
+#ifdef use_root
+ TNtuple *ntuple=(TNtuple *) nt;
+ TFile *f = new TFile(filename,"RECREATE");
+ ntuple->Write();
+ f->Close();
+ delete ntuple;
+ return kTRUE;
+#else
+ return kFALSE;
+#endif
+}
+
+void AliL3Merger::FillNtuple(void *nt,AliL3Track *innertrack,AliL3Track *outertrack){
+ Float_t data[17];
+ if(outertrack->IsPoint()&&innertrack->IsPoint()){
+ data[0] =Float_t(innertrack->GetPointX()-outertrack->GetPointX());
+ data[1] =Float_t(innertrack->GetPointY()-outertrack->GetPointY());
+ data[2] =Float_t(innertrack->GetPointZ()-outertrack->GetPointZ());
+ data[3] =Float_t(innertrack->GetKappa()-outertrack->GetKappa());
+ Double_t psi= innertrack->GetPointPsi() - outertrack->GetPointPsi();
+ if(psi>PI) psi-=2*PI;
+ if(psi<-PI)psi+=2*PI;
+ data[4] =Float_t(psi);
+ data[5] =Float_t(innertrack->GetTgl()-outertrack->GetTgl());
+ data[6] =Float_t(innertrack->GetCharge()-outertrack->GetCharge());
+ data[7] =Float_t(innertrack->GetLastPointX()-outertrack->GetFirstPointX());
+ data[8] =Float_t(innertrack->GetLastPointY()-outertrack->GetFirstPointY());
+ data[9] =Float_t(innertrack->GetLastPointZ()-outertrack->GetFirstPointZ());
+ data[10] =sqrt(pow(data[7],2)+pow(data[8],2)+pow(data[9],2));
+ data[11]= outertrack->GetNHits();
+ data[12]= innertrack->GetNHits();
+ data[13] = Float_t(TrackDiff(innertrack,outertrack));
+#ifdef use_root
+ TNtuple *ntuple = (TNtuple *) nt;
+ ntuple->Fill(data);
+#endif
+ }
+}
+
+void AliL3Merger::FillNtuple(void *nt,Float_t *data){
+#ifdef use_root
+ TNtuple *ntuple = (TNtuple *) nt;
+ ntuple->Fill(data);
+#endif
+}
+
+Double_t AliL3Merger::GetAngle(Double_t a1,Double_t a2){
+ Double_t da = a1 - a2 +4*PI;
+ da = fmod(da,2*PI);
+ if(da>PI) da = 2*PI -da;
+ return da;
+}
+
+void AliL3Merger::SetParameter(Double_t maxy, Double_t maxz, Double_t maxkappa, Double_t maxpsi, Double_t maxtgl){
+ fMaxY = maxy;
+ fMaxZ = maxz;
+ fMaxKappa = maxkappa;
+ fMaxPsi = maxpsi;
+ fMaxTgl = maxtgl;
+}
+
+Bool_t AliL3Merger::IsTrack(AliL3Track *innertrack,AliL3Track *outertrack){
+
+ if(innertrack->GetCharge()!=outertrack->GetCharge()) return kFALSE;
+ if( (!innertrack->IsPoint()) || (!outertrack->IsPoint()) ) return kFALSE;
+ if(innertrack->GetNHits()+outertrack->GetNHits()>174) return kFALSE;
+
+ if(fabs(innertrack->GetPointY()-outertrack->GetPointY()) >fMaxY) return kFALSE;
+ if(fabs(innertrack->GetPointZ()-outertrack->GetPointZ()) >fMaxZ) return kFALSE;
+ if(fabs(innertrack->GetKappa()-outertrack->GetKappa()) >fMaxKappa) return kFALSE;
+ if(GetAngle(innertrack->GetPointPsi(),outertrack->GetPointPsi()) >fMaxPsi) return kFALSE;
+ if(fabs(innertrack->GetTgl()-outertrack->GetTgl()) >fMaxTgl) return kFALSE;
+ //if no rejection up to this point: merge!!
+ return kTRUE;
+}
+
+Bool_t AliL3Merger::IsRTrack(AliL3Track *innertrack,AliL3Track *outertrack){
+ return IsTrack(innertrack,outertrack);
+}
+
+Double_t AliL3Merger::TrackDiff(AliL3Track *innertrack,AliL3Track *outertrack){
+ Double_t diff =-1;
+ Double_t x[4],y[4],z[4],dy[4],dz[4];
+ AliL3Track *tracks[2];
+
+ tracks[0] = innertrack;
+ tracks[1] = outertrack;
+ SortGlobalTracks(tracks,2);
+ innertrack = tracks[0];
+ outertrack = tracks[1];
+
+ x[0] = innertrack->GetFirstPointX();
+ x[1] = innertrack->GetLastPointX();
+ x[2] = outertrack->GetFirstPointX();
+ x[3] = outertrack->GetLastPointX();
+
+ y[0] = innertrack->GetFirstPointY();
+ y[1] = innertrack->GetLastPointY();
+ y[2] = outertrack->GetFirstPointY();
+ y[3] = outertrack->GetLastPointY();
+
+ z[0] = innertrack->GetFirstPointZ();
+ z[1] = innertrack->GetLastPointZ();
+ z[2] = outertrack->GetFirstPointZ();
+ z[3] = outertrack->GetLastPointZ();
+
+
+ outertrack->CalculatePoint(x[0]);
+ if(!outertrack->IsPoint()) return diff;
+ dy[0] = fabs(y[0] - outertrack->GetPointY());
+ dz[0] = fabs(z[0] - outertrack->GetPointZ());
+
+ outertrack->CalculatePoint(x[1]);
+ if(!outertrack->IsPoint()) return diff;
+ dy[1] = fabs(y[1] - outertrack->GetPointY());
+ dz[1] = fabs(z[1] - outertrack->GetPointZ());
+
+ innertrack->CalculatePoint(x[2]);
+ if(!innertrack->IsPoint()) return diff;
+ dy[2] = fabs(y[2] - innertrack->GetPointY());
+ dz[2] = fabs(z[2] - innertrack->GetPointZ());
+
+ innertrack->CalculatePoint(x[3]);
+ if(!innertrack->IsPoint()) return diff;
+ dy[3] = fabs(y[3] - innertrack->GetPointY());
+ dz[3] = fabs(z[3] - innertrack->GetPointZ());
+
+ diff=0;
+ for(Int_t i=0;i<4;i++)
+ diff+=sqrt(dy[i]*dy[i]+dz[i]*dz[i]);
+ return diff;
+}
+
+
+
+void AliL3Merger::PrintDiff(AliL3Track *innertrack,AliL3Track *outertrack){
+ if(!innertrack->IsPoint()||!outertrack->IsPoint()){
+ cerr<<"AliL3Merger::PrintDiff: No Points"<<endl;
+ cerr<<"---------------------------"<<endl;
+ return;
+ }
+ Double_t dx = innertrack->GetPointX()-outertrack->GetPointX();
+ Double_t dy = innertrack->GetPointY()-outertrack->GetPointY();
+ Double_t dz = innertrack->GetPointZ()-outertrack->GetPointZ();
+ Double_t dk = innertrack->GetKappa()-outertrack->GetKappa();
+ Double_t dpsi= innertrack->GetPointPsi() - outertrack->GetPointPsi();
+ if(dpsi>PI) dpsi-=2*PI;
+ if(dpsi<-PI)dpsi+=2*PI;
+// Double_t dpsi = GetAngle(innertrack->GetPointPsi(),outertrack->GetPointPsi());
+ Double_t dtgl= innertrack->GetTgl()-outertrack->GetTgl();
+ Double_t dq =innertrack->GetCharge()-outertrack->GetCharge();
+
+ fprintf(stderr,"dx: %4f dy: %4f dz: %4f dk: %4f dpsi: %4f dtgl: %4f dq: %4f\n",
+ dx,dy,dz,dk,dpsi,dtgl,dq);
+cerr<<"---------------------------"<<endl;
+// cerr<<endl;
+
+}
+
+void AliL3Merger::Print(){
+ // print some infos
+ for(Int_t i=0; i<fNIn; i++){
+ AliL3TrackArray *ttt= GetInTracks(i);
+ for(Int_t j =0;j<ttt->GetNTracks();j++){
+ AliL3Track *track=ttt->GetCheckedTrack(j);
+ if(!track) continue;
+ track->CalculateHelix();
+// Double_t angle = atan2(track->GetLastPointY(),track->GetLastPointX());
+// if(angle<0) angle+=PI;
+ if(track->CalculatePoint(135))
+// if(!track->CalculateEdgePoint(angle)) cerr<<"**************"<<endl;
+// if(track->CalculatePoint(track->GetLastPointX()))
+// if(track->CalculatePoint(0))
+ {
+// PrintTrack(track);
+// track->CalculateReferencePoint(PI/180.);
+ track->CalculateReferencePoint(0.001);
+ fprintf(stderr,"npt: %3d dx: %8.5f dy: %8.5f dz: %8.5f\n",
+ track->GetNHits(),(float)track->GetPointX()-track->GetPointX(),
+ (float)track->GetPointY()-track->GetPointY(),
+ (float)track->GetPointZ()-track->GetPointZ());
+
+ cerr<<"---------------------------"<<endl;
+ }
+ }
+ }
+}
+
+void AliL3Merger::PrintTrack(AliL3Track *track){
+ fprintf(stderr,"npt: %3d pt: %.2f psi: %.2f tgl: %5.2f q: %2d\n",
+ track->GetNHits(),track->GetPt(),track->GetPsi(),
+ track->GetTgl(),track->GetCharge());
+ fprintf(stderr,
+ "x1: %6.2f y1: %6.2f z1: %6.2f xl: %6.2f yl: %6.2f zl: %6.2f\n",
+ track->GetFirstPointX(),track->GetFirstPointY(),track->GetFirstPointZ(),
+ track->GetLastPointX(),track->GetLastPointY(),track->GetLastPointZ());
+ if(track->IsPoint()){
+ fprintf(stderr,
+ "R: %.2f Xc: %.2f Yc: %.2f Xp: %.2f Yp: %.2f Zp: %.2f Psip: %.2f\n",
+ track->GetRadius(),track->GetCenterX(),track->GetCenterY(),
+ track->GetPointX(),track->GetPointY(),track->GetPointZ(),
+ track->GetPointPsi());
+ }
+}
+
+
+
+
--- /dev/null
+#ifndef ALIL3MERGER_H
+#define ALIL3MERGER_H
+#define PI 3.14159265358979312
+
+#include "AliL3RootTypes.h"
+
+class AliL3Track;
+class AliL3TrackSegmentData;
+class AliL3Vertex;
+class AliL3Transform;
+class AliL3TrackArray;
+
+class AliL3Merger {
+ private:
+ Double_t fMaxY;
+ Double_t fMaxZ;
+ Double_t fMaxKappa;
+ Double_t fMaxPsi;
+ Double_t fMaxTgl;
+ void SetArray(Int_t nin);
+ void DeleteArray();
+
+ AliL3TrackArray **fInTrack;//!
+ Int_t fNIn;
+
+ AliL3TrackArray *fOutTrack;//!
+
+ protected:
+ Int_t fCurrentTracks;
+ Int_t fSlice;
+ AliL3Vertex *fVertex;//!
+ AliL3Transform *fTransformer;//!
+ Bool_t f2Global;
+ Bool_t Is2Global(Bool_t is){f2Global=is;return f2Global;}
+
+ public:
+ AliL3Merger();
+ AliL3Merger(Int_t ntrackarrays);
+ virtual ~AliL3Merger();
+
+ Int_t GetNIn(){return fNIn;}
+ AliL3TrackArray *GetInTracks(Int_t in){return fInTrack[in];}
+ AliL3TrackArray *GetOutTracks(){return fOutTrack;}
+
+ Bool_t Is2Global(){return f2Global;}
+ void SetTransformer(AliL3Transform *trans){fTransformer = trans;}
+ void SetVertex(AliL3Vertex *vertex){fVertex=vertex;}
+ void Reset();
+ void SetParameter(Double_t maxy=1., Double_t maxz=1., Double_t maxkappa=0.001, Double_t maxpsi=0.05, Double_t maxtgl=0.1);
+ void FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr); //Fill tracks in fTrackArray[fCurrentTracks]
+ Double_t GetAngle(Double_t a1,Double_t a2);
+ void* GetNtuple();
+ void* GetNtuple(char *varlist);
+ Bool_t WriteNtuple(char *filename,void* nt);
+ void FillNtuple(void* nt,Float_t *data);
+ void FillNtuple(void* nt,AliL3Track *innertrack,AliL3Track *outertrack);
+ void AddAllTracks();//Copy all Tracks to Output Array
+ void SortGlobalTracks(AliL3Track **tracks, Int_t ntrack);
+ void SortTracks(AliL3Track **tracks, Int_t ntrack);
+ void AddTrack(AliL3TrackArray *mergedtrack,AliL3Track *track);
+ AliL3Track * MultiMerge(AliL3TrackArray *mergedtrack,AliL3Track **tracks, Int_t ntrack);
+ AliL3Track * MergeTracks(AliL3TrackArray *mergedtrack,AliL3Track *t0,AliL3Track *t1);
+ Bool_t IsTrack(AliL3Track *innertrack,AliL3Track *outertrack);
+ Bool_t IsRTrack(AliL3Track *innertrack,AliL3Track *outertrack);
+ Double_t TrackDiff(AliL3Track *innertrack,AliL3Track *outertrack);
+ void Print();
+ void PrintDiff(AliL3Track *innertrack,AliL3Track *outertrack);
+ void PrintTrack(AliL3Track *track);
+// Int_t WriteTracks(Char_t *file);
+// Int_t WriteInTracks(Char_t *file);
+// Int_t WriteAllTracks(Char_t *file);
+
+ ClassDef(AliL3Merger,1)
+};
+
+#endif
--- /dev/null
+#ifndef ALIL3ROOTTYPES_H
+#define ALIL3ROOTTYPES_H
+
+
+//////////////////////////////////////////////////////////////////////////
+// //
+// Basic types used by level3 //
+// //
+//////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <math.h>
+
+//#define no_root //switch on the root
+
+#ifndef no_root
+#define use_root
+#include <TObject.h>
+#include <Rtypes.h>
+
+#else
+
+#ifndef ROOT_Rtypes
+//---- types -------------------------------------------------------------------
+
+typedef char Char_t; //Signed Character 1 byte
+typedef unsigned char UChar_t; //Unsigned Character 1 byte
+typedef short Short_t; //Signed Short integer 2 bytes
+typedef unsigned short UShort_t; //Unsigned Short integer 2 bytes
+#ifdef R__INT16
+typedef long Int_t; //Signed integer 4 bytes
+typedef unsigned long UInt_t; //Unsigned integer 4 bytes
+#else
+typedef int Int_t; //Signed integer 4 bytes
+typedef unsigned int UInt_t; //Unsigned integer 4 bytes
+#endif
+#ifdef R__B64
+typedef int Seek_t; //File pointer
+typedef long Long_t; //Signed long integer 4 bytes
+typedef unsigned long ULong_t; //Unsigned long integer 4 bytes
+#else
+typedef int Seek_t; //File pointer
+typedef long Long_t; //Signed long integer 8 bytes
+typedef unsigned long ULong_t; //Unsigned long integer 8 bytes
+#endif
+typedef float Float_t; //Float 4 bytes
+typedef double Double_t; //Float 8 bytes
+typedef char Text_t; //General string
+typedef unsigned char Bool_t; //Boolean (0=false, 1=true)
+typedef unsigned char Byte_t; //Byte (8 bits)
+typedef short Version_t; //Class version identifier
+typedef const char Option_t; //Option string
+typedef int Ssiz_t; //String size
+typedef float Real_t; //TVector and TMatrix element type
+
+typedef void (*VoidFuncPtr_t)(); //pointer to void function
+
+
+//---- constants ---------------------------------------------------------------
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+const Bool_t kTRUE = 1;
+const Bool_t kFALSE = 0;
+
+const Int_t kMaxInt = 2147483647;
+const Int_t kMaxShort = 32767;
+const size_t kBitsPerByte = 8;
+const Ssiz_t kNPOS = ~(Ssiz_t)0;
+
+
+//---- ClassDef macros ---------------------------------------------------------
+
+
+#define ClassDef(name,id)
+
+#define ClassImp(name)
+#endif //end of Rtypes
+
+#endif //end of root selection
+
+//---- Timms AliL3EventDataType from AliL3EventDataType.h
+
+union AliL3EventDataTypeRoot{
+ ULong_t fID;
+ unsigned char fDescr[8];
+};
+
+typedef union AliL3EventDataTypeRoot AliL3EventDataTypeRoot;
+
+#define ROOT_UNKNOWN_DATAID (((ULong_t)'UNKN')<<32 | 'OWN ')
+#define ROOT_COMPOSITE_DATAID (((ULong_t)'COMP')<<32 | 'OSIT')
+#define ROOT_ADCCOUNTS_DATAID (((ULong_t)'ADCC')<<32 | 'OUNT')
+#define ROOT_ADCCOUNTS_UNPACKED_DATAID (((ULong_t)'ADCC')<<32 | 'NTUP')
+#define ROOT_CLUSTERS_DATAID (((ULong_t)'CLUS')<<32 | 'TERS')
+#define ROOT_SPACEPOINTS_DATAID (((ULong_t)'SPAC')<<32 | 'EPTS')
+#define ROOT_VERTEXDATA_DATAID (((ULong_t)'VRTX')<<32 | 'DATA')
+#define ROOT_TRACKSEGMENTS_DATAID (((ULong_t)'TRAC')<<32 | 'SEGS')
+#define ROOT_SLICETRACKS_DATAID (((ULong_t)'SLCT')<<32 | 'RCKS')
+#define ROOT_TRACKS_DATAID (((ULong_t)'TRAC')<<32 | 'KS ')
+#define ROOT_NODELIST_DATAID (((ULong_t)'NODE')<<32 | 'LIST')
+#define ROOT_EVENTTRIGGER_DATAID (((ULong_t)'EVTT')<<32 | 'RG ')
+
+#endif
--- /dev/null
+#ifndef SPACEPOINTDATA_H
+#define SPACEPOINTDATA_H
+
+#include "AliL3RootTypes.h"
+struct AliL3SpacePointData{
+ Float_t fX;
+ Float_t fY;
+ Float_t fZ;
+ UInt_t fID; //contains slice patch and number
+ UChar_t fPadRow;
+ Float_t fXYErr;
+ Float_t fZErr;
+};
+typedef struct AliL3SpacePointData AliL3SpacePointData;
+
+
+#endif /* SPACEPOINTDATA_H */
--- /dev/null
+//Author: Anders Strand Vestbo
+//Author: Uli Frankenfeld
+//Last Modified: 06.03.2001
+
+//____________________________________
+// AliL3Track
+//
+// Base track class for L3
+
+//Changes:
+
+//14.03.01: Moved fHitNumbers from protected to private.-ASV
+// Set memory to zero in ctor.
+// Moved fNHits 2 private. Protected data members not a good idea after all.
+//19.03.01: Made the method void Set(AliL3Track) virtual.
+
+#include "AliL3RootTypes.h"
+
+#include "AliL3Logging.h"
+#include "AliL3Track.h"
+#include <math.h>
+
+ClassImp(AliL3Track)
+
+Float_t AliL3Track::BFACT = 0.0029980;
+Float_t AliL3Track::bField = 0.2;
+Double_t AliL3Track::pi=3.14159265358979323846;
+
+AliL3Track::AliL3Track()
+{
+ //Constructor
+
+ fNHits = 0;
+ fMCid = -1;
+ fKappa=0;
+ fRadius=0;
+ fCenterX=0;
+ fCenterY=0;
+ ComesFromMainVertex(false);
+ fQ = 0;
+ fPhi0=0;
+ fPsi=0;
+ fR0=0;
+ fTanl=0;
+ fZ0=0;
+ fPt=0;
+ fLength=0;
+ fIsLocal=true;
+ fRowRange[0]=0;
+ fRowRange[1]=0;
+ memset(fHitNumbers,0,174*sizeof(UInt_t));
+}
+
+void AliL3Track::Set(AliL3Track *tpt){
+
+ SetRowRange(tpt->GetFirstRow(),tpt->GetLastRow());
+ SetPhi0(tpt->GetPhi0());
+ SetKappa(tpt->GetKappa());
+ SetNHits(tpt->GetNHits());
+
+ SetFirstPoint(tpt->GetFirstPointX(),tpt->GetFirstPointY(),tpt->GetFirstPointZ());
+
+ SetLastPoint(tpt->GetLastPointX(),tpt->GetLastPointY(),tpt->GetLastPointZ());
+ SetPt(tpt->GetPt());
+ SetPsi(tpt->GetPsi());
+ SetTgl(tpt->GetTgl());
+ SetCharge(tpt->GetCharge());
+
+ SetHits(tpt->GetNHits(),(UInt_t *)tpt->GetHitNumbers());
+
+/*
+ fPhi0 = track->GetPhi0();
+ fKappa = track->GetKappa();
+
+ fRowRange[0] = track->GetFirstRow();
+ fRowRange[1] = track->GetLastRow();
+ fQ = track->GetCharge();
+ fFirstPoint[0] = track->GetFirstPointX();
+ fFirstPoint[1] = track->GetFirstPointY();
+ fFirstPoint[2] = track->GetFirstPointZ();
+ fLastPoint[0] = track->GetLastPointX();
+ fLastPoint[1] = track->GetLastPointY();
+ fLastPoint[2] = track->GetLastPointZ();
+ fPt = track->GetPt();
+ fTanl = track->GetTgl();
+ fPsi = track->GetPsi();
+ fQ = track->GetCharge();
+ fNHits = track->GetNHits();
+ memcpy(fHitNumbers,track->GetHitNumbers(),fNHits*sizeof(UInt_t));
+*/
+}
+
+
+AliL3Track::~AliL3Track()
+{
+
+}
+
+Double_t AliL3Track::GetP() const
+{
+ // Returns total momentum.
+
+ return fabs(GetPt())*sqrt(1. + GetTgl()*GetTgl());
+
+}
+
+Double_t AliL3Track::GetPseudoRapidity() const
+{
+ return 0.5 * log((GetP() + GetPz()) / (GetP() - GetPz()));
+}
+
+Double_t AliL3Track::GetEta() const
+{
+ return GetPseudoRapidity();
+}
+
+Double_t AliL3Track::GetRapidity() const
+{
+ Double_t m_pi = 0.13957;
+ return 0.5 * log((m_pi + GetPz()) / (m_pi - GetPz()));
+}
+
+void AliL3Track::CalculateHelix(){
+ //Calculate Radius, CenterX and Centery from Psi, X0, Y0
+ //
+
+ fRadius = fPt / (BFACT*bField);
+ if(fRadius) fKappa = 1./fRadius;
+ else fRadius = 999999; //just zero
+ Double_t trackPhi0 = fPsi + fQ *0.5 * pi;
+
+ fCenterX = fFirstPoint[0] - fRadius * cos(trackPhi0);
+ fCenterY = fFirstPoint[1] - fRadius * sin(trackPhi0);
+}
+
+Bool_t AliL3Track::CalculateReferencePoint(Double_t angle){
+ // Global coordinate: crossing point with y = ax+ b; a=tan(angle-Pi/2);
+ //
+ const Double_t rr=132; //position of referece plane
+ const Double_t xr = cos(angle) *rr;
+ const Double_t yr = sin(angle) *rr;
+
+ Double_t a = tan(angle-pi/2);
+ Double_t b = yr - a * xr;
+
+ Double_t pp=(fCenterX+a*fCenterY-a*b)/(1+pow(a,2));
+ Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-2*fCenterY*b+pow(b,2)-pow(fRadius,2))/(1+pow(a,2));
+
+ Double_t racine = pp*pp-qq;
+ if(racine<0) return IsPoint(kFALSE); //no Point
+
+ Double_t rootRacine = sqrt(racine);
+ Double_t x0 = pp+rootRacine;
+ Double_t x1 = pp-rootRacine;
+ Double_t y0 = a*x0 + b;
+ Double_t y1 = a*x1 + b;
+
+ Double_t diff0 = sqrt(pow(x0-xr,2)+pow(y0-yr,2));
+ Double_t diff1 = sqrt(pow(x1-xr,2)+pow(y1-yr,2));
+
+ if(diff0<diff1){
+ fPoint[0]=x0;
+ fPoint[1]=y0;
+ }
+ else{
+ fPoint[0]=x1;
+ fPoint[1]=y1;
+ }
+
+ Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
+ Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
+ if(fabs(trackPhi0-pointPhi0)>pi){
+ if(trackPhi0<pointPhi0) trackPhi0 += 2*pi;
+ else pointPhi0 += 2*pi;
+ }
+ Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
+ fPoint[2] = fFirstPoint[2] + stot * fTanl;
+
+ fPointPsi = pointPhi0 - fQ * 0.5 * pi;
+ if(fPointPsi<0.) fPointPsi+= 2*pi;
+ fPointPsi = fmod(fPointPsi, 2*pi);
+
+ return IsPoint(kTRUE);
+}
+
+Bool_t AliL3Track::CalculateEdgePoint(Double_t angle){
+ // Global coordinate: crossing point with y = ax; a=tan(angle);
+ //
+ Double_t rmin=80; //min Radius of TPC
+ Double_t rmax=260; //max Radius of TPC
+
+ Double_t a = tan(angle);
+ Double_t pp=(fCenterX+a*fCenterY)/(1+pow(a,2));
+ Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-pow(fRadius,2))/(1+pow(a,2));
+ Double_t racine = pp*pp-qq;
+ if(racine<0) return IsPoint(kFALSE); //no Point
+ Double_t rootRacine = sqrt(racine);
+ Double_t x0 = pp+rootRacine;
+ Double_t x1 = pp-rootRacine;
+ Double_t y0 = a*x0;
+ Double_t y1 = a*x1;
+
+ Double_t r0 = sqrt(pow(x0,2)+pow(y0,2));
+ Double_t r1 = sqrt(pow(x1,2)+pow(y1,2));
+ //find the right crossing point:
+ //inside the TPC modules
+ Bool_t ok0 = kFALSE;
+ Bool_t ok1 = kFALSE;
+ if(r0>rmin&&r0<rmax){
+ Double_t da=atan2(y0,x0);
+ if(da<0) da+=pi;
+ if(fabs(da-angle)<0.5)
+ ok0 = kTRUE;
+ }
+ if(r1>rmin&&r1<rmax){
+ Double_t da=atan2(y1,y1);
+ if(da<0) da+=pi;
+ if(fabs(da-angle)<0.5)
+ ok1 = kTRUE;
+ }
+ if(!(ok0||ok1)) return IsPoint(kFALSE); //no Point
+
+ if(ok0&&ok1){
+ Double_t diff0 = sqrt(pow(fFirstPoint[0]-x0,2)+pow(fFirstPoint[1]-y0,2));
+ Double_t diff1 = sqrt(pow(fFirstPoint[0]-x1,2)+pow(fFirstPoint[1]-y1,2));
+ if(diff0<diff1) ok1 = kFALSE; //use ok0
+ else ok0 = kFALSE; //use ok1
+ }
+ if(ok0){fPoint[0]=x0; fPoint[1]=y0;}
+ else {fPoint[0]=x1; fPoint[1]=y1;}
+
+ Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
+ Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
+ if(fabs(trackPhi0-pointPhi0)>pi){
+ if(trackPhi0<pointPhi0) trackPhi0 += 2*pi;
+ else pointPhi0 += 2*pi;
+ }
+ Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
+ fPoint[2] = fFirstPoint[2] + stot * fTanl;
+
+ fPointPsi = pointPhi0 - fQ * 0.5 * pi;
+ if(fPointPsi<0.) fPointPsi+= 2*pi;
+ fPointPsi = fmod(fPointPsi, 2*pi);
+
+ return IsPoint(kTRUE);
+}
+
+Bool_t AliL3Track::CalculatePoint(Double_t xplane){
+ // Local coordinate: crossing point with x plane
+ //
+ Double_t racine = pow(fRadius,2)-pow(xplane-fCenterX,2);
+ if(racine<0) return IsPoint(kFALSE);
+ Double_t rootRacine = sqrt(racine);
+
+ Double_t y0 = fCenterY + rootRacine;
+ Double_t y1 = fCenterY - rootRacine;
+ //Double_t diff0 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y0));
+ //Double_t diff1 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y1));
+ Double_t diff0 = fabs(y0-fFirstPoint[1]);
+ Double_t diff1 = fabs(y1-fFirstPoint[1]);
+
+ fPoint[0]=xplane;
+ if(diff0<diff1) fPoint[1]=y0;
+ else fPoint[1]=y1;
+
+ Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
+ Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
+ if(fabs(trackPhi0-pointPhi0)>pi){
+ if(trackPhi0<pointPhi0) trackPhi0 += 2*pi;
+ else pointPhi0 += 2*pi;
+ }
+ Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
+ fPoint[2] = fFirstPoint[2] + stot * fTanl;
+
+ fPointPsi = pointPhi0 - fQ * 0.5 * pi;
+ if(fPointPsi<0.) fPointPsi+= 2*pi;
+ fPointPsi = fmod(fPointPsi, 2*pi);
+
+ return IsPoint(kTRUE);
+}
+
--- /dev/null
+#ifndef ALIL3TRACK_H
+#define ALIL3TRACK_H
+
+#include <string.h>
+
+#include "AliL3RootTypes.h"
+
+class AliL3Track {
+
+ private:
+
+ Int_t fNHits;
+
+ Int_t fMCid; //Assigned id from MC data.
+ Double_t fKappa; // Curvature
+ Double_t fRadius; // Radius of the helix (projected to a circle)
+ Double_t fCenterX; // x coordinate of the center of the helix (projected to a circle)
+ Double_t fCenterY; // y coordinate of the center of the helix (projected to a circle)
+ Bool_t fFromMainVertex; // true if tracks origin is the main vertex, otherwise false
+
+ Int_t fRowRange[2]; //Subsector where this track was build
+ Int_t fSector; //Sector # where this track was build
+
+ //data from momentum fit
+ Int_t fQ; //charge measured fit
+
+ //track parameters:
+ Double_t fPhi0; //azimuthal angle of the first point
+ Double_t fPsi; //azimuthal angle of the momentum
+ Double_t fR0; //radius of the first point
+ Double_t fTanl; //tan of dipangle at (r,phi,z)
+ Double_t fZ0; //z coordinate of the first point
+ Double_t fPt; //transverse momentum
+ Double_t fLength;
+
+ Double_t fPterr;
+ Double_t fPsierr;
+ Double_t fZ0err;
+ Double_t fTanlerr;
+
+ Double_t fFirstPoint[3];
+ Double_t fLastPoint[3];
+ Double_t fPoint[3];
+ Double_t fPointPsi; //azimuthal angle of the momentum at Point
+ Bool_t fIsPoint; //Helix crosses the X-plane
+ Bool_t IsPoint(Bool_t ispoint) {fIsPoint = ispoint;return fIsPoint;}
+
+ Bool_t fIsLocal; //Track given in local coordinates.
+
+ UInt_t fHitNumbers[174]; //Array of hit numbers for this track
+
+ protected:
+
+ static Float_t BFACT;
+ static Float_t bField;
+ static Double_t pi;
+
+ public:
+
+ AliL3Track();
+ virtual ~AliL3Track();
+
+ virtual void Set(AliL3Track* track);
+
+ Bool_t CalculateReferencePoint(Double_t angle);//Calculate Reference Point
+ Bool_t CalculateEdgePoint(Double_t angle);//Calculate crossing point with line
+ Bool_t CalculatePoint(Double_t xplane);//Calculate crossing point with X-plane
+ Bool_t IsPoint() {return fIsPoint;}
+ void CalculateHelix();
+ Double_t GetDistance(Double_t x0,Double_t x1){return 0;}
+
+ Bool_t IsLocal() {return fIsLocal;}
+
+ // getter
+ Double_t GetFirstPointX() {return fFirstPoint[0];}
+ Double_t GetFirstPointY() {return fFirstPoint[1];}
+ Double_t GetFirstPointZ() {return fFirstPoint[2];}
+ Double_t GetLastPointX() {return fLastPoint[0];}
+ Double_t GetLastPointY() {return fLastPoint[1];}
+ Double_t GetLastPointZ() {return fLastPoint[2];}
+
+ Double_t GetPointPsi() {return fPointPsi;}
+ Double_t GetPointX() {return fPoint[0];}
+ Double_t GetPointY() {return fPoint[1];}
+ Double_t GetPointZ() {return fPoint[2];}
+
+ Double_t GetPt() const {return fPt;}
+ Double_t GetTgl() const {return fTanl;}
+ Double_t GetPhi0() const {return fPhi0;}
+ Double_t GetPsi() const {return fPsi;}
+ Double_t GetR0() const {return fR0;}
+ Double_t GetZ0() const {return fZ0;}
+
+ Double_t GetKappa() const { return fKappa;}
+ Double_t GetRadius() const { return fRadius;}
+ Double_t GetCenterX() const { return fCenterX;}
+ Double_t GetCenterY() const { return fCenterY;}
+
+ Int_t GetNHits() {return fNHits;}
+ Int_t GetNumberOfPoints() const {return fNHits;}
+ Bool_t ComesFromMainVertex() const { return fFromMainVertex;}
+
+ Double_t GetPx() const { return fPt*cos(fPsi);}
+ Double_t GetPy() const { return fPt*sin(fPsi);}
+ Double_t GetPz() const { return fPt*fTanl;}
+
+ Double_t GetP() const;
+ Double_t GetPseudoRapidity() const;
+ Double_t GetEta() const;
+ Double_t GetRapidity() const;
+
+ Int_t GetCharge() const { return fQ;}
+ Int_t GetMCid() const {return fMCid;}
+ Double_t GetLength() const {return fLength;}
+
+ Int_t GetFirstRow() const {return fRowRange[0];}
+ Int_t GetLastRow() const {return fRowRange[1];}
+
+ UInt_t *GetHitNumbers() {return fHitNumbers;}
+
+ // setter
+ void SetMCid(Int_t f) {fMCid = f;}
+ void SetFirstPoint(Double_t f,Double_t g,Double_t h) {fFirstPoint[0]=f; fFirstPoint[1]=g; fFirstPoint[2]=h;}
+ void SetLastPoint(Double_t f,Double_t g,Double_t h) {fLastPoint[0]=f; fLastPoint[1]=g; fLastPoint[2]=h;}
+
+ void SetHits(Int_t nhits,UInt_t *hits) {memcpy(fHitNumbers,hits,nhits*sizeof(UInt_t));}
+
+ void SetPhi0(Double_t f) {fPhi0 = f;}
+ void SetPsi(Double_t f) {fPsi = f;}
+ void SetR0(Double_t f) {fR0 = f;}
+ void SetTgl(Double_t f) {fTanl =f;}
+ void SetZ0(Double_t f) {fZ0 = f;}
+ void SetPt(Double_t f) {fPt = f;}
+ void SetLength(Double_t f) {fLength = f;}
+ void SetPterr(Double_t f) {fPterr = f;}
+ void SetPsierr(Double_t f) {fPsierr = f;}
+ void SetZ0err(Double_t f) {fZ0err = f;}
+ void SetTglerr(Double_t f) {fTanlerr = f;}
+ void SetKappa(Double_t f) {fKappa = f;}
+
+ void SetNHits(Int_t f) {fNHits = f;}
+
+ void SetRowRange(Int_t f,Int_t g) {fRowRange[0]=f; fRowRange[1]=g;}
+ void SetSector(Int_t f) {fSector = f;}
+
+ void SetRadius(Double_t f) { fRadius = f; }
+ void SetCenterX(Double_t f) { fCenterX = f; }
+ void SetCenterY(Double_t f) { fCenterY = f; }
+
+ void SetCharge(Int_t f) { fQ = f; }
+
+ void ComesFromMainVertex(Bool_t f) { fFromMainVertex = f; }
+
+ ClassDef(AliL3Track,1) //Conformal mapping track class
+};
+
+#endif
+
--- /dev/null
+//Author: Uli Frankenfeld
+//Last Modified: 06.12.2000
+
+#include <math.h>
+#include <string.h>
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3TrackArray.h"
+#include "AliL3HoughTrack.h"
+#include "AliL3ConfMapTrack.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3Transform.h"
+#include "AliL3ConfMapPoint.h"
+//_____________________________________________________________
+//
+// The L3 TrackArray
+//
+
+ClassImp(AliL3TrackArray)
+
+AliL3TrackArray::AliL3TrackArray(){
+ //Default constructor
+ fSize = 0;
+ fNTracks=0;
+ fNAbsent=0;
+ fTrackType='t';
+ SetSize();
+}
+
+
+AliL3TrackArray::AliL3TrackArray(Int_t ntrack){
+ //Constructor.
+ fSize = 0;
+ fNTracks=0;
+ fNAbsent=0;
+ fTrackType='t';
+ SetSize(ntrack);
+}
+
+AliL3TrackArray::AliL3TrackArray(char* tracktype,Int_t ntrack){
+ //Constructor.
+ fSize = 0;
+ fNTracks=0;
+ fNAbsent=0;
+ if(strcmp(tracktype,"AliL3Track")==0) fTrackType='t';
+ if(strcmp(tracktype,"AliL3ConfMapTrack")==0) fTrackType='c';
+ if(strcmp(tracktype,"AliL3HoughTrack")==0) fTrackType='h';
+ SetSize(ntrack);
+}
+
+AliL3TrackArray::AliL3TrackArray(char* tracktype){
+ //Constructor.
+ fSize = 0;
+ fNTracks=0;
+ fNAbsent=0;
+ if(strcmp(tracktype,"AliL3Track")==0) fTrackType='t';
+ if(strcmp(tracktype,"AliL3ConfMapTrack")==0) fTrackType='c';
+ if(strcmp(tracktype,"AliL3HoughTrack")==0) fTrackType='h';
+ SetSize();
+}
+
+
+AliL3TrackArray::~AliL3TrackArray(){
+ //Destructor
+ DeleteArray();
+}
+
+
+AliL3Track *AliL3TrackArray::NextTrack(){
+ if(fNTracks<fSize) return fTrack[fNTracks++];
+ SetSize(fSize+100);
+ return fTrack[fNTracks++];
+}
+
+void AliL3TrackArray::DeleteArray(){
+ for(Int_t i=0; i<fSize;i++)
+ delete fTrack[i];
+ delete[] fIsPresent;
+ delete[] fTrack;
+}
+
+Bool_t AliL3TrackArray::SetSize(Int_t newsize){
+ if(newsize<=fSize) return kFALSE; //shrink comes later!!
+ if(!fSize){
+ fSize = newsize;
+ fTrack = new AliL3Track*[fSize];
+ fIsPresent = new Bool_t[fSize];
+ switch(fTrackType){
+ case 't':
+ for(Int_t i=0;i<fSize;i++){
+ fTrack[i] = new AliL3Track();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ case 'c':
+ for(Int_t i=0;i<fSize;i++){
+ fTrack[i] = new AliL3ConfMapTrack();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ case 'h':
+ for(Int_t i=0;i<fSize;i++){
+ fTrack[i] = new AliL3HoughTrack();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ default:
+ return kFALSE;
+ }
+ return kTRUE;
+ }
+ AliL3Track **tmp = new AliL3Track*[fSize];
+ Bool_t *pre = new Bool_t[fSize];
+ for(Int_t i=0; i<fSize;i++){
+ tmp[i] = fTrack[i];
+ pre[i] = fIsPresent[i];
+ }
+ delete[] fTrack;
+ delete[] fIsPresent;
+ fTrack = new AliL3Track*[fSize];
+ fIsPresent = new Bool_t[newsize];
+ for(Int_t i=0; i<fSize;i++){
+ fTrack[i] = tmp[i];
+ fIsPresent[i] = pre[i];
+ }
+ delete[] tmp;
+ delete[] pre;
+ switch(fTrackType){
+ case 't':
+ for(Int_t i=fSize;i<newsize;i++){
+ fTrack[i] = new AliL3Track();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ case 'c':
+ for(Int_t i=fSize;i<newsize;i++){
+ fTrack[i] = new AliL3ConfMapTrack();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ case 'h':
+ for(Int_t i=fSize;i<newsize;i++){
+ fTrack[i] = new AliL3HoughTrack();
+ fIsPresent[i] = kTRUE;
+ }
+ break;
+ default:
+ return kFALSE;
+ }
+ fSize = newsize;
+ return kTRUE;
+}
+
+void AliL3TrackArray::Reset(){
+ fNTracks=0;
+ fNAbsent=0;
+ for(Int_t i=0; i<fSize;i++)
+ fIsPresent[i] = kTRUE;
+}
+
+void AliL3TrackArray::Remove(Int_t track){
+ if(fIsPresent[track]){
+ fIsPresent[track]=kFALSE;
+ fNAbsent++;
+ }
+}
+
+void AliL3TrackArray::FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr){
+ //Read tracks from shared memory (or memory)
+ AliL3TrackSegmentData *trs = tr;
+ for(Int_t i=0; i<ntracks; i++){
+ AliL3Track *track = NextTrack();
+ track->SetPt(trs->fPt);
+ track->SetPsi(trs->fPsi);
+ track->SetTgl(trs->fTgl);
+ track->SetNHits(trs->fNPoints);
+ track->SetCharge(trs->fCharge);
+ track->SetFirstPoint(trs->fX,trs->fY,trs->fZ);
+ track->SetLastPoint(trs->fLastX,trs->fLastY,trs->fLastZ);
+ track->SetHits( trs->fNPoints, trs->fPointIDs );
+ UChar_t *tmpP = (UChar_t*)trs;
+ tmpP += sizeof(AliL3TrackSegmentData)+trs->fNPoints*sizeof(UInt_t);
+ trs = (AliL3TrackSegmentData*)tmpP;
+ }
+}
+
+void AliL3TrackArray::FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr,Int_t slice, AliL3Transform* trans){
+ //Read tracks from shared memory (or memory)
+ AliL3TrackSegmentData *trs = tr;
+ for(Int_t i=0; i<ntracks; i++){
+ AliL3Track *track = NextTrack();
+ track->SetPt(trs->fPt);
+ Float_t psi[1];
+ psi[0]=trs->fPsi;
+ trans->Local2GlobalAngle(psi,slice);
+ track->SetPsi(psi[0]);
+ track->SetTgl(trs->fTgl);
+ track->SetNHits(trs->fNPoints);
+ track->SetCharge(trs->fCharge);
+ Float_t first[3];
+ first[0]=trs->fX;first[1]=trs->fY;first[2]=trs->fZ;
+ trans->Local2Global(first,slice);
+ track->SetFirstPoint(first[0],first[1],first[2]);
+ Float_t last[3];
+ last[0]=trs->fLastX;last[1]=trs->fLastY;last[2]=trs->fLastZ;
+ trans->Local2Global(last,slice);
+ track->SetLastPoint(last[0],last[1],last[2]);
+ track->SetHits( trs->fNPoints, trs->fPointIDs );
+ UChar_t *tmpP = (UChar_t*)trs;
+ tmpP += sizeof(AliL3TrackSegmentData)+trs->fNPoints*sizeof(UInt_t);
+ trs = (AliL3TrackSegmentData*)tmpP;
+ }
+}
+
+UInt_t AliL3TrackArray::GetOutSize(){
+ UInt_t count = GetOutCount(); //use only present tracks
+ UInt_t tHits = 0;
+ for(Int_t i=0;i<fNTracks;i++){ //loop over all tracks
+ AliL3Track *track = GetCheckedTrack(i); //use only present tracks
+ if(track) //use only present tracks
+ tHits += track->GetNHits();
+ }
+
+ //calculate size of track
+ return count*sizeof(AliL3TrackSegmentData)+sizeof(UInt_t)*tHits;
+}
+
+UInt_t AliL3TrackArray::WriteTracks(UInt_t & ntracks,AliL3TrackSegmentData* tr){
+ ntracks = GetOutCount();
+ return WriteTracks(tr);
+}
+
+UInt_t AliL3TrackArray::WriteTracks(AliL3TrackSegmentData* tr){
+ if(GetTrackType()=='c') return WriteConfMapTracks(tr);
+ AliL3TrackSegmentData *tP = tr;
+ UInt_t *pP;
+ UInt_t size = 0;
+ for(Int_t i=0; i<fNTracks; i++){ //loop over all tracks
+ AliL3Track *track = GetCheckedTrack(i); //use only present tracks
+ if(!track) continue; //use only present tracks
+ tP->fX = track->GetFirstPointX();
+ tP->fY = track->GetFirstPointY();
+ tP->fZ = track->GetFirstPointZ();
+ tP->fPt = track->GetPt();
+ tP->fLastX = track->GetLastPointX();
+ tP->fLastY = track->GetLastPointY();
+ tP->fLastZ = track->GetLastPointZ();
+ tP->fPsi = track->GetPsi();
+ tP->fTgl = track->GetTgl();
+ tP->fCharge = track->GetCharge();
+ tP->fNPoints = track->GetNHits();
+ pP = (UInt_t*)track->GetHitNumbers();
+ for (UInt_t j=0;j<tP->fNPoints;j++){
+ tP->fPointIDs[j] = pP[j];
+ }
+ Byte_t *tmpP = (Byte_t *)tP;
+ tmpP += sizeof(AliL3TrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
+ size += sizeof(AliL3TrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
+ tP = (AliL3TrackSegmentData*)tmpP;
+ }
+ return size;
+}
+
+UInt_t AliL3TrackArray::WriteConfMapTracks(AliL3TrackSegmentData* tr){
+ // use first and last point objects
+ AliL3TrackSegmentData *tP = tr;
+ UInt_t *pP;
+ UInt_t size = 0;
+ for(Int_t i=0; i<fNTracks; i++){ //loop over all tracks
+ AliL3ConfMapTrack *track =(AliL3ConfMapTrack *) GetCheckedTrack(i); //use only present tracks
+ if(!track) continue; //use only present tracks
+ AliL3ConfMapPoint *hit = (AliL3ConfMapPoint*)track->lastHit;
+ AliL3ConfMapPoint *lastHit = (AliL3ConfMapPoint*)track->firstHit;
+ tP->fX = hit->GetX();
+ tP->fY = hit->GetY();
+ tP->fZ = hit->GetZ();
+ tP->fLastX = lastHit->GetX();
+ tP->fLastY = lastHit->GetY();
+ tP->fLastZ = lastHit->GetZ();
+
+// tP->fX = track->GetFirstPointX();
+// tP->fY = track->GetFirstPointY();
+// tP->fZ = track->GetFirstPointZ();
+ tP->fPt = track->GetPt();
+// tP->fLastX = track->GetLastPointX();
+// tP->fLastY = track->GetLastPointY();
+// tP->fLastZ = track->GetLastPointZ();
+ tP->fPsi = track->GetPsi();
+ tP->fTgl = track->GetTgl();
+ tP->fCharge = track->GetCharge();
+ tP->fNPoints = track->GetNHits();
+ pP = (UInt_t*)track->GetHitNumbers();
+ for (UInt_t j=0;j<tP->fNPoints;j++){
+ tP->fPointIDs[j] = pP[j];
+ }
+ Byte_t *tmpP = (Byte_t *)tP;
+ tmpP += sizeof(AliL3TrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
+ size +=sizeof(AliL3TrackSegmentData)+tP->fNPoints*sizeof(UInt_t);
+ tP = (AliL3TrackSegmentData*)tmpP;
+ }
+ return size;
+}
+
+void AliL3TrackArray::AddTracks(AliL3TrackArray *newtrack){
+ if(GetTrackType() != newtrack->GetTrackType())
+ return;
+ if(fSize < fNTracks+newtrack->GetNPresent())
+ SetSize(fSize+newtrack->GetSize());
+ for(Int_t i =0;i<newtrack->GetNTracks();i++){
+ AliL3Track *tpt = newtrack->GetCheckedTrack(i);
+ if(!tpt) continue;
+ newtrack->Remove(i);
+ AliL3Track *track = NextTrack();
+ track->SetNHits(tpt->GetNHits());
+ track->SetHits(tpt->GetNHits(),(UInt_t *)tpt->GetHitNumbers());
+ track->SetFirstPoint(tpt->GetFirstPointX(),tpt->GetFirstPointY(),tpt->GetFirstPointZ());
+ track->SetLastPoint(tpt->GetLastPointX(),tpt->GetLastPointY(),tpt->GetLastPointZ());
+ track->SetPt(tpt->GetPt());
+ track->SetPsi(tpt->GetPsi());
+ track->SetTgl(tpt->GetTgl());
+ track->SetCharge(tpt->GetCharge());
+ }
+}
+
+
+void AliL3TrackArray::Compress(){
+ if(GetNPresent()==GetNTracks()) return;
+ AliL3Track **tmp = new AliL3Track *[fNTracks];
+ Int_t present=0;
+ Int_t absent=GetNPresent();
+ for(Int_t i=0;i<GetNTracks();i++){
+ if(fIsPresent[i]) tmp[present++] = fTrack[i];
+ else tmp[absent++] = fTrack[i];
+ }
+ for(Int_t i=0;i<GetNTracks();i++)
+ fIsPresent[i]=kTRUE;
+
+ //Copy pointers back
+ for(Int_t i=0; i<GetNTracks();i++){
+ fTrack[i]=tmp[i];
+ }
+
+ delete[] tmp;
+
+ fNTracks = GetNPresent();
+ fNAbsent = 0;
+}
+
+void AliL3TrackArray::QSort(){
+ // compress an sort
+ Compress();
+ QSort(fTrack,0,fNTracks);
+}
+
+ void AliL3TrackArray::QSort( AliL3Track **a, Int_t first, Int_t last){
+
+ // Sort array of AliL3Track pointers using a quicksort algorithm.
+ // Uses TrackCompare() to compare objects.
+ // Thanks to Root!
+
+ static AliL3Track *tmp;
+ static int i; // "static" to save stack space
+ int j;
+
+ while (last - first > 1) {
+ i = first;
+ j = last;
+ for (;;) {
+ while (++i < last && TrackCompare(a[i], a[first]) < 0)
+ ;
+ while (--j > first && TrackCompare(a[j], a[first]) > 0)
+ ;
+ if (i >= j)
+ break;
+
+ tmp = a[i];
+ a[i] = a[j];
+ a[j] = tmp;
+ }
+ if (j == first) {
+ ++first;
+ continue;
+ }
+ tmp = a[first];
+ a[first] = a[j];
+ a[j] = tmp;
+ if (j - first < last - (j + 1)) {
+ QSort(a, first, j);
+ first = j + 1; // QSort(j + 1, last);
+ } else {
+ QSort(a, j + 1, last);
+ last = j; // QSort(first, j);
+ }
+ }
+}
+
+Int_t AliL3TrackArray::TrackCompare(AliL3Track *a, AliL3Track *b){
+ // Compare the two tracks.
+
+ if(a->GetNHits() < b->GetNHits()) return 1;
+ if(a->GetNHits() > b->GetNHits()) return -1;
+ return 0;
+}
+
+
--- /dev/null
+#ifndef ALIL3TRACKARRAY_H
+#define ALIL3TRACKARRAY_H
+
+#include "AliL3RootTypes.h"
+class AliL3ConfMapTrack;
+class AliL3Track;
+class AliL3TrackSegmentData;
+class AliL3Transform;
+
+class AliL3TrackArray{
+ private:
+ void DeleteArray();
+
+ Char_t fTrackType;
+ Int_t fSize;
+ Bool_t *fIsPresent;//!
+ Int_t fNAbsent;
+
+ AliL3Track **fTrack;//!
+ Int_t fNTracks;
+
+ UInt_t WriteConfMapTracks(AliL3TrackSegmentData* tr);
+
+ public:
+ AliL3TrackArray();
+ AliL3TrackArray(Int_t ntrack);
+ AliL3TrackArray(char* tracktype,Int_t ntrack);
+ AliL3TrackArray(char* tracktype);
+ virtual ~AliL3TrackArray();
+ Int_t GetTrackType(){return fTrackType;}
+ Int_t GetSize(){return fSize;}
+ Bool_t SetSize(Int_t newsize=2000);
+
+ Int_t GetNPresent(){return (fNTracks- fNAbsent);}
+
+ Int_t GetNTracks(){return fNTracks;}
+ AliL3Track *NextTrack();
+ AliL3Track *GetCheckedTrack(Int_t t){if(fIsPresent[t]) return fTrack[t]; return 0;}
+ AliL3Track *GetTrack(Int_t t){return fTrack[t];}
+
+ void Remove(Int_t track);
+ void RemoveLast() {fNTracks--;}
+ void Compress();
+ void Reset();
+ void QSort();
+ void QSort( AliL3Track **a, Int_t first, Int_t last);
+ Int_t TrackCompare(AliL3Track *a, AliL3Track *b);
+
+
+ void FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr,Int_t slice,
+ AliL3Transform* trans); //Fill tracks and transform
+ void FillTracks(Int_t ntracks, AliL3TrackSegmentData* tr); //Fill tracks
+ UInt_t WriteTracks(AliL3TrackSegmentData* tr); //Write tracks
+ UInt_t WriteTracks(UInt_t & ntracks,AliL3TrackSegmentData* tr); //Write tracks
+ UInt_t GetOutSize();
+ UInt_t GetOutCount(){return (UInt_t) GetNPresent();}
+ void AddTracks(AliL3TrackArray *newtrack);//add all Tracks to this
+
+ ClassDef(AliL3TrackArray,1)
+};
+
+#endif
--- /dev/null
+
+//Author: Uli Frankenfeld
+//Last Modified: 06.12.2000
+
+#include <math.h>
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3TrackMerger.h"
+#include "AliL3Track.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3Transform.h"
+#include "AliL3TrackArray.h"
+
+//_____________________________________________________________
+//
+// The L3 track segment merger
+//
+
+ClassImp(AliL3TrackMerger)
+
+AliL3TrackMerger::AliL3TrackMerger(){
+ //Default constructor
+ Is2Global(kFALSE);
+ fSlow = kFALSE;
+ SetParameter();
+// fRowMin = 0;
+// fRowMax = 0;
+}
+
+
+AliL3TrackMerger::AliL3TrackMerger(Int_t nsubsectors):AliL3Merger(nsubsectors){
+ //Constructor.
+ fNSubSector = nsubsectors;
+ Is2Global(kFALSE);
+ fSlow = kFALSE;
+ SetParameter();
+ //fRowMin = new Int_t(nsubsectors);
+ //fRowMax = new Int_t(nsubsectors);
+}
+
+AliL3TrackMerger::~AliL3TrackMerger(){
+ //Destructor
+}
+
+void AliL3TrackMerger::SetRows(Int_t *row){
+ for(Int_t i =0;i<fNSubSector;i++){
+ fRowMin[i]=*(row+(2*i));
+ fRowMax[i]=*(row+(2*i+1));
+ }
+}
+
+void AliL3TrackMerger::InitSector(Int_t slice,Int_t subsector){
+ //
+ // Select Sector and subsector. The following FillTracks call will
+ // fill this subsector
+ //
+ fSlice = slice;
+ fSubSector = subsector;
+ fCurrentTracks = fSubSector;
+}
+
+void AliL3TrackMerger::SlowMerge(AliL3TrackArray *mergedtrack,AliL3TrackArray *tracksin,AliL3TrackArray *tracksout,Double_t xval){
+ void *ntuple=GetNtuple();
+ const Int_t kNOut=tracksout->GetNTracks();
+ const Int_t kNIn =tracksin->GetNTracks();
+ const Int_t kNMerged =mergedtrack->GetNTracks();
+ AliL3Track *tracks[2];
+ Bool_t merge = kTRUE;
+ while(merge){
+ Int_t inmin=-1,outmin=-1;
+ Double_t min=10;
+ for(Int_t out=0;out<kNOut;out++){
+ AliL3Track *outertrack=tracksout->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ AliL3Track *innertrack=tracksin->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ Double_t diff = TrackDiff(innertrack,outertrack);
+ if(diff>=0&&diff<min){
+ min=diff;
+ inmin=in;
+ outmin=out;
+ }
+ }
+ }
+ if(inmin>=0&&outmin>=0){
+ AliL3Track *outertrack=tracksout->GetTrack(outmin);
+ AliL3Track *innertrack=tracksin->GetTrack(inmin);
+ tracks[0]=innertrack;
+ tracks[1]=outertrack;
+ SortTracks(tracks,2);
+ MultiMerge(mergedtrack,tracks,2);
+ outertrack->CalculatePoint(xval);
+ innertrack->CalculatePoint(xval);
+ PrintDiff(innertrack,outertrack);
+ FillNtuple(ntuple,innertrack,outertrack);
+ tracksout->Remove(outmin);
+ tracksin->Remove(inmin);
+// tracksout->Compress();
+// tracksin->Compress();
+ }
+ else merge = kFALSE;
+ }
+ LOG(AliL3Log::kInformational,"AliL3TrackMerger::SlowMerge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "
+ <<mergedtrack->GetNTracks()-kNMerged<<ENDLOG;
+ char name[256] = "ntuple_t.root";
+ for(Int_t i=0;i<4;i++)
+ if(tracksin==GetInTracks(i))
+ sprintf(name,"ntuple_t_%d.root",i);
+ WriteNtuple(name,ntuple);
+}
+
+void AliL3TrackMerger::SlowMerge(){
+ fSlow = kTRUE;
+ Merge();
+}
+
+void AliL3TrackMerger::InterMerge(){
+
+ for(Int_t patch=0;patch< GetNIn();patch++){
+ AliL3TrackArray * tracks = GetInTracks(patch);
+ Double_t xval = fTransformer->Row2X((fRowMax[patch]+fRowMin[patch])/2);
+ Int_t nrow= fRowMax[patch]-fRowMin[patch]+1;
+ const Int_t kNIn =tracks->GetNTracks();
+ AliL3Track *tr[2];
+ for(Int_t in=0;in<kNIn;in++){
+ AliL3Track *t = tracks->GetCheckedTrack(in);
+ if(t){
+ t->CalculateHelix();
+ t->CalculatePoint(xval);
+ }
+ }
+ for(Int_t out=0;out<kNIn;out++){
+ AliL3Track *outertrack=tracks->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ if(in==out) continue;
+ AliL3Track *innertrack=tracks->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+ if(IsTrack(innertrack,outertrack)){
+ tr[0]=innertrack;
+ tr[1]=outertrack;
+ SortTracks(tr,2);
+ if(tr[0]->GetLastPointX()<tr[1]->GetFirstPointX()){
+ MultiMerge(tracks,tr,2);
+ tracks->Remove(out);
+ tracks->Remove(in);
+ break;
+ }
+ }
+ }
+ }
+ Int_t nmerged = tracks->GetNTracks()-kNIn;
+ LOG(AliL3Log::kInformational,"AliL3TrackMerger::InterMerge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "<<nmerged<<ENDLOG;
+ }
+}
+
+void AliL3TrackMerger::Merge(){
+ //Loop over tracks and pass them to the track merger.
+ Double_t edge0 = PI/18.;
+ Double_t edge1 = 2*PI - edge0;
+ AliL3TrackArray *ttt = GetOutTracks();
+ if(fNSubSector==1) {
+ GetOutTracks()->AddTracks(GetInTracks(0));
+ LOG(AliL3Log::kInformational,"AliL3TrackMerger::Merge","Result")
+ <<AliL3Log::kDec<<"Total Copied Tracks: "<<GetOutTracks()->GetNPresent()
+ <<ENDLOG;
+ return;
+ }
+ Int_t subsec = fNSubSector -2;
+ for(Int_t i=subsec;i>=0;i--){
+ AliL3TrackArray *tout = GetOutTracks();
+ if(i==subsec) tout = GetInTracks(subsec+1);
+ AliL3TrackArray *tin = GetInTracks(i);
+ Double_t xval = fTransformer->Row2X(fRowMax[i]);
+ Double_t xmax = fTransformer->Row2X(fRowMax[i+1]);
+ Double_t ymax = xval*tan(edge0);
+ for(Int_t out=0;out<tout->GetNTracks();out++){
+ AliL3Track *outtrack=tout->GetCheckedTrack(out);
+ if(!outtrack) continue;
+ outtrack->CalculateHelix();
+ outtrack->CalculatePoint(xval);
+ if(outtrack->IsPoint()&&fabs(outtrack->GetPointY())>ymax){
+ if(outtrack->GetNHits()<10)
+ tout->Remove(out);
+ }
+ }
+// tout->Compress();
+ for(Int_t in=0;in<tin->GetNTracks();in++){
+ AliL3Track *intrack=(AliL3Track*)tin->GetTrack(in);
+ intrack->CalculateHelix();
+ intrack->CalculatePoint(xval);
+ }
+ tin->QSort();
+ tout->QSort();
+
+ if(fSlow) SlowMerge(ttt,tin,tout,xval);
+ else Merge(ttt,tin,tout);
+ for(Int_t in=0;in<tin->GetNTracks();in++){
+ AliL3Track *intrack=(AliL3Track*)tin->GetCheckedTrack(in);
+ if(!intrack) continue;
+ if(intrack->CalculateEdgePoint(edge0)){
+ if(intrack->GetPointX()<xmax ){
+ AddTrack(ttt,intrack);
+ tin->Remove(in);
+ }
+ }
+ else if(intrack->CalculateEdgePoint(edge1)){
+ if(intrack->GetPointX()<xmax ){
+ AddTrack(ttt,intrack);
+ tin->Remove(in);
+ }
+ }
+ }
+/*
+ for(Int_t in=0;in<tin->GetNTracks();in++){
+ AliL3Track *intrack=(AliL3Track*)tin->GetCheckedTrack(in);
+ if(!intrack) continue;
+ if(intrack->GetNHits()<10) continue;
+ AddTrack(ttt,intrack);
+ tin->Remove(in);
+ }
+*/
+ } // end subsector loop
+ LOG(AliL3Log::kInformational,"AliL3TrackMerger::Merge","Result")
+ <<AliL3Log::kDec<<"Total Merged Tracks: "<<GetOutTracks()->GetNPresent()
+ <<ENDLOG;
+}
+
+Int_t AliL3TrackMerger::Merge(AliL3TrackArray* mergedtrack,AliL3TrackArray *tracksin,AliL3TrackArray *tracksout){
+ //Loop over tracks and pass them to the track merger.
+ AliL3Track *tracks[2];
+
+ const Int_t kNOut=tracksout->GetNTracks();
+ const Int_t kNIn =tracksin->GetNTracks();
+ const Int_t kNMerged =mergedtrack->GetNTracks();
+
+ Bool_t *ismatchedin = new Bool_t[kNIn];
+ for(Int_t in =0;in<kNIn;in++)
+ ismatchedin[in]=kFALSE;
+ Bool_t *ismatchedout = new Bool_t[kNOut];
+ for(Int_t out =0;out<kNOut;out++)
+ ismatchedout[out] = kFALSE;
+ for(Int_t out =0;out<kNOut;out++){
+ AliL3Track *outertrack=(AliL3Track*)tracksout->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in =0;in<kNIn;in++){
+ if(ismatchedin[in]) continue;
+ AliL3Track *innertrack=(AliL3Track*)tracksin->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack==innertrack) continue;
+ if(outertrack->GetCharge()!=innertrack->GetCharge()) continue;
+ if(IsTrack(innertrack,outertrack)){
+ tracks[0]=innertrack; tracks[1]=outertrack;
+ SortTracks(tracks,2);
+ if(tracks[0]->GetLastPointX()<tracks[1]->GetFirstPointX()){
+ MultiMerge(mergedtrack,tracks,2);
+ tracksout->Remove(out);
+ tracksin->Remove(in);
+ ismatchedin[in]=kTRUE;
+ ismatchedout[out]=kTRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ Int_t nmerged = mergedtrack->GetNTracks()-kNMerged;
+ LOG(AliL3Log::kInformational,"AliL3TrackMerger::Merge","Result")
+ <<AliL3Log::kDec<<"Merged Tracks: "<<nmerged<<ENDLOG;
+ delete[] ismatchedin;
+ delete[] ismatchedout;
+ return nmerged;
+}
+
+
--- /dev/null
+#ifndef ALIL3TRACKMERGER_H
+#define ALIL3TRACKMERGER_H
+
+
+#ifndef __CINT__
+#include "AliL3Merger.h"
+#endif
+
+class AliL3Merger;
+
+class AliL3TrackMerger : public AliL3Merger {
+
+ private:
+
+ Int_t fSubSector;
+ Int_t fNSubSector;
+ Int_t fRowMin[5];
+ Int_t fRowMax[5];
+ Bool_t fSlow;
+ void SlowMerge(AliL3TrackArray *mergedtrack,AliL3TrackArray *tracksin,AliL3TrackArray *tracksout,Double_t xval);
+ Int_t Merge(AliL3TrackArray *mergedtrack,AliL3TrackArray *tracksin,AliL3TrackArray *tracksout);
+ public:
+ AliL3TrackMerger();
+ AliL3TrackMerger(Int_t nsubsectors);
+ virtual ~AliL3TrackMerger();
+
+ void SetRows(Int_t *row);
+ void InitSector(Int_t sector,Int_t subsector);
+ void SlowMerge();
+ void Merge(); //Loop over tracks from different subsectors
+ void InterMerge();
+
+ ClassDef(AliL3TrackMerger,1)
+};
+
+#endif
--- /dev/null
+#ifndef _ALIL3TRACKSEGMENTDATA_H_
+#define _ALIL3TRACKSEGMENTDATA_H_
+
+#include "AliL3RootTypes.h"
+
+struct AliL3TrackSegmentData
+ {
+ Float_t fX;
+ Float_t fY;
+ Float_t fZ;
+ Float_t fLastX;
+ Float_t fLastY;
+ Float_t fLastZ;
+ Double_t fPt;
+ Double_t fPsi;
+ Double_t fTgl;
+ Int_t fCharge;
+ UInt_t fNPoints;
+ UInt_t fPointIDs[0];
+ };
+
+typedef struct AliL3TrackSegmentData AliL3TrackSegmentData;
+
+
+
+
+#endif /* _ALIL3TRACKSEGMENTDATA_H_ */
--- /dev/null
+
+//Author: Anders Strand Vestbo
+//Author: Uli Frankenfeld
+//Last Modified: 05.12.2000
+
+#include "AliL3Logging.h"
+#include "AliL3Transform.h"
+//#include <TFile.h>
+#include <math.h>
+//___________________________
+// AliL3Transform
+//
+// Transformation class for ALICE TPC.
+
+ClassImp(AliL3Transform);
+
+
+AliL3Transform::AliL3Transform(){
+ //constructor
+ Init();
+}
+
+
+AliL3Transform::~AliL3Transform(){
+}
+
+void AliL3Transform::Init(){
+ //sector:
+ fNTimeBins = 512; //?uli
+ fNRowLow = 55;
+ fNRowUp = 119;
+ fNSectorLow = 36;
+ fNSectorUp = 36;
+ fNSector = 72;
+ fPadPitchWidthLow = 0.400000;
+ fPadPitchWidthUp = 0.600000;
+ fZWidth = 0.56599998474121093750;
+ fZSigma = 0.22880849748219134199;
+
+ //slices:
+ fNSlice = 36;
+ fNRow = 174;
+ fPi = 3.14159265358979323846;
+ for(Int_t i=0;i<36;i++){
+ fCos[i] = cos(fPi/9*i);
+ fSin[i] = sin(fPi/9*i);
+ }
+
+ fX[0] = 88.850006103515625;
+ fX[1] = 89.600006103515625;
+ fX[2] = 90.350006103515625;
+ fX[3] = 91.100006103515625;
+ fX[4] = 91.850006103515625;
+ fX[5] = 92.600006103515625;
+ fX[6] = 93.350006103515625;
+ fX[7] = 94.100006103515625;
+ fX[8] = 94.850006103515625;
+ fX[9] = 95.600006103515625;
+ fX[10] = 96.350006103515625;
+ fX[11] = 97.100006103515625;
+ fX[12] = 97.850006103515625;
+ fX[13] = 98.600006103515625;
+ fX[14] = 99.350006103515625;
+ fX[15] = 100.100006103515625;
+ fX[16] = 100.850006103515625;
+ fX[17] = 101.600006103515625;
+ fX[18] = 102.350006103515625;
+ fX[19] = 103.100006103515625;
+ fX[20] = 103.850006103515625;
+ fX[21] = 104.600006103515625;
+ fX[22] = 105.350006103515625;
+ fX[23] = 106.100006103515625;
+ fX[24] = 106.850006103515625;
+ fX[25] = 107.600006103515625;
+ fX[26] = 108.350006103515625;
+ fX[27] = 109.100006103515625;
+ fX[28] = 109.850006103515625;
+ fX[29] = 110.600006103515625;
+ fX[30] = 111.350006103515625;
+ fX[31] = 112.100006103515625;
+ fX[32] = 112.850006103515625;
+ fX[33] = 113.600006103515625;
+ fX[34] = 114.350006103515625;
+ fX[35] = 115.100006103515625;
+ fX[36] = 115.850006103515625;
+ fX[37] = 116.600006103515625;
+ fX[38] = 117.350006103515625;
+ fX[39] = 118.100006103515625;
+ fX[40] = 118.850006103515625;
+ fX[41] = 119.600006103515625;
+ fX[42] = 120.350006103515625;
+ fX[43] = 121.100006103515625;
+ fX[44] = 121.850006103515625;
+ fX[45] = 122.600006103515625;
+ fX[46] = 123.350006103515625;
+ fX[47] = 124.100006103515625;
+ fX[48] = 124.850006103515625;
+ fX[49] = 125.600006103515625;
+ fX[50] = 126.350006103515625;
+ fX[51] = 127.100006103515625;
+ fX[52] = 127.850006103515625;
+ fX[53] = 128.600006103515625;
+ fX[54] = 129.350006103515625;
+ fX[55] = 132.574996948242188;
+ fX[56] = 133.574996948242188;
+ fX[57] = 134.574996948242188;
+ fX[58] = 135.574996948242188;
+ fX[59] = 136.574996948242188;
+ fX[60] = 137.574996948242188;
+ fX[61] = 138.574996948242188;
+ fX[62] = 139.574996948242188;
+ fX[63] = 140.574996948242188;
+ fX[64] = 141.574996948242188;
+ fX[65] = 142.574996948242188;
+ fX[66] = 143.574996948242188;
+ fX[67] = 144.574996948242188;
+ fX[68] = 145.574996948242188;
+ fX[69] = 146.574996948242188;
+ fX[70] = 147.574996948242188;
+ fX[71] = 148.574996948242188;
+ fX[72] = 149.574996948242188;
+ fX[73] = 150.574996948242188;
+ fX[74] = 151.574996948242188;
+ fX[75] = 152.574996948242188;
+ fX[76] = 153.574996948242188;
+ fX[77] = 154.574996948242188;
+ fX[78] = 155.574996948242188;
+ fX[79] = 156.574996948242188;
+ fX[80] = 157.574996948242188;
+ fX[81] = 158.574996948242188;
+ fX[82] = 159.574996948242188;
+ fX[83] = 160.574996948242188;
+ fX[84] = 161.574996948242188;
+ fX[85] = 162.574996948242188;
+ fX[86] = 163.574996948242188;
+ fX[87] = 164.574996948242188;
+ fX[88] = 165.574996948242188;
+ fX[89] = 166.574996948242188;
+ fX[90] = 167.574996948242188;
+ fX[91] = 168.574996948242188;
+ fX[92] = 169.574996948242188;
+ fX[93] = 170.574996948242188;
+ fX[94] = 171.574996948242188;
+ fX[95] = 172.574996948242188;
+ fX[96] = 173.574996948242188;
+ fX[97] = 174.574996948242188;
+ fX[98] = 175.574996948242188;
+ fX[99] = 176.574996948242188;
+ fX[100] = 177.574996948242188;
+ fX[101] = 178.574996948242188;
+ fX[102] = 179.574996948242188;
+ fX[103] = 180.574996948242188;
+ fX[104] = 181.574996948242188;
+ fX[105] = 182.574996948242188;
+ fX[106] = 183.574996948242188;
+ fX[107] = 184.574996948242188;
+ fX[108] = 185.574996948242188;
+ fX[109] = 186.574996948242188;
+ fX[110] = 187.574996948242188;
+ fX[111] = 188.574996948242188;
+ fX[112] = 189.574996948242188;
+ fX[113] = 190.574996948242188;
+ fX[114] = 191.574996948242188;
+ fX[115] = 192.574996948242188;
+ fX[116] = 193.574996948242188;
+ fX[117] = 194.574996948242188;
+ fX[118] = 195.574996948242188;
+ fX[119] = 196.574996948242188;
+ fX[120] = 197.574996948242188;
+ fX[121] = 198.574996948242188;
+ fX[122] = 199.574996948242188;
+ fX[123] = 200.574996948242188;
+ fX[124] = 201.574996948242188;
+ fX[125] = 202.574996948242188;
+ fX[126] = 203.574996948242188;
+ fX[127] = 204.574996948242188;
+ fX[128] = 205.574996948242188;
+ fX[129] = 206.574996948242188;
+ fX[130] = 207.574996948242188;
+ fX[131] = 208.574996948242188;
+ fX[132] = 209.574996948242188;
+ fX[133] = 210.574996948242188;
+ fX[134] = 211.574996948242188;
+ fX[135] = 212.574996948242188;
+ fX[136] = 213.574996948242188;
+ fX[137] = 214.574996948242188;
+ fX[138] = 215.574996948242188;
+ fX[139] = 216.574996948242188;
+ fX[140] = 217.574996948242188;
+ fX[141] = 218.574996948242188;
+ fX[142] = 219.574996948242188;
+ fX[143] = 220.574996948242188;
+ fX[144] = 221.574996948242188;
+ fX[145] = 222.574996948242188;
+ fX[146] = 223.574996948242188;
+ fX[147] = 224.574996948242188;
+ fX[148] = 225.574996948242188;
+ fX[149] = 226.574996948242188;
+ fX[150] = 227.574996948242188;
+ fX[151] = 228.574996948242188;
+ fX[152] = 229.574996948242188;
+ fX[153] = 230.574996948242188;
+ fX[154] = 231.574996948242188;
+ fX[155] = 232.574996948242188;
+ fX[156] = 233.574996948242188;
+ fX[157] = 234.574996948242188;
+ fX[158] = 235.574996948242188;
+ fX[159] = 236.574996948242188;
+ fX[160] = 237.574996948242188;
+ fX[161] = 238.574996948242188;
+ fX[162] = 239.574996948242188;
+ fX[163] = 240.574996948242188;
+ fX[164] = 241.574996948242188;
+ fX[165] = 242.574996948242188;
+ fX[166] = 243.574996948242188;
+ fX[167] = 244.574996948242188;
+ fX[168] = 245.574996948242188;
+ fX[169] = 246.574996948242188;
+ fX[170] = 247.574996948242188;
+ fX[171] = 248.574996948242188;
+ fX[172] = 249.574996948242188;
+ fX[173] = 250.574996948242188;
+ fNPads[0] = 71;
+ fNPads[1] = 71;
+ fNPads[2] = 71;
+ fNPads[3] = 73;
+ fNPads[4] = 73;
+ fNPads[5] = 73;
+ fNPads[6] = 75;
+ fNPads[7] = 75;
+ fNPads[8] = 75;
+ fNPads[9] = 77;
+ fNPads[10] = 77;
+ fNPads[11] = 77;
+ fNPads[12] = 79;
+ fNPads[13] = 79;
+ fNPads[14] = 79;
+ fNPads[15] = 81;
+ fNPads[16] = 81;
+ fNPads[17] = 81;
+ fNPads[18] = 83;
+ fNPads[19] = 83;
+ fNPads[20] = 83;
+ fNPads[21] = 85;
+ fNPads[22] = 85;
+ fNPads[23] = 85;
+ fNPads[24] = 87;
+ fNPads[25] = 87;
+ fNPads[26] = 87;
+ fNPads[27] = 89;
+ fNPads[28] = 89;
+ fNPads[29] = 89;
+ fNPads[30] = 89;
+ fNPads[31] = 91;
+ fNPads[32] = 91;
+ fNPads[33] = 91;
+ fNPads[34] = 93;
+ fNPads[35] = 93;
+ fNPads[36] = 93;
+ fNPads[37] = 95;
+ fNPads[38] = 95;
+ fNPads[39] = 95;
+ fNPads[40] = 97;
+ fNPads[41] = 97;
+ fNPads[42] = 97;
+ fNPads[43] = 99;
+ fNPads[44] = 99;
+ fNPads[45] = 99;
+ fNPads[46] = 101;
+ fNPads[47] = 101;
+ fNPads[48] = 101;
+ fNPads[49] = 103;
+ fNPads[50] = 103;
+ fNPads[51] = 103;
+ fNPads[52] = 105;
+ fNPads[53] = 105;
+ fNPads[54] = 105;
+ fNPads[55] = 73;
+ fNPads[56] = 73;
+ fNPads[57] = 73;
+ fNPads[58] = 75;
+ fNPads[59] = 75;
+ fNPads[60] = 75;
+ fNPads[61] = 75;
+ fNPads[62] = 77;
+ fNPads[63] = 77;
+ fNPads[64] = 77;
+ fNPads[65] = 79;
+ fNPads[66] = 79;
+ fNPads[67] = 79;
+ fNPads[68] = 81;
+ fNPads[69] = 81;
+ fNPads[70] = 81;
+ fNPads[71] = 81;
+ fNPads[72] = 83;
+ fNPads[73] = 83;
+ fNPads[74] = 83;
+ fNPads[75] = 85;
+ fNPads[76] = 85;
+ fNPads[77] = 85;
+ fNPads[78] = 85;
+ fNPads[79] = 87;
+ fNPads[80] = 87;
+ fNPads[81] = 87;
+ fNPads[82] = 89;
+ fNPads[83] = 89;
+ fNPads[84] = 89;
+ fNPads[85] = 91;
+ fNPads[86] = 91;
+ fNPads[87] = 91;
+ fNPads[88] = 91;
+ fNPads[89] = 93;
+ fNPads[90] = 93;
+ fNPads[91] = 93;
+ fNPads[92] = 95;
+ fNPads[93] = 95;
+ fNPads[94] = 95;
+ fNPads[95] = 95;
+ fNPads[96] = 97;
+ fNPads[97] = 97;
+ fNPads[98] = 97;
+ fNPads[99] = 99;
+ fNPads[100] = 99;
+ fNPads[101] = 99;
+ fNPads[102] = 101;
+ fNPads[103] = 101;
+ fNPads[104] = 101;
+ fNPads[105] = 101;
+ fNPads[106] = 103;
+ fNPads[107] = 103;
+ fNPads[108] = 103;
+ fNPads[109] = 105;
+ fNPads[110] = 105;
+ fNPads[111] = 105;
+ fNPads[112] = 105;
+ fNPads[113] = 107;
+ fNPads[114] = 107;
+ fNPads[115] = 107;
+ fNPads[116] = 109;
+ fNPads[117] = 109;
+ fNPads[118] = 109;
+ fNPads[119] = 111;
+ fNPads[120] = 111;
+ fNPads[121] = 111;
+ fNPads[122] = 111;
+ fNPads[123] = 113;
+ fNPads[124] = 113;
+ fNPads[125] = 113;
+ fNPads[126] = 115;
+ fNPads[127] = 115;
+ fNPads[128] = 115;
+ fNPads[129] = 115;
+ fNPads[130] = 117;
+ fNPads[131] = 117;
+ fNPads[132] = 117;
+ fNPads[133] = 119;
+ fNPads[134] = 119;
+ fNPads[135] = 119;
+ fNPads[136] = 121;
+ fNPads[137] = 121;
+ fNPads[138] = 121;
+ fNPads[139] = 121;
+ fNPads[140] = 123;
+ fNPads[141] = 123;
+ fNPads[142] = 123;
+ fNPads[143] = 125;
+ fNPads[144] = 125;
+ fNPads[145] = 125;
+ fNPads[146] = 125;
+ fNPads[147] = 127;
+ fNPads[148] = 127;
+ fNPads[149] = 127;
+ fNPads[150] = 129;
+ fNPads[151] = 129;
+ fNPads[152] = 129;
+ fNPads[153] = 129;
+ fNPads[154] = 131;
+ fNPads[155] = 131;
+ fNPads[156] = 131;
+ fNPads[157] = 133;
+ fNPads[158] = 133;
+ fNPads[159] = 133;
+ fNPads[160] = 135;
+ fNPads[161] = 135;
+ fNPads[162] = 135;
+ fNPads[163] = 135;
+ fNPads[164] = 137;
+ fNPads[165] = 137;
+ fNPads[166] = 137;
+ fNPads[167] = 139;
+ fNPads[168] = 139;
+ fNPads[169] = 139;
+ fNPads[170] = 139;
+ fNPads[171] = 141;
+ fNPads[172] = 141;
+ fNPads[173] = 141;
+}
+
+
+Double_t AliL3Transform::GetEta(Float_t *xyz)
+{
+ Double_t r3 = sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]+xyz[2]*xyz[2]);
+ Double_t eta = 0.5 * log((r3+xyz[2])/(r3-xyz[2]));
+ return eta;
+}
+
+Double_t AliL3Transform::GetPhi(Float_t *xyz)
+{
+
+ Double_t phi = atan2(xyz[1],xyz[0]);
+ //if(phi<0) phi=phi+2*TMath::Pi();
+ return phi;
+}
+
+
+Bool_t AliL3Transform::Slice2Sector(Int_t slice, Int_t slicerow, Int_t & sector, Int_t &row) const{
+ if(slicerow<0&&slicerow>=fNRow) return kFALSE;
+ if(slice<0||slice>=fNSlice) return kFALSE;
+
+ if(slicerow<fNRowLow){
+ sector = slice;
+ row = slicerow;
+ }
+ else {
+ sector = slice+fNSlice;
+ row = slicerow-fNRowLow;
+ }
+ return kTRUE;
+}
+
+Bool_t AliL3Transform::Sector2Slice(Int_t & slice, Int_t sector) const{
+ if(sector<0||sector>=fNSector) return kFALSE;
+ if(sector<fNSectorLow) slice = sector;
+ else slice = sector - fNSectorLow;
+ return kTRUE;
+}
+
+Bool_t AliL3Transform::Sector2Slice(Int_t & slice, Int_t & slicerow,Int_t sector, Int_t row) const{
+ if(sector<0||sector>=fNSector||row<0) return kFALSE;
+ if(sector<fNSectorLow){
+ if(row>=fNRowLow) return kFALSE;
+ slice = sector;
+ slicerow = row;
+ }
+ else{
+ if(row>=fNRowUp) return kFALSE;
+ slice = sector - fNSectorLow;
+ slicerow = row + fNRowLow;
+ }
+ return kTRUE;
+}
+
+Double_t AliL3Transform::Row2X(Int_t slicerow){
+ if(slicerow<0||slicerow>=fNRow) return 0;
+ return fX[slicerow];
+}
+
+void AliL3Transform::Local2Global(Float_t *xyz,Int_t slice)
+{
+ //Transformation to global coordinate system
+ Float_t x0 = xyz[0];
+ Float_t y0 = xyz[1];
+ Float_t cs,sn;
+ cs = fCos[slice];
+ sn = fSin[slice];
+ xyz[0]=x0*cs-y0*sn;
+ xyz[1]=x0*sn+y0*cs;
+ xyz[2]=xyz[2];//global z=local z
+}
+
+void AliL3Transform::Local2GlobalAngle(Float_t *angle,Int_t slice){
+ angle[0] = fmod(angle[0]+slice*fPi/9,2*fPi);
+}
+
+void AliL3Transform::Global2LocalAngle(Float_t *angle,Int_t slice){
+ angle[0] = angle[0]-slice*fPi/9;
+ if(angle[0]<0) angle[0]+=2*fPi;
+}
+
+void AliL3Transform::Raw2Local(Float_t *xyz,Int_t sector,Int_t row,Float_t pad,Float_t time)
+{
+ //Transformation from rawdata to local coordinate system
+
+ Int_t slice,slicerow;
+ Sector2Slice(slice, slicerow, sector, row);
+
+ xyz[0]=Row2X(slicerow);
+ Int_t npads= fNPads[slicerow];
+ if(sector<fNSectorLow)
+ xyz[1]=(pad-0.5*(npads-1))*fPadPitchWidthLow;
+ else
+ xyz[1]=(pad-0.5*(npads-1))*fPadPitchWidthUp;
+ xyz[2]=fZWidth*time-3.*fZSigma;
+ Int_t sign=-1;
+ Int_t nis=fNSectorLow;
+ Int_t nos=fNSectorUp;
+
+ if((sector<nis)/2 || ((sector-nis)<nos/2)) sign=1;
+ xyz[2]=sign*(250.-xyz[2]);
+
+}
+
+void AliL3Transform::Local2Global(Float_t *xyz,Int_t sector,Int_t row)
+{
+ //Transformation to global coordinate system
+ Int_t slice,slicerow;
+ Sector2Slice(slice, slicerow, sector, row);
+ Float_t r=Row2X(slicerow);
+ Float_t cs = fCos[slice];
+ Float_t sn = fSin[slice];
+
+ xyz[0]=r*cs-xyz[1]*sn;
+ xyz[1]=r*sn+xyz[1]*cs;
+ xyz[2]=xyz[2];//global z=local z
+}
+
+Double_t AliL3Transform::GetMaxY(Int_t slicerow)
+{
+
+ if(slicerow < fNRowLow)
+ return fPadPitchWidthLow*fNPads[slicerow]/2;
+
+ else
+ return fPadPitchWidthUp*fNPads[slicerow]/2;
+}
+
+void AliL3Transform::Global2Local(Float_t *xyz,Int_t sector)
+{
+ Int_t slice;
+ Sector2Slice(slice, sector);
+ Float_t cs = fCos[slice];
+ Float_t sn = fSin[slice];
+ Float_t x1 = xyz[0]*cs + xyz[1]*sn;
+ Float_t y1 = -xyz[0]*sn + xyz[1]*cs;
+ xyz[0] = x1;
+ xyz[1] = y1;
+}
+
+void AliL3Transform::Raw2Global(Float_t *xyz,Int_t sector,Int_t row,Float_t pad,Float_t time)
+{
+ //Transformation from raw to global coordinates
+
+ Raw2Local(xyz,sector,row,pad,time);
+ Local2Global(xyz,sector,row);
+}
+
+void AliL3Transform::Local2Raw(Float_t *xyz,Int_t sector,Int_t row)
+{
+ //Transformation from local coordinates to raw
+
+ Int_t slice,slicerow;
+ Sector2Slice(slice, slicerow, sector, row);
+
+ if(sector<fNSectorLow)
+ xyz[1]=xyz[1]/fPadPitchWidthLow+0.5*(fNPads[slicerow]-1);
+ else
+ xyz[1]=xyz[1]/fPadPitchWidthUp+0.5*(fNPads[slicerow]-1);
+ Int_t sign=-1;
+ Int_t nis=fNSectorLow;
+ Int_t nos=fNSectorUp;
+
+ if ((sector<nis/2) || ((sector-nis)<nos/2)) sign=1;
+ xyz[2]=250-sign*xyz[2];
+ xyz[2]=(xyz[2]+3.*fZSigma)/fZWidth;
+}
+
+void AliL3Transform::Global2Raw(Float_t *xyz,Int_t sector,Int_t row)
+{
+ //Transformation from global coordinates to raw.
+
+ Global2Local(xyz,sector);
+ Local2Raw(xyz,sector,row);
+
+}
--- /dev/null
+#ifndef ALIL3TRANSFORM_H
+#define ALIL3TRANSFORM_H
+
+
+
+//#include "AliTPCParam.h"
+#include "AliL3RootTypes.h"
+class TFile;
+
+class AliL3Transform {
+ private:
+// AliTPCParam *fParam;
+ Int_t fNTimeBins;
+ Int_t fNRowLow;
+ Int_t fNRowUp;
+ Int_t fNSectorLow;
+ Int_t fNSectorUp;
+ Double_t fPadPitchWidthLow;
+ Double_t fPadPitchWidthUp;
+ Double_t fZWidth;
+ Double_t fZSigma;
+ Int_t fNSector;
+ Int_t fNSlice;
+ Int_t fNRow;
+ Double_t fPi;
+ Double_t fCos[36];
+ Double_t fSin[36];
+ Double_t fX[174];
+ Int_t fNPads[174];
+ public:
+ AliL3Transform();
+ virtual ~AliL3Transform();
+ void Init();
+
+ Double_t GetPadPitchWidthLow() {return fPadPitchWidthLow;}
+ Double_t GetPadPitchWidthUp() {return fPadPitchWidthUp;}
+
+ Bool_t Slice2Sector(Int_t slice, Int_t slicerow, Int_t & sector, Int_t &row) const;
+
+ Bool_t Sector2Slice(Int_t & slice, Int_t sector) const;
+ Bool_t Sector2Slice(Int_t & slice, Int_t & slicerow,Int_t sector, Int_t row) const;
+
+ Double_t Row2X(Int_t slicerow);
+ Int_t GetNPads(Int_t row){return (row<174)?fNPads[row]:0;}
+ Int_t GetNTimeBins(){return fNTimeBins;}
+
+ Double_t GetEta(Float_t *xyz);
+ Double_t GetPhi(Float_t *xyz);
+ Double_t GetMaxY(Int_t slicerow);
+ void Local2Global(Float_t *xyz,Int_t slice);
+ void Local2GlobalAngle(Float_t *angle,Int_t slice);
+ void Global2LocalAngle(Float_t *angle,Int_t slice);
+
+ void Raw2Local(Float_t *xyz,Int_t sector,Int_t row,Float_t pad,Float_t time);
+ void Local2Global(Float_t *xyz,Int_t sector,Int_t row);
+ void Global2Local(Float_t *xyz,Int_t sector);
+ void Raw2Global(Float_t *xyz,Int_t sector,Int_t row,Float_t pad,Float_t time);
+ void Local2Raw(Float_t *xyz,Int_t sector,Int_t row);
+ void Global2Raw(Float_t *xyz,Int_t sector,Int_t row);
+
+ ClassDef(AliL3Transform,1)
+};
+
+
+#endif
--- /dev/null
+//Author: Uli Frankenfeld
+//Last Modified: 07.11.2000
+
+#include "AliL3RootTypes.h"
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3Vertex.h"
+
+//_____________________________________________________________
+//
+// AliL3Vertex
+//
+// stores the information of the vertex position
+//
+
+
+ClassImp(AliL3Vertex)
+AliL3Vertex::AliL3Vertex(){
+ //
+ // default constructor for the AliL3Vertex class.
+ //
+
+ //Set vertex to zero.
+ SetZero();
+}
+
+AliL3Vertex::~AliL3Vertex(){
+ //
+ // destructor
+ //
+}
+
+void AliL3Vertex::SetZero(){
+ // doit
+ SetX(0);
+ SetY(0);
+ SetZ(0);
+ SetXErr(1);
+ SetYErr(1);
+ SetZErr(1);
+ fR=0;
+ fPhi=0;
+
+ fMWxy = 1.;
+}
+
+void AliL3Vertex::Read(AliL3VertexData *vertex){
+ // doit
+ SetX(vertex->fX);
+ SetY(vertex->fY);
+ SetZ(vertex->fZ);
+ SetXErr(vertex->fXErr);
+ SetYErr(vertex->fYErr);
+ SetZErr(vertex->fZErr);
+ fR=0;
+ fPhi=0;
+
+ fMWxy = 1.;
+}
+
--- /dev/null
+#ifndef AliL3VERTEX_H
+#define AliL3VERTEX_H
+
+#include "AliL3RootTypes.h"
+#include "AliL3VertexData.h"
+
+class AliL3Vertex {
+ private:
+ Double_t fX;
+ Double_t fY;
+ Double_t fZ;
+ Double_t fPhi;
+ Double_t fR;
+
+ Double_t fXErr;
+ Double_t fYErr;
+ Double_t fZErr;
+
+ Double_t fMWxy;
+
+ public:
+ AliL3Vertex();
+ AliL3Vertex(AliL3Vertex&){;}
+ virtual ~AliL3Vertex();
+ void SetZero();
+
+ void Read(AliL3VertexData *vertex);
+
+ Double_t GetX() const {return fX;}
+ Double_t GetY() const {return fY;}
+ Double_t GetZ() const {return fZ;}
+ Double_t GetXErr() const {return fXErr;}
+ Double_t GetYErr() const {return fYErr;}
+ Double_t GetZErr() const {return fZErr;}
+ Double_t GetPhi() const {return fPhi;}
+ Double_t GetR() const {return fR;}
+ Double_t GetXYWeight() const {return fMWxy;}
+ void SetX(Double_t f) {fX=f;}
+ void SetY(Double_t f) {fY=f;}
+ void SetZ(Double_t f) {fZ=f;}
+ void SetXErr(Double_t f) {fXErr=f;}
+ void SetYErr(Double_t f) {fYErr=f;}
+ void SetZErr(Double_t f) {fZErr=f;}
+
+ void SetXYWeight(Double_t f) {fMWxy = f;}
+
+ ClassDef(AliL3Vertex,1) // Level3
+};
+#endif
--- /dev/null
+//Author: Uli Frankenfeld
+//Last Modified: 07.11.2000
+
+#include "AliL3Logging.h"
+//#include <TMath.h>
+#include <iostream.h>
+#include "AliL3VertexArray.h"
+
+//_____________________________________________________________
+// The L3 Fast Vertex Finder Base Class
+//
+// usage:
+//
+//for(Int_t sec=0;sec<NSEC;sec++){
+// ResetSector();
+// FillSectorSeed3D(x,y,z);
+// FillSector3D(x,y,z);
+// FindSectorVertex();
+// Double_t z = GetZSector();
+// Double_t zerr = GetZSectorErr();
+//// do somethink with z, zerr
+//}
+
+ClassImp(AliL3VertexArray)
+void AliL3VertexArray::AnalyzeSector(Float_t *vertex, Int_t *array, Int_t len){
+//loop over all seeds and all vertex position
+ LOG(AliL3Log::kInformational,"AliL3VertexArray::AnalyzeSector","Analyze")
+ <<AliL3Log::kDec<<"Number of Seeds: "<<fNSeed<<ENDLOG;
+ for(Int_t i =0;i<fNSeed;i++)
+ for(Int_t bin = 0;bin<len;bin++)
+ array[bin] += Trace(fZSeed[i],fRSeed[i],fSecSeed[i],vertex[bin]);
+}
+
+void AliL3VertexArray::FindSectorVertex(Double_t pos, Double_t range, Int_t nbin){
+//define position and range for search and
+//loop over all seeds
+//and find position of vertex and error
+ const Int_t len = nbin;
+ const Double_t width = range;
+ const Double_t xmin = pos - width/2;
+ const Double_t step = width/len;
+ const Double_t start = xmin + step/2.;
+ Int_t * array = new Int_t[len];
+ Float_t * ver = new Float_t[len];
+ for(Int_t i=0;i<len;i++){
+ ver[i] = start + step * i;
+ array[i] = 0;
+ }
+ AnalyzeSector(ver,array,len);
+ FindMean(ver,array,len);
+ delete[] array;
+ delete[] ver;
+}
+
+void AliL3VertexArray::FindMean(Float_t *vertex,Int_t *array, Int_t len){
+//find mean and error of array and store it in
+//fZSector and fZSectorErr
+ const Int_t nbin = len;
+ Int_t xbin =0;
+ Int_t max=0;
+ for(Int_t i = 0;i<nbin;i++){
+ if(array[i]>max){
+ max = array[i];
+ xbin =i;
+ }
+ }
+ Int_t hmax = max/2;
+ Int_t xmin,xmax;
+ Int_t ops = 0;
+ xmin = xbin;
+ while(xmin--){
+ if(xmin<0) {ops++;break;}
+ if(array[xmin]<hmax) {
+ break;
+ }
+ }
+ xmax = xbin;
+ while(xmax++){
+ if(xmax>=nbin) {ops++;break;}
+ if(array[xmax]<hmax){
+ break;
+ }
+ }
+ if(ops){
+ if(xbin >= nbin/2){xmin = 2 * xbin - nbin +1;xmax = nbin-1;}
+ else{xmin = 0;xmax = 2 * xbin;}
+ }
+ Double_t sumw=0;
+ Double_t sumw2=0;
+ Double_t sumwx=0;
+ Double_t sumwx2=0;
+ for(Int_t bin = xmin;bin<=xmax;bin++){
+ sumw += array[bin];
+ sumw2 += array[bin] * array[bin];
+ sumwx += array[bin] * vertex[bin];
+ sumwx2 += array[bin] * vertex[bin] * vertex[bin];
+ }
+ if(sumw){
+ Double_t mean = sumwx/sumw;
+ Double_t rms2 = fabs(sumwx2/sumw - mean*mean);
+ fZSectorErr = sqrt(rms2/sumw);
+ fZSector = mean;
+ }
+ else{fZSectorErr = fZSector = 0;}
+}
+
--- /dev/null
+#ifndef AliL3VERTEXARRAY_H
+#define AliL3VERTEXARRAY_H
+
+#include <math.h>
+#include "AliL3RootTypes.h"
+
+class AliL3VertexArray{
+ private:
+
+ Char_t fArray[8320][8][8];
+ Double_t fZSector;
+ Double_t fZSectorErr;
+ Int_t fMaxSeed;
+ Int_t fNSeed;
+ Float_t fZSeed[400];
+ Float_t fRSeed[400];
+ Int_t fSecSeed[400];
+
+ void FindMean(Float_t *vertex,Int_t *array, Int_t len);
+ void AnalyzeSector(Float_t *vertex, Int_t *array, Int_t len);
+
+ public:
+ AliL3VertexArray(){fNSeed=0;fMaxSeed=400;}
+ AliL3VertexArray(AliL3VertexArray&){fNSeed=0;fMaxSeed=400;}
+ AliL3VertexArray(Int_t maxseed){fNSeed=0;fMaxSeed=maxseed;}
+ virtual ~AliL3VertexArray(){;}
+
+ Int_t GetContent(Float_t z,Float_t r,Int_t sec);
+ Int_t Trace(Float_t z,Float_t r,Int_t sec,Float_t vertex);
+
+ Double_t GetZSectorErr(){return fZSectorErr;}
+ Double_t GetZSector(){return fZSector;}
+ Int_t GetMaxSeed(){return fMaxSeed;}
+ Int_t GetNSeed(){return fNSeed;}
+ Float_t GetRSeed(Int_t i){if(i<400) return fRSeed[i]; else return -999;}
+ Float_t GetZSeed(Int_t i){if(i<400) return fZSeed[i]; else return -999;}
+ Float_t GetSecSeed(Int_t i){if(i<400) return fSecSeed[i]; else return -999;}
+
+ void FillSector2D(Float_t z,Float_t r,Int_t sec);
+ void FillSectorSeed2D(Float_t z,Float_t r,Int_t sec);
+ void FillSector3D(Float_t x,Float_t y, Float_t z);
+ void FillSectorSeed3D(Float_t x,Float_t y, Float_t z);
+ void FindSectorVertex(Double_t pos = 0,Double_t range = 60,Int_t nbin = 60);
+ void ResetSector();
+
+ ClassDef(AliL3VertexArray,1) // Level3
+
+};
+
+inline void AliL3VertexArray::FillSector3D(Float_t x, Float_t y, Float_t z){
+ // Filling routine in coordinates
+ Int_t sec = Int_t( (y+.168*x)/(.336*x)*8); // 8 subsec!!
+ Float_t r = sqrt(pow(y,2)+pow(x,2));
+ FillSector2D(z,r,sec);
+}
+
+inline void AliL3VertexArray:: FillSectorSeed3D(Float_t x,Float_t y, Float_t z){
+ // Filling routine for seeds in coordinates
+ Int_t sec = Int_t( (y+.168*x)/(.336*x)*8); // 8 subsec!!
+ Float_t r = sqrt(pow(y,2)+pow(x,2));
+ FillSectorSeed2D(z,r,sec);
+}
+
+inline void AliL3VertexArray::FillSectorSeed2D(Float_t z,Float_t r,Int_t sec){
+ // Filling routine in r,z coordinates
+ if(fNSeed>=400) return;
+ fZSeed[fNSeed] = z; fRSeed[fNSeed] = r; fSecSeed[fNSeed] = sec;
+ fNSeed++;
+}
+
+inline void AliL3VertexArray::FillSector2D(Float_t z,Float_t r,Int_t sec){
+ // Filling routine for seeds in r,z coordinates
+ if(z>r||z<=0||r<220||r>=252) return;
+ fArray[Int_t(z/r*32*260)][(Int_t(r-220))/4][sec] += 1;
+}
+
+inline Int_t AliL3VertexArray::GetContent(Float_t z,Float_t r,Int_t sec){
+ // Return content of array in r,z coordinates
+ if(z>r||z<=0||r<220||r>=252) return 0;
+ return fArray[Int_t(z/r*32*260)][(Int_t(r-220))/4][sec];
+}
+
+inline void AliL3VertexArray::ResetSector(){
+ // do it!
+ fZSector=0;
+ fZSectorErr=0;
+ fNSeed=0;
+ for(Int_t i =0;i<400;i++)
+ fZSeed[i] = fRSeed[i] = fSecSeed[i] = 0;
+ for(Int_t z=0;z<8320;z++)
+ for(Int_t r=0;r<8;r++)
+ for(Int_t sec =0;sec<8;sec++)
+ fArray[z][r][sec] = 0;
+}
+
+inline Int_t AliL3VertexArray::Trace(Float_t z,Float_t r,Int_t sec,Float_t vertex){
+// count the number of entries along starting from z,r to vertex,0
+ Int_t cont=0;
+ for(Int_t i = 0;i<8;i++){
+ Float_t ry = 222 +(i*4);
+ Float_t zx = (ry/r)*(z-vertex)+vertex;
+ cont += GetContent(zx,ry,sec);
+ }
+ if(cont < 5) return 0;
+ return cont;
+}
+
+#endif
--- /dev/null
+#ifndef VERTEXDATA_H
+#define VERTEXDATA_H
+
+#include "AliL3RootTypes.h"
+
+struct AliL3VertexData{
+ Double_t fX;
+ Double_t fY;
+ Double_t fZ;
+ Double_t fXErr;
+ Double_t fYErr;
+ Double_t fZErr;
+};
+typedef struct AliL3VertexData AliL3VertexData;
+
+#endif /* VERTEXDATA_H */
--- /dev/null
+//Author: Uli Frankenfeld
+//Last Modified: 07.11.2000
+
+#include <iostream.h>
+#include "AliL3Logging.h"
+#include "AliL3VertexArray.h"
+#include "AliL3Vertex.h"
+#include "AliL3VertexFinder.h"
+#include "AliL3SpacePointData.h"
+
+//_____________________________________________________________
+//
+// AliL3VertexFinder
+//
+// Implementation of AliL3Array
+// usage:
+//
+// ResetSector();
+// for(n=0;n<NMEMSEC;n++)
+// Read();
+// FindSectorVertex();
+// SetZ(GetZSector());
+// SetZErr(GetZErrSector());
+// // do somethink with z, zerr
+//
+
+ClassImp(AliL3VertexFinder)
+AliL3VertexFinder::AliL3VertexFinder(){
+ //
+ // default constructor for the AliL3VertexFinder class.
+ //
+
+ //Set vertex to zero.
+ SetX(0);
+ SetY(0);
+ SetZ(0);
+ SetXErr(1);
+ SetYErr(1);
+ SetZErr(1);
+ fR=0;
+ fPhi=0;
+
+ fMWxy = 1.;
+
+}
+
+AliL3VertexFinder::~AliL3VertexFinder(){
+ //
+ // destructor
+ //
+}
+
+void AliL3VertexFinder::Reset(){
+ ResetSector();
+}
+
+
+void AliL3VertexFinder::Read(Int_t ncluster, AliL3SpacePointData* hits ){
+ //
+ // analyze sector
+ //
+
+ const Int_t seedRow = 173;
+ const Int_t firstRow = seedRow-32;
+ for(Int_t n=0;n<ncluster;n++){
+ if(hits[n].fPadRow==seedRow)
+ FillSectorSeed3D(hits[n].fX,hits[n].fY,hits[n].fZ); //copy seeds in 3D
+ if(hits[n].fPadRow<=seedRow && hits[n].fPadRow>=firstRow)
+ FillSector3D(hits[n].fX,hits[n].fY,hits[n].fZ); //copy data in 3D
+ }
+}
+
+void AliL3VertexFinder::Analyze(){
+ FindSectorVertex();
+ SetZ(GetZSector());
+ SetZErr(GetZSectorErr());
+ LOG(AliL3Log::kInformational,"AliL3VertexFinder::Analyze","Result")
+ <<AliL3Log::kDec<<"Vertex: "<<GetZ()<<" Error: "<<GetZErr()<<ENDLOG;
+}
+
+void AliL3VertexFinder::Write(AliL3Vertex *vertex){
+ vertex->SetX(GetX());
+ vertex->SetY(GetZ());
+ vertex->SetZ(GetZ());
+ vertex->SetXErr(GetXErr());
+ vertex->SetYErr(GetYErr());
+ vertex->SetZErr(GetZErr());
+
+ vertex->SetXYWeight(GetXYWeight());
+}
+
+void AliL3VertexFinder::Write(AliL3VertexData *vertex){
+ vertex->fX=GetX();
+ vertex->fY=GetZ();
+ vertex->fZ=GetZ();
+ vertex->fXErr=GetXErr();
+ vertex->fYErr=GetYErr();
+ vertex->fZErr=GetZErr();
+}
--- /dev/null
+#ifndef AliL3VERTEXFINDER_H
+#define AliL3VERTEXFINDER_H
+
+#include "AliL3VertexArray.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3VertexData.h"
+
+class AliL3Vertex;
+
+class AliL3VertexFinder:public AliL3VertexArray{
+ private:
+ Double_t fX;
+ Double_t fY;
+ Double_t fZ;
+ Double_t fPhi;
+ Double_t fR;
+
+ Double_t fXErr;
+ Double_t fYErr;
+ Double_t fZErr;
+
+ Double_t fMWxy;
+
+ public:
+ AliL3VertexFinder();
+ AliL3VertexFinder(AliL3VertexFinder&){;}
+ virtual ~AliL3VertexFinder();
+
+ void Reset();
+ void Read(Int_t ncluster, AliL3SpacePointData* hits);
+ void Analyze();
+ void Write(AliL3Vertex *vertex);
+ void Write(AliL3VertexData *vertex);
+
+ Double_t GetX() const {return fX;}
+ Double_t GetY() const {return fY;}
+ Double_t GetZ() const {return fZ;}
+ Double_t GetXErr() const {return fXErr;}
+ Double_t GetYErr() const {return fYErr;}
+ Double_t GetZErr() const {return fZErr;}
+ Double_t GetPhi() const {return fPhi;}
+ Double_t GetR() const {return fR;}
+ Double_t GetXYWeight() const {return fMWxy;}
+ void SetX(Double_t f) {fX=f;}
+ void SetY(Double_t f) {fY=f;}
+ void SetZ(Double_t f) {fZ=f;}
+ void SetXErr(Double_t f) {fXErr=f;}
+ void SetYErr(Double_t f) {fYErr=f;}
+ void SetZErr(Double_t f) {fZErr=f;}
+
+ void SetXYWeight(Double_t f) {fMWxy = f;}
+
+ ClassDef(AliL3VertexFinder,1) // Level3
+};
+#endif
--- /dev/null
+//Author: Uli Frankenfeld
+//Author: Anders Strand Vestbo
+//Last Modified: 13.12.2000
+
+#include "AliL3Logging.h"
+
+#include <TFile.h>
+#include <TDirectory.h>
+#include <TClonesArray.h>
+#include <TStopwatch.h>
+#include <iostream.h>
+
+//#include <AliTPCcluster.h>
+//#include "AliTPCParam.h"
+#include "AliLevel3.h"
+#include "AliL3ConfMapper.h"
+#include "AliL3Vertex.h"
+#include "AliL3VertexFinder.h"
+#include "AliL3TrackMerger.h"
+#include "AliL3GlobalMerger.h"
+#include "AliL3InterMerger.h"
+#include "AliL3ConfMapPoint.h"
+#include "AliL3ConfMapTrack.h"
+#include "AliL3Transform.h"
+#include "AliL3ClustFinder.h"
+#include "AliL3DigitData.h"
+#include "AliL3TrackArray.h"
+#include "AliL3MemHandler.h"
+#include "AliL3FileHandler.h"
+#include "AliL3Benchmark.h"
+
+#include "AliL3DigitData.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3VertexData.h"
+
+//_______________________________________
+//
+// AliLevel3
+//
+// Interface class for Level3 tracker.
+// Tracking is done by calling constructor with input,output
+// given as argument.
+// You must always remember to set the tracking parameters. E.g.:
+//
+// AliLevel3 *level3 = new AliLevel3(inputfile,outputfile);
+// level3->SetTrackerParam(); //Sets default tracking parameters
+// level3->ProcessSector(2,2); //Does tracking on sector 2 (actually 2+38)
+
+ClassImp(AliLevel3)
+
+AliLevel3::AliLevel3(){
+ fInputFile=0;
+ fOutputFile=0;
+ Init();
+}
+
+AliLevel3::AliLevel3(Char_t *infile,Char_t *outfile){
+ //Constructor. Calls constructor of the tracker, vertexfinder and merger classes.
+
+ fOutputFile = new TFile(outfile,"NEW");
+
+ if(!fOutputFile->IsOpen())
+ {
+ LOG(AliL3Log::kWarning, "AliLevel3::AliLevel3","File Open")
+ <<"Delete your old "<<outfile<<" file!"<<ENDLOG;
+ }
+ fInputFile = new TFile(infile,"READ");
+
+ if(!fInputFile->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Inputfile "<<infile<<" does not exist"<<ENDLOG;
+ return;
+ }
+
+ Init();
+}
+
+AliLevel3::AliLevel3(TFile *in, TFile *out){
+ fOutputFile = out;
+ fInputFile = in;
+ if(!in){
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Pointer to InFile 0x0!"<<ENDLOG;
+ return;
+ }
+ if(!out){
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Pointer to OutFile 0x0!"<<ENDLOG;
+ return;
+ }
+
+ if(!fOutputFile->IsOpen())
+ {
+ LOG(AliL3Log::kWarning,"AliLevel3::AliLevel3","File Open")
+ <<"no output file!"<<ENDLOG;
+ return;
+ }
+ if(!fInputFile->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Inputfile does not exist"<<ENDLOG;
+ return;
+ }
+ Init();
+}
+
+void AliLevel3::Init(){
+ fWriteOut = kFALSE;
+ fGlobalMerger=0;
+ fTransformer = new AliL3Transform();
+ fDoRoi = kFALSE;
+ fUseBinary =kFALSE;
+ SetPath("");
+ fFindVertex =kTRUE;
+ fNPatch = 5; //number of patches change row in process
+ fVertexFinder = new AliL3VertexFinder();
+ fVertex = new AliL3Vertex();
+ fTracker = new AliL3ConfMapper();
+ fTrackMerger = new AliL3TrackMerger(fNPatch);
+ fInterMerger = new AliL3InterMerger();
+ fFileHandler = new AliL3FileHandler();
+ fFileHandler->SetAliInput(fInputFile);
+ fBenchmark = new AliL3Benchmark();
+}
+
+void AliLevel3::DoBench(char* name){
+ fBenchmark->Analyze(name);
+}
+
+void AliLevel3::DoMc(char* file){
+ if(!fFileHandler->IsDigit())
+ fFileHandler->SetMCOutput(file);
+}
+
+AliLevel3::~AliLevel3(){
+ //Destructor
+ if(fVertexFinder) delete fVertexFinder;
+ if(fVertex) delete fVertex;
+ if(fTracker) delete fTracker;
+ if(fTransformer) delete fTransformer;
+ if(fTrackMerger) delete fTrackMerger;
+ if(fInterMerger) delete fInterMerger;
+ if(fFileHandler) delete fFileHandler;
+}
+
+void AliLevel3::SetTrackerParam(Int_t phi_segments, Int_t eta_segments,
+ Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,
+ Double_t min_pt_fit, Double_t maxangle,
+ Double_t goodDist, Double_t hitChi2Cut,
+ Double_t goodHitChi2, Double_t trackChi2Cut,
+ Int_t maxdist)
+{
+ //Set parameters input to the tracker
+ //If no arguments are given, default parameters will be used
+
+ fTracker->SetNSegments(phi_segments,eta_segments);
+ fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
+ fTracker->SetMaxDca(min_pt_fit);
+ fTracker->SetTrackletCuts(maxangle,goodDist,true);
+ fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist);
+
+ fTracker->SetParamDone(true);
+}
+
+void AliLevel3::ProcessEvent(Int_t first,Int_t last){
+ //Do tracking on all slices in region [first,last]
+ //Slices numbering in TPC goes from 0-35, which means that 1 slice
+ //corresponds to inner+outer sector.E.g. slice 2 corresponds to
+ //inner=2 + outer=38.
+ fGlobalMerger= new AliL3GlobalMerger(first,last);
+ for(Int_t i=first; i<=last; i++){
+ ProcessSlice(i);
+ fGlobalMerger->SetVertex(fVertex);
+ fGlobalMerger->SetTransformer(fTransformer);
+ fGlobalMerger->InitSlice(i);
+ fBenchmark->Start("Fill Global Merger");
+ fGlobalMerger->FillTracks(fNTrackData,fTrackData);
+ fBenchmark->Stop("Fill Global Merger");
+ fFileHandler->Free(); //free the memory
+ fNTrackData=0;
+ fTrackData=0;
+ }
+ fBenchmark->Start("Global Merger");
+ fGlobalMerger->Merge();
+// fGlobalMerger->SlowMerge();
+ fBenchmark->Stop("Global Merger");
+
+ if(fWriteOut) WriteResults();
+ delete fGlobalMerger; fGlobalMerger = 0;
+}
+
+void AliLevel3::ProcessSlice(Int_t slice){
+ char name[256];
+ Bool_t isdigit = fFileHandler->IsDigit();
+// Int_t row[5][2] = {{ 0,173}};
+ Int_t row[5][2] = {{ 0, 45},{46,77},{78,109},{110,141},{142,173}};
+ const Int_t maxpoints=100000;
+ const Int_t pointsize = maxpoints * sizeof(AliL3SpacePointData);
+ AliL3MemHandler *memory = new AliL3MemHandler();
+
+ fTrackMerger->Reset();
+ fTrackMerger->SetTransformer(fTransformer);
+ fTrackMerger->SetRows(row[0]);
+ for(Int_t patch=fNPatch-1;patch>=0;patch--){
+ fFileHandler->Init(slice,patch,row[patch]);
+ fFileHandler->Init(fTransformer);
+ UInt_t npoints=0;
+ AliL3SpacePointData *points =0;
+ UInt_t ndigits=0;
+ AliL3DigitRowData *digits =0;
+ if(fUseBinary){
+
+ if(!fDoRoi){
+ if(0){ //Binary to Memory
+ fFileHandler->Free();
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ fFileHandler->SetBinaryInput(name);
+ digits= (AliL3DigitRowData *)fFileHandler->CompBinary2Memory(ndigits);
+ fFileHandler->CloseBinaryInput();
+ }
+
+ if(1){ //Binary to Memory with Benchmark
+ fFileHandler->Free();
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliL3DigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ }
+
+ if(0){ //Binary to Memory with Random
+ fFileHandler->Free();
+ fFileHandler->ResetRandom();
+ fFileHandler->SetRandomCluster(100);
+ fFileHandler->SetNGenerate(100);
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t dsize=memory->GetMemorySize(ndigits,comp);
+ UInt_t rsize=fFileHandler->GetRandomSize();
+ digits=(AliL3DigitRowData*)fFileHandler->Allocate(dsize+rsize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ if(1)
+ cerr<<endl<<dsize/1024<<" "<<rsize/1024<<" "
+ <<100.*rsize/dsize<<"%"<<endl;
+ }
+ }
+
+ else{ //Binary to Memory with Roi
+ fFileHandler->Free();
+ Int_t sli[2]={0,0};
+ fFileHandler->SetROI(fEta,sli);
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliL3DigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ if(1)
+ cerr<<endl<<datasize/1024<<" "<<endl;
+ }
+
+
+ points = (AliL3SpacePointData *) memory->Allocate(pointsize);
+
+ fClusterFinder = new AliL3ClustFinder(fTransformer);
+ fClusterFinder->InitSlice(slice,patch,row[patch][0],row[patch][1]
+ ,maxpoints);
+ fClusterFinder->SetXYError(0.1);
+ fClusterFinder->SetZError(0.2);
+ fClusterFinder->SetOutputArray(points);
+ fBenchmark->Start("Read Cluster Finder");
+ fClusterFinder->Read(ndigits,digits);
+ fBenchmark->Stop("Read Cluster Finder");
+ fBenchmark->Start("Cluster Finder");
+ fClusterFinder->ProcessDigits();
+ fBenchmark->Stop("Cluster Finder");
+ npoints = fClusterFinder->GetNumberOfClusters();
+ delete fClusterFinder;
+ fClusterFinder =0;
+ fFileHandler->Free();
+
+ LOG(AliL3Log::kInformational,"AliLevel3::ProcessSlice","Cluster Finder")
+ <<AliL3Log::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
+ }
+
+ else{
+ if(isdigit){
+ sprintf(name,"digits_%d_%d.raw",slice,patch);
+
+ if(0){ //Ali to Binary
+ fFileHandler->SetBinaryOutput(name);
+ fFileHandler->AliDigits2CompBinary();
+ fFileHandler->CloseBinaryOutput();
+ }
+
+ if(1){ //Ali to Memory
+ digits=(AliL3DigitRowData *)fFileHandler->AliDigits2Memory(ndigits);
+ if(fWriteOut){ //Memory to Binary
+ fFileHandler->SetBinaryOutput(name);
+ fFileHandler->Memory2CompBinary(ndigits,digits);
+ fFileHandler->CloseBinaryOutput();
+ }
+ }
+ }
+ else points = fFileHandler->AliPoints2Memory(npoints);
+ }
+
+ if(patch == fNPatch-1){
+ // Vertex
+ if(fFindVertex){
+ // Vertex Finder
+
+ fBenchmark->Start("Vertex Finder Read");
+ fVertexFinder->Reset();
+ fVertexFinder->Read(npoints,points);
+ fBenchmark->Stop("Vertex Finder Read");
+ fBenchmark->Start("Vertex Finder");
+ fVertexFinder->Analyze();
+ AliL3VertexData vertex[1];
+ fVertexFinder->Write(vertex);
+ fVertex->Read(vertex);
+ fBenchmark->Stop("Vertex Finder");
+ }
+ else{
+ //use 0,0,0 for vertex
+ fVertex->SetZero();
+ }
+ fTrackMerger->SetVertex(fVertex);
+ }
+ fTracker->InitSector(slice,row[patch]);
+ fTracker->SetVertex(fVertex);
+ fBenchmark->Start("Tracker Read Hits");
+ fTracker->ReadHits(npoints,points);
+ fBenchmark->Stop("Tracker Read Hits");
+ fBenchmark->Start("MainVertexTracking A");
+ fTracker->MainVertexTracking_a();
+ fBenchmark->Stop("MainVertexTracking A");
+ fBenchmark->Start("MainVertexTracking B");
+ fTracker->MainVertexTracking_b();
+ fBenchmark->Stop("MainVertexTracking B");
+ fBenchmark->Start("Tracking fit");
+ fTracker->FillTracks();
+ fBenchmark->Stop("Tracking fit");
+
+ if(fWriteOut)
+ WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
+ fFileHandler->Free();
+
+ UInt_t ntracks0 =0;
+ AliL3TrackSegmentData *trackdata0 =
+ (AliL3TrackSegmentData *) memory->Allocate(fTracker->GetTracks());
+ memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
+
+ //write tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_tr_%d_%d.raw",slice,patch);
+ memory->SetBinaryOutput(name);
+ memory->Memory2Binary(ntracks0,trackdata0);
+ memory->CloseBinaryOutput();
+ }
+
+ fInterMerger->Reset();
+ fInterMerger->SetTransformer(fTransformer);
+ fInterMerger->Init(row[patch],patch);
+
+ fBenchmark->Start("Fill Inter Merger");
+ fInterMerger->FillTracks(ntracks0,trackdata0);
+ fBenchmark->Stop("Fill Inter Merger");
+ fBenchmark->Start("Inter Merger");
+ fInterMerger->Merge();
+// fInterMerger->SlowMerge();
+
+ fBenchmark->Stop("Inter Merger");
+
+ //write inter merged tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_im_%d_%d.raw",slice,patch);
+ WriteTracks(name,fInterMerger,'i'); //write output of intermerger
+ }
+ memory->Free();
+
+ UInt_t ntracks1 =0;
+ AliL3TrackSegmentData *trackdata1 =
+ (AliL3TrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
+ memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
+
+ fTrackMerger->InitSector(slice,patch);
+ fBenchmark->Start("Fill Patch Merger");
+ fTrackMerger->FillTracks(ntracks1,trackdata1);
+ fBenchmark->Stop("Fill Patch Merger");
+
+ memory->Free();
+ }
+ fBenchmark->Start("Patch Merger");
+// fTrackMerger->SlowMerge();
+ fTrackMerger->Merge();
+ fBenchmark->Stop("Patch Merger");
+ //write merged tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_tm_%d.raw",slice);
+ WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
+ }
+
+ fTrackData = (AliL3TrackSegmentData *)
+ fFileHandler->Allocate(fTrackMerger->GetOutTracks());
+
+ fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
+ fTrackMerger->GetOutTracks());
+
+ delete memory;
+}
+
+void AliLevel3::WriteSpacePoints(UInt_t npoints,AliL3SpacePointData *points,
+ Int_t slice,Int_t patch){
+ char name[256];
+ sprintf(name,"points_%d_%d.raw",slice,patch);
+ AliL3MemHandler * memory = new AliL3MemHandler();
+ memory->SetBinaryOutput(name);
+ memory->Transform(npoints,points,slice,fTransformer);
+ memory->Memory2Binary(npoints,points);
+ memory->CloseBinaryOutput();
+ delete memory;
+}
+
+
+Int_t AliLevel3::WriteTracks(char *filename,AliL3Merger *merger,char opt){
+ AliL3FileHandler *memory = new AliL3FileHandler();
+ memory->SetBinaryOutput(filename);
+ if(opt=='a'||opt=='i'){ //add intracks
+ for(Int_t i=0;i<merger->GetNIn();i++){
+ AliL3TrackArray *tr=merger->GetInTracks(i);
+ memory->TrackArray2Binary(tr);
+ }
+ }
+
+ if(opt=='o'||opt=='a'){
+ AliL3TrackArray *tr=merger->GetOutTracks();
+ memory->TrackArray2Binary(tr);
+ }
+
+ memory->CloseBinaryOutput();
+
+ return 1;
+}
+
+void AliLevel3::WriteResults()
+{
+ //Write the resulting tracks to outputfile
+ WriteTracks("tracks.raw",fGlobalMerger,'a');
+}
--- /dev/null
+#ifndef ALILEVEL3_H
+#define ALILEVEL3_H
+
+#include <TObject.h>
+#include <TBuffer.h>
+#include <TFile.h>
+
+#include "AliL3DigitData.h"
+
+class AliL3SpacePointData;
+class AliL3DigitRowData;
+class AliL3TrackSegmentData;
+class AliL3DigitData;
+class AliL3Transform;
+class TClonesArray;
+class AliTPCParam;
+class AliL3ConfMapper;
+class AliL3Vertex;
+class AliL3VertexFinder;
+class AliL3TrackMerger;
+class AliL3GlobalMerger;
+class TDirectory;
+class AliL3Transform;
+class AliL3ClustFinder;
+class AliL3Merger;
+class AliL3InterMerger;
+class AliL3FileHandler;
+class AliL3Benchmark;
+
+class AliLevel3 : public TObject {
+
+ private:
+ UInt_t fNTrackData;
+ AliL3TrackSegmentData* fTrackData; //!
+ AliL3ConfMapper *fTracker; //!
+ AliL3Vertex *fVertex; //!
+ AliL3VertexFinder *fVertexFinder; //!
+ AliL3TrackMerger *fTrackMerger; //!
+ AliL3GlobalMerger *fGlobalMerger; //!
+ AliL3InterMerger *fInterMerger; //!
+ AliL3ClustFinder *fClusterFinder; //!
+ AliL3FileHandler *fFileHandler; //!
+ AliL3Benchmark *fBenchmark;//!
+ Int_t fNPatch;
+ Char_t fPath[256];
+ AliL3Transform *fTransformer; //!
+ TDirectory *savedir;
+ TFile *fInputFile;
+ TFile *fOutputFile;
+ Bool_t fFindVertex;
+ void Init();
+ void WriteSpacePoints(UInt_t npoints,AliL3SpacePointData *points,
+ Int_t slice,Int_t patch);
+ void WriteResults();
+ Int_t WriteTracks(char *filename,AliL3Merger *merger,char opt='o');
+ Float_t fEta[2];
+ Bool_t fDoRoi;
+ Bool_t fUseBinary;
+ Bool_t fWriteOut;
+ void SetPath(char *p){sprintf(fPath,"%s",p);}
+ public:
+ AliLevel3 ();
+ AliLevel3(Char_t *infile,Char_t *outfile);
+ AliLevel3(TFile *in, TFile *out);
+ virtual ~AliLevel3();
+
+ void SetTrackerParam(Int_t phi_segments=50,Int_t eta_segments=100,
+ Int_t trackletlength=3,Int_t tracklength=5,
+ Int_t rowscopetracklet=2,Int_t rowscopetrack=3,
+ Double_t min_pt_fit=0,Double_t maxangle=1.31,
+ Double_t goodDist=5,Double_t hitChi2Cut=10,
+ Double_t goodHitChi2=20,Double_t trackChi2Cut=50,
+ Int_t maxdist=50);
+
+
+ void ProcessEvent(Int_t first,Int_t last);
+ void ProcessSlice(Int_t slice);
+
+
+ void UseBinaryInput(char *path){SetPath(path);fUseBinary=kTRUE;}
+ void DoMc(char* file="point_mc.dat");
+ void DoBench(char* name="benchmark");
+ void DoRoi(Float_t e0=0.4,Float_t e1=0.5){fEta[0]=e0;fEta[1]=e1;fDoRoi=kTRUE;}
+ void WriteFiles(){fWriteOut = kTRUE;}
+ ClassDef(AliLevel3,1) //Interface class for Level3-tracking
+};
+
+#endif
--- /dev/null
+//Author: Uli Frankenfeld
+//Author: Anders Strand Vestbo
+//Last Modified: 13.12.2000
+
+#include <TFile.h>
+#include <TDirectory.h>
+#include <TClonesArray.h>
+#include <TStopwatch.h>
+#include <iostream.h>
+
+#include "AliL3Logging.h"
+#include "AliLevel3_Root.h"
+#include "AliL3ConfMapper.h"
+#include "AliL3Vertex.h"
+#include "AliL3VertexFinder.h"
+#include "AliL3TrackMerger.h"
+#include "AliL3GlobalMerger.h"
+#include "AliL3InterMerger.h"
+#include "AliL3ConfMapPoint.h"
+#include "AliL3ConfMapTrack.h"
+#include "AliL3Transform.h"
+#include "AliL3ClustFinder.h"
+#include "AliL3DigitData.h"
+#include "AliL3TrackArray.h"
+#include "AliL3MemHandler.h"
+#include "AliL3Benchmark.h"
+
+#include "AliL3DigitData.h"
+#include "AliL3TrackSegmentData.h"
+#include "AliL3SpacePointData.h"
+#include "AliL3VertexData.h"
+
+//_______________________________________
+//
+// AliLevel3
+//
+// Interface class for Level3 tracker.
+// Tracking is done by calling constructor with input,output
+// given as argument.
+// You must always remember to set the tracking parameters. E.g.:
+//
+// AliLevel3 *level3 = new AliLevel3(inputfile,outputfile);
+// level3->SetTrackerParam(); //Sets default tracking parameters
+// level3->ProcessSector(2,2); //Does tracking on sector 2 (actually 2+38)
+
+ClassImp(AliLevel3)
+
+AliLevel3::AliLevel3(){
+ fInputFile=0;
+ fOutputFile=0;
+ Init();
+}
+
+AliLevel3::AliLevel3(Char_t *infile,Char_t *outfile){
+ //Constructor. Calls constructor of the tracker, vertexfinder and merger classes.
+
+ fOutputFile = new TFile(outfile,"NEW");
+
+ if(!fOutputFile->IsOpen())
+ {
+ LOG(AliL3Log::kWarning, "AliLevel3::AliLevel3","File Open")
+ <<"Delete your old "<<outfile<<" file!"<<ENDLOG;
+ }
+ fInputFile = new TFile(infile,"READ");
+
+ if(!fInputFile->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Inputfile "<<infile<<" does not exist"<<ENDLOG;
+ return;
+ }
+
+ Init();
+}
+
+AliLevel3::AliLevel3(TFile *in, TFile *out){
+ fOutputFile = out;
+ fInputFile = in;
+ if(!in){
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Pointer to InFile 0x0!"<<ENDLOG;
+ return;
+ }
+ if(!out){
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Pointer to OutFile 0x0!"<<ENDLOG;
+ return;
+ }
+
+ if(!fOutputFile->IsOpen())
+ {
+ LOG(AliL3Log::kWarning,"AliLevel3::AliLevel3","File Open")
+ <<"no output file!"<<ENDLOG;
+ return;
+ }
+ if(!fInputFile->IsOpen())
+ {
+ LOG(AliL3Log::kError,"AliLevel3::AliLevel3","File Open")
+ <<"Inputfile does not exist"<<ENDLOG;
+ return;
+ }
+ Init();
+}
+
+void AliLevel3::Init(){
+ fWriteOut = kFALSE;
+ fGlobalMerger=0;
+ fTransformer = new AliL3Transform();
+ fDoRoi = kFALSE;
+ fUseBinary =kFALSE;
+ SetPath("");
+ fFindVertex =kTRUE;
+ fNPatch = 5; //number of patches change row in process
+ fVertexFinder = new AliL3VertexFinder();
+ fVertex = new AliL3Vertex();
+ fTracker = new AliL3ConfMapper();
+ fTrackMerger = new AliL3TrackMerger(fNPatch);
+ fInterMerger = new AliL3InterMerger();
+ fFileHandler = new AliL3MemHandler();
+ fBenchmark = new AliL3Benchmark();
+}
+
+void AliLevel3::DoBench(char* name){
+ fBenchmark->Analyze(name);
+}
+
+void AliLevel3::DoMc(char* file){
+}
+
+AliLevel3::~AliLevel3(){
+ //Destructor
+ if(fVertexFinder) delete fVertexFinder;
+ if(fVertex) delete fVertex;
+ if(fTracker) delete fTracker;
+ if(fTransformer) delete fTransformer;
+ if(fTrackMerger) delete fTrackMerger;
+ if(fInterMerger) delete fInterMerger;
+ if(fFileHandler) delete fFileHandler;
+}
+
+void AliLevel3::SetTrackerParam(Int_t phi_segments, Int_t eta_segments,
+ Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,
+ Double_t min_pt_fit, Double_t maxangle,
+ Double_t goodDist, Double_t hitChi2Cut,
+ Double_t goodHitChi2, Double_t trackChi2Cut,
+ Int_t maxdist)
+{
+ //Set parameters input to the tracker
+ //If no arguments are given, default parameters will be used
+
+ fTracker->SetNSegments(phi_segments,eta_segments);
+ fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
+ fTracker->SetMaxDca(min_pt_fit);
+ fTracker->SetTrackletCuts(maxangle,goodDist,true);
+ fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist);
+
+ fTracker->SetParamDone(true);
+}
+
+void AliLevel3::ProcessEvent(Int_t first,Int_t last){
+ //Do tracking on all slices in region [first,last]
+ //Slices numbering in TPC goes from 0-35, which means that 1 slice
+ //corresponds to inner+outer sector.E.g. slice 2 corresponds to
+ //inner=2 + outer=38.
+ fGlobalMerger= new AliL3GlobalMerger(first,last);
+ for(Int_t i=first; i<=last; i++){
+ ProcessSlice(i);
+ fGlobalMerger->SetVertex(fVertex);
+ fGlobalMerger->SetTransformer(fTransformer);
+ fGlobalMerger->InitSlice(i);
+// fBenchmark->Start("Fill Global Merger");
+ fGlobalMerger->FillTracks(fNTrackData,fTrackData);
+// fBenchmark->Stop("Fill Global Merger");
+ fFileHandler->Free(); //free the memory
+ fNTrackData=0;
+ fTrackData=0;
+ }
+ fBenchmark->Start("Global Merger");
+ fGlobalMerger->Merge();
+// fGlobalMerger->SlowMerge();
+ fBenchmark->Stop("Global Merger");
+
+ if(fWriteOut) WriteResults();
+ delete fGlobalMerger; fGlobalMerger = 0;
+}
+
+void AliLevel3::ProcessSlice(Int_t slice){
+ char name[256];
+// Int_t row[5][2] = {{ 0,173}};
+ Int_t row[5][2] = {{ 0, 45},{46,77},{78,109},{110,141},{142,173}};
+ const Int_t maxpoints=100000;
+ const Int_t pointsize = maxpoints * sizeof(AliL3SpacePointData);
+ AliL3MemHandler *memory = new AliL3MemHandler();
+
+ fTrackMerger->Reset();
+ fTrackMerger->SetTransformer(fTransformer);
+ fTrackMerger->SetRows(row[0]);
+ for(Int_t patch=fNPatch-1;patch>=0;patch--){
+ fFileHandler->Init(slice,patch,row[patch]);
+ fFileHandler->Init(fTransformer);
+ UInt_t npoints=0;
+ AliL3SpacePointData *points =0;
+ UInt_t ndigits=0;
+ AliL3DigitRowData *digits =0;
+ if(fUseBinary){
+
+ if(!fDoRoi){
+ if(0){ //Binary to Memory
+ fFileHandler->Free();
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ fFileHandler->SetBinaryInput(name);
+ digits= (AliL3DigitRowData *)fFileHandler->CompBinary2Memory(ndigits);
+ fFileHandler->CloseBinaryInput();
+ }
+
+ if(1){ //Binary to Memory with Benchmark
+ fFileHandler->Free();
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliL3DigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ }
+
+ if(0){ //Binary to Memory with Random
+ fFileHandler->Free();
+ fFileHandler->ResetRandom();
+ fFileHandler->SetRandomCluster(100);
+ fFileHandler->SetNGenerate(100);
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t dsize=memory->GetMemorySize(ndigits,comp);
+ UInt_t rsize=fFileHandler->GetRandomSize();
+ digits=(AliL3DigitRowData*)fFileHandler->Allocate(dsize+rsize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ if(0)
+ cerr<<endl<<dsize/1024<<" "<<rsize/1024<<" "
+ <<100.*rsize/dsize<<"%"<<endl;
+ }
+ }
+
+ else{ //Binary to Memory with Roi
+ fFileHandler->Free();
+ Int_t sli[2]={0,0};
+ fFileHandler->SetROI(fEta,sli);
+ sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,patch);
+ memory->SetBinaryInput(name);
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliL3DigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ if(0)
+ cerr<<endl<<datasize/1024<<" "<<endl;
+ }
+
+
+ points = (AliL3SpacePointData *) memory->Allocate(pointsize);
+
+ fClusterFinder = new AliL3ClustFinder(fTransformer);
+ fClusterFinder->InitSlice(slice,patch,row[patch][0],row[patch][1]
+ ,maxpoints);
+ fClusterFinder->SetXYError(0.1);
+ fClusterFinder->SetZError(0.2);
+ fClusterFinder->SetOutputArray(points);
+// fBenchmark->Start("Read Cluster Finder");
+ fClusterFinder->Read(ndigits,digits);
+// fBenchmark->Stop("Read Cluster Finder");
+ fBenchmark->Start("Cluster Finder");
+ fClusterFinder->ProcessDigits();
+ fBenchmark->Stop("Cluster Finder");
+ npoints = fClusterFinder->GetNumberOfClusters();
+ delete fClusterFinder;
+ fClusterFinder =0;
+ fFileHandler->Free();
+
+ LOG(AliL3Log::kInformational,"AliLevel3::ProcessSlice","Cluster Finder")
+ <<AliL3Log::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
+ }
+
+ else{
+
+ }
+
+ if(patch == fNPatch-1){
+ // Vertex
+ if(fFindVertex){
+ // Vertex Finder
+
+ fBenchmark->Start("Vertex Finder Read");
+ fVertexFinder->Reset();
+ fVertexFinder->Read(npoints,points);
+ fBenchmark->Stop("Vertex Finder Read");
+ fBenchmark->Start("Vertex Finder");
+
+ fVertexFinder->Analyze();
+ AliL3VertexData vertex[1];
+ fVertexFinder->Write(vertex);
+ fVertex->Read(vertex);
+ fBenchmark->Stop("Vertex Finder");
+ }
+ else{
+ //use 0,0,0 for vertex
+ fVertex->SetZero();
+ }
+ fTrackMerger->SetVertex(fVertex);
+ }
+ fTracker->InitSector(slice,row[patch]);
+ fTracker->SetVertex(fVertex);
+ fBenchmark->Start("Tracker Read Hits");
+ fTracker->ReadHits(npoints,points);
+ fBenchmark->Stop("Tracker Read Hits");
+ fBenchmark->Start("MainVertexTracking A");
+ fTracker->MainVertexTracking_a();
+ fBenchmark->Stop("MainVertexTracking A");
+ fBenchmark->Start("MainVertexTracking B");
+ fTracker->MainVertexTracking_b();
+ fBenchmark->Stop("MainVertexTracking B");
+ fBenchmark->Start("Tracking fit");
+ fTracker->FillTracks();
+ fBenchmark->Stop("Tracking fit");
+
+ if(fWriteOut)
+ WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
+ fFileHandler->Free();
+
+ UInt_t ntracks0 =0;
+ AliL3TrackSegmentData *trackdata0 =
+ (AliL3TrackSegmentData *) memory->Allocate(fTracker->GetTracks());
+ memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
+
+ //write tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_tr_%d_%d.raw",slice,patch);
+ memory->SetBinaryOutput(name);
+ memory->Memory2Binary(ntracks0,trackdata0);
+ memory->CloseBinaryOutput();
+ }
+
+ fInterMerger->Reset();
+ fInterMerger->SetTransformer(fTransformer);
+ fInterMerger->Init(row[patch],patch);
+
+// fBenchmark->Start("Fill Inter Merger");
+ fInterMerger->FillTracks(ntracks0,trackdata0);
+// fBenchmark->Stop("Fill Inter Merger");
+ fBenchmark->Start("Inter Merger");
+ fInterMerger->Merge();
+// fInterMerger->SlowMerge();
+
+ fBenchmark->Stop("Inter Merger");
+
+ //write inter merged tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_im_%d_%d.raw",slice,patch);
+ WriteTracks(name,fInterMerger,'i'); //write output of intermerger
+ }
+ memory->Free();
+
+ UInt_t ntracks1 =0;
+ AliL3TrackSegmentData *trackdata1 =
+ (AliL3TrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
+ memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
+
+ fTrackMerger->InitSector(slice,patch);
+// fBenchmark->Start("Fill Patch Merger");
+ fTrackMerger->FillTracks(ntracks1,trackdata1);
+// fBenchmark->Stop("Fill Patch Merger");
+
+ memory->Free();
+ }
+ fBenchmark->Start("Patch Merger");
+// fTrackMerger->SlowMerge();
+ fTrackMerger->Merge();
+ fBenchmark->Stop("Patch Merger");
+ //write merged tracks
+ if(fWriteOut){
+ sprintf(name,"tracks_tm_%d.raw",slice);
+ WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
+ }
+
+ fTrackData = (AliL3TrackSegmentData *)
+ fFileHandler->Allocate(fTrackMerger->GetOutTracks());
+
+ fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
+ fTrackMerger->GetOutTracks());
+
+ delete memory;
+}
+
+void AliLevel3::WriteSpacePoints(UInt_t npoints,AliL3SpacePointData *points,
+ Int_t slice,Int_t patch){
+ char name[256];
+ sprintf(name,"points_%d_%d.raw",slice,patch);
+ AliL3MemHandler * memory = new AliL3MemHandler();
+ memory->SetBinaryOutput(name);
+ memory->Transform(npoints,points,slice,fTransformer);
+ memory->Memory2Binary(npoints,points);
+ memory->CloseBinaryOutput();
+ delete memory;
+}
+
+
+Int_t AliLevel3::WriteTracks(char *filename,AliL3Merger *merger,char opt){
+ AliL3MemHandler *memory = new AliL3MemHandler();
+ memory->SetBinaryOutput(filename);
+ if(opt=='a'||opt=='i'){ //add intracks
+ for(Int_t i=0;i<merger->GetNIn();i++){
+ AliL3TrackArray *tr=merger->GetInTracks(i);
+ memory->TrackArray2Binary(tr);
+ }
+ }
+
+ if(opt=='o'||opt=='a'){
+ AliL3TrackArray *tr=merger->GetOutTracks();
+ memory->TrackArray2Binary(tr);
+ }
+
+ memory->CloseBinaryOutput();
+
+ return 1;
+}
+
+void AliLevel3::WriteResults()
+{
+ //Write the resulting tracks to outputfile
+ WriteTracks("tracks.raw",fGlobalMerger,'a');
+}
--- /dev/null
+#ifndef ALILEVEL3_H
+#define ALILEVEL3_H
+
+#include <TBuffer.h>
+#include <TFile.h>
+
+#include "AliL3DigitData.h"
+#include "AliL3RootTypes.h"
+
+class AliL3SpacePointData;
+class AliL3DigitRowData;
+class AliL3TrackSegmentData;
+class AliL3DigitData;
+class AliL3Transform;
+class AliL3ConfMapper;
+class AliL3Vertex;
+class AliL3VertexFinder;
+class AliL3TrackMerger;
+class AliL3GlobalMerger;
+class AliL3Transform;
+class AliL3ClustFinder;
+class AliL3Merger;
+class AliL3InterMerger;
+class AliL3MemHandler;
+class AliL3Benchmark;
+
+class AliLevel3{
+
+ private:
+ UInt_t fNTrackData;
+ AliL3TrackSegmentData* fTrackData; //!
+ AliL3ConfMapper *fTracker; //!
+ AliL3Vertex *fVertex; //!
+ AliL3VertexFinder *fVertexFinder; //!
+ AliL3TrackMerger *fTrackMerger; //!
+ AliL3GlobalMerger *fGlobalMerger; //!
+ AliL3InterMerger *fInterMerger; //!
+ AliL3ClustFinder *fClusterFinder; //!
+ AliL3MemHandler *fFileHandler; //!
+ AliL3Benchmark *fBenchmark;//!
+ Int_t fNPatch;
+ Char_t fPath[256];
+ AliL3Transform *fTransformer; //!
+ TDirectory *savedir;
+ TFile *fInputFile;
+ TFile *fOutputFile;
+ Bool_t fFindVertex;
+ void Init();
+ void WriteSpacePoints(UInt_t npoints,AliL3SpacePointData *points,
+ Int_t slice,Int_t patch);
+ void WriteResults();
+ Int_t WriteTracks(char *filename,AliL3Merger *merger,char opt='o');
+ Float_t fEta[2];
+ Bool_t fDoRoi;
+ Bool_t fUseBinary;
+ Bool_t fWriteOut;
+ void SetPath(char *p){sprintf(fPath,"%s",p);}
+ public:
+ AliLevel3 ();
+ AliLevel3(Char_t *infile,Char_t *outfile);
+ AliLevel3(TFile *in, TFile *out);
+ virtual ~AliLevel3();
+
+ void SetTrackerParam(Int_t phi_segments=50,Int_t eta_segments=100,
+ Int_t trackletlength=3,Int_t tracklength=5,
+ Int_t rowscopetracklet=2,Int_t rowscopetrack=3,
+ Double_t min_pt_fit=0,Double_t maxangle=1.31,
+ Double_t goodDist=5,Double_t hitChi2Cut=10,
+ Double_t goodHitChi2=20,Double_t trackChi2Cut=50,
+ Int_t maxdist=50);
+
+
+ void ProcessEvent(Int_t first,Int_t last);
+ void ProcessSlice(Int_t slice);
+
+
+ void UseBinaryInput(char *path){SetPath(path);fUseBinary=kTRUE;}
+ void DoMc(char* file="point_mc.dat");
+ void DoBench(char* name="benchmark");
+ void DoRoi(Float_t e0=0.4,Float_t e1=0.5){fEta[0]=e0;fEta[1]=e1;fDoRoi=kTRUE;}
+ void WriteFiles(){fWriteOut = kTRUE;}
+ ClassDef(AliLevel3,1) //Interface class for Level3-tracking
+};
+
+#endif
--- /dev/null
+############################### TPC Makefile ##################################
+
+# Include machine specific definitions
+
+include $(ALICE_ROOT)/conf/GeneralDef
+include $(ALICE_ROOT)/conf/MachineDef.$(ALICE_TARGET)
+
+PACKAGE = AliL3
+
+# C++ sources
+
+
+SRCS = AliL3ConfMapper.cxx AliL3ConfMapPoint.cxx AliLevel3.cxx\
+ &nbs