This commit was generated by cvs2svn to compensate for changes in r3176,
authorfranken <franken@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 22 Mar 2001 15:19:09 +0000 (15:19 +0000)
committerfranken <franken@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 22 Mar 2001 15:19:09 +0000 (15:19 +0000)
which included commits to RCS files with non-trunk default branches.

62 files changed:
HLT/src/.nfs002b88e300000129 [new file with mode: 0644]
HLT/src/AliL3Benchmark.cxx [new file with mode: 0644]
HLT/src/AliL3Benchmark.h [new file with mode: 0644]
HLT/src/AliL3ClustFinder.cxx [new file with mode: 0644]
HLT/src/AliL3ClustFinder.h [new file with mode: 0644]
HLT/src/AliL3ConfMapFit.cxx [new file with mode: 0644]
HLT/src/AliL3ConfMapFit.h [new file with mode: 0644]
HLT/src/AliL3ConfMapPoint.cxx [new file with mode: 0644]
HLT/src/AliL3ConfMapPoint.h [new file with mode: 0644]
HLT/src/AliL3ConfMapTrack.cxx [new file with mode: 0644]
HLT/src/AliL3ConfMapTrack.h [new file with mode: 0644]
HLT/src/AliL3ConfMapper.cxx [new file with mode: 0644]
HLT/src/AliL3ConfMapper.h [new file with mode: 0644]
HLT/src/AliL3Defs.h [new file with mode: 0644]
HLT/src/AliL3DigitData.h [new file with mode: 0644]
HLT/src/AliL3Display.cxx [new file with mode: 0644]
HLT/src/AliL3Display.h [new file with mode: 0644]
HLT/src/AliL3Evaluate.cxx [new file with mode: 0644]
HLT/src/AliL3Evaluate.h [new file with mode: 0644]
HLT/src/AliL3FileHandler.cxx [new file with mode: 0644]
HLT/src/AliL3FileHandler.h [new file with mode: 0644]
HLT/src/AliL3GlobalMerger.cxx [new file with mode: 0644]
HLT/src/AliL3GlobalMerger.h [new file with mode: 0644]
HLT/src/AliL3HoughTrack.cxx [new file with mode: 0644]
HLT/src/AliL3HoughTrack.h [new file with mode: 0644]
HLT/src/AliL3InterMerger.cxx [new file with mode: 0644]
HLT/src/AliL3InterMerger.h [new file with mode: 0644]
HLT/src/AliL3LinkDef.h [new file with mode: 0644]
HLT/src/AliL3Logger.cxx [new file with mode: 0644]
HLT/src/AliL3Logger.h [new file with mode: 0644]
HLT/src/AliL3Logging.h [new file with mode: 0644]
HLT/src/AliL3MemHandler.cxx [new file with mode: 0644]
HLT/src/AliL3MemHandler.h [new file with mode: 0644]
HLT/src/AliL3Merger.cxx [new file with mode: 0644]
HLT/src/AliL3Merger.h [new file with mode: 0644]
HLT/src/AliL3RootTypes.h [new file with mode: 0644]
HLT/src/AliL3SpacePointData.h [new file with mode: 0644]
HLT/src/AliL3Track.cxx [new file with mode: 0644]
HLT/src/AliL3Track.h [new file with mode: 0644]
HLT/src/AliL3TrackArray.cxx [new file with mode: 0644]
HLT/src/AliL3TrackArray.h [new file with mode: 0644]
HLT/src/AliL3TrackMerger.cxx [new file with mode: 0644]
HLT/src/AliL3TrackMerger.h [new file with mode: 0644]
HLT/src/AliL3TrackSegmentData.h [new file with mode: 0644]
HLT/src/AliL3Transform.cxx [new file with mode: 0644]
HLT/src/AliL3Transform.h [new file with mode: 0644]
HLT/src/AliL3Vertex.cxx [new file with mode: 0644]
HLT/src/AliL3Vertex.h [new file with mode: 0644]
HLT/src/AliL3VertexArray.cxx [new file with mode: 0644]
HLT/src/AliL3VertexArray.h [new file with mode: 0644]
HLT/src/AliL3VertexData.h [new file with mode: 0644]
HLT/src/AliL3VertexFinder.cxx [new file with mode: 0644]
HLT/src/AliL3VertexFinder.h [new file with mode: 0644]
HLT/src/AliLevel3.cxx [new file with mode: 0644]
HLT/src/AliLevel3.h [new file with mode: 0644]
HLT/src/AliLevel3_Root.cxx [new file with mode: 0644]
HLT/src/AliLevel3_Root.h [new file with mode: 0644]
HLT/src/Makefile [new file with mode: 0644]
HLT/src/Makefile_Root [new file with mode: 0644]
HLT/src/doit [new file with mode: 0644]
HLT/src/speedtest.cxx [new file with mode: 0644]
HLT/src/speedtest.h [new file with mode: 0644]

diff --git a/HLT/src/.nfs002b88e300000129 b/HLT/src/.nfs002b88e300000129
new file mode 100644 (file)
index 0000000..171df4b
Binary files /dev/null and b/HLT/src/.nfs002b88e300000129 differ
diff --git a/HLT/src/AliL3Benchmark.cxx b/HLT/src/AliL3Benchmark.cxx
new file mode 100644 (file)
index 0000000..385ed1f
--- /dev/null
@@ -0,0 +1,155 @@
+#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;
+}
+
+
diff --git a/HLT/src/AliL3Benchmark.h b/HLT/src/AliL3Benchmark.h
new file mode 100644 (file)
index 0000000..92a3a78
--- /dev/null
@@ -0,0 +1,33 @@
+#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
diff --git a/HLT/src/AliL3ClustFinder.cxx b/HLT/src/AliL3ClustFinder.cxx
new file mode 100644 (file)
index 0000000..30fdda1
--- /dev/null
@@ -0,0 +1,484 @@
+//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++;
+
+    }
+
+  
+}
diff --git a/HLT/src/AliL3ClustFinder.h b/HLT/src/AliL3ClustFinder.h
new file mode 100644 (file)
index 0000000..4faba7a
--- /dev/null
@@ -0,0 +1,83 @@
+#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
diff --git a/HLT/src/AliL3ConfMapFit.cxx b/HLT/src/AliL3ConfMapFit.cxx
new file mode 100644 (file)
index 0000000..6e6b21a
--- /dev/null
@@ -0,0 +1,510 @@
+#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 ;
+} 
diff --git a/HLT/src/AliL3ConfMapFit.h b/HLT/src/AliL3ConfMapFit.h
new file mode 100644 (file)
index 0000000..8cfb69a
--- /dev/null
@@ -0,0 +1,30 @@
+#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
diff --git a/HLT/src/AliL3ConfMapPoint.cxx b/HLT/src/AliL3ConfMapPoint.cxx
new file mode 100644 (file)
index 0000000..e212b8b
--- /dev/null
@@ -0,0 +1,223 @@
+//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());
+}
+*/
diff --git a/HLT/src/AliL3ConfMapPoint.h b/HLT/src/AliL3ConfMapPoint.h
new file mode 100644 (file)
index 0000000..0ace974
--- /dev/null
@@ -0,0 +1,184 @@
+#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
diff --git a/HLT/src/AliL3ConfMapTrack.cxx b/HLT/src/AliL3ConfMapTrack.cxx
new file mode 100644 (file)
index 0000000..f38a99c
--- /dev/null
@@ -0,0 +1,317 @@
+
+//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;
+  */
+}
+
diff --git a/HLT/src/AliL3ConfMapTrack.h b/HLT/src/AliL3ConfMapTrack.h
new file mode 100644 (file)
index 0000000..df25573
--- /dev/null
@@ -0,0 +1,66 @@
+#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
+    
diff --git a/HLT/src/AliL3ConfMapper.cxx b/HLT/src/AliL3ConfMapper.cxx
new file mode 100644 (file)
index 0000000..0d4f90a
--- /dev/null
@@ -0,0 +1,834 @@
+
+//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;
+}
diff --git a/HLT/src/AliL3ConfMapper.h b/HLT/src/AliL3ConfMapper.h
new file mode 100644 (file)
index 0000000..48b11f2
--- /dev/null
@@ -0,0 +1,142 @@
+#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
diff --git a/HLT/src/AliL3Defs.h b/HLT/src/AliL3Defs.h
new file mode 100644 (file)
index 0000000..129d8df
--- /dev/null
@@ -0,0 +1,11 @@
+#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_ */
diff --git a/HLT/src/AliL3DigitData.h b/HLT/src/AliL3DigitData.h
new file mode 100644 (file)
index 0000000..de89851
--- /dev/null
@@ -0,0 +1,29 @@
+#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_ */
diff --git a/HLT/src/AliL3Display.cxx b/HLT/src/AliL3Display.cxx
new file mode 100644 (file)
index 0000000..a425989
--- /dev/null
@@ -0,0 +1,363 @@
+//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");
+  
+}
diff --git a/HLT/src/AliL3Display.h b/HLT/src/AliL3Display.h
new file mode 100644 (file)
index 0000000..9942daf
--- /dev/null
@@ -0,0 +1,35 @@
+#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
diff --git a/HLT/src/AliL3Evaluate.cxx b/HLT/src/AliL3Evaluate.cxx
new file mode 100644 (file)
index 0000000..356be29
--- /dev/null
@@ -0,0 +1,760 @@
+//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;
+
+}
+
diff --git a/HLT/src/AliL3Evaluate.h b/HLT/src/AliL3Evaluate.h
new file mode 100644 (file)
index 0000000..24d53b7
--- /dev/null
@@ -0,0 +1,89 @@
+#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
diff --git a/HLT/src/AliL3FileHandler.cxx b/HLT/src/AliL3FileHandler.cxx
new file mode 100644 (file)
index 0000000..d1e7b1a
--- /dev/null
@@ -0,0 +1,379 @@
+
+//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;
+}
+
diff --git a/HLT/src/AliL3FileHandler.h b/HLT/src/AliL3FileHandler.h
new file mode 100644 (file)
index 0000000..6038b2f
--- /dev/null
@@ -0,0 +1,54 @@
+#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
diff --git a/HLT/src/AliL3GlobalMerger.cxx b/HLT/src/AliL3GlobalMerger.cxx
new file mode 100644 (file)
index 0000000..f6e4f70
--- /dev/null
@@ -0,0 +1,184 @@
+
+//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;
+  }
+}
diff --git a/HLT/src/AliL3GlobalMerger.h b/HLT/src/AliL3GlobalMerger.h
new file mode 100644 (file)
index 0000000..4e0f30d
--- /dev/null
@@ -0,0 +1,27 @@
+#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
diff --git a/HLT/src/AliL3HoughTrack.cxx b/HLT/src/AliL3HoughTrack.cxx
new file mode 100644 (file)
index 0000000..edd620a
--- /dev/null
@@ -0,0 +1,277 @@
+
+#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;
+}
diff --git a/HLT/src/AliL3HoughTrack.h b/HLT/src/AliL3HoughTrack.h
new file mode 100644 (file)
index 0000000..5835803
--- /dev/null
@@ -0,0 +1,46 @@
+#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
diff --git a/HLT/src/AliL3InterMerger.cxx b/HLT/src/AliL3InterMerger.cxx
new file mode 100644 (file)
index 0000000..63af893
--- /dev/null
@@ -0,0 +1,137 @@
+
+//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;
+}
+
+
diff --git a/HLT/src/AliL3InterMerger.h b/HLT/src/AliL3InterMerger.h
new file mode 100644 (file)
index 0000000..9d6aa5d
--- /dev/null
@@ -0,0 +1,26 @@
+#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
diff --git a/HLT/src/AliL3LinkDef.h b/HLT/src/AliL3LinkDef.h
new file mode 100644 (file)
index 0000000..a3d03a6
--- /dev/null
@@ -0,0 +1,36 @@
+#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
+
diff --git a/HLT/src/AliL3Logger.cxx b/HLT/src/AliL3Logger.cxx
new file mode 100644 (file)
index 0000000..84d30a5
--- /dev/null
@@ -0,0 +1,69 @@
+#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
+
diff --git a/HLT/src/AliL3Logger.h b/HLT/src/AliL3Logger.h
new file mode 100644 (file)
index 0000000..2ab6a72
--- /dev/null
@@ -0,0 +1,32 @@
+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;
+};
+
+
diff --git a/HLT/src/AliL3Logging.h b/HLT/src/AliL3Logging.h
new file mode 100644 (file)
index 0000000..40d7b57
--- /dev/null
@@ -0,0 +1,33 @@
+#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
+
+
diff --git a/HLT/src/AliL3MemHandler.cxx b/HLT/src/AliL3MemHandler.cxx
new file mode 100644 (file)
index 0000000..ccaf227
--- /dev/null
@@ -0,0 +1,1096 @@
+//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;
+}
+
diff --git a/HLT/src/AliL3MemHandler.h b/HLT/src/AliL3MemHandler.h
new file mode 100644 (file)
index 0000000..e7ca880
--- /dev/null
@@ -0,0 +1,151 @@
+#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
diff --git a/HLT/src/AliL3Merger.cxx b/HLT/src/AliL3Merger.cxx
new file mode 100644 (file)
index 0000000..12fbe2a
--- /dev/null
@@ -0,0 +1,415 @@
+
+//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());
+  }
+}
+
+
+
+
diff --git a/HLT/src/AliL3Merger.h b/HLT/src/AliL3Merger.h
new file mode 100644 (file)
index 0000000..9bc0070
--- /dev/null
@@ -0,0 +1,76 @@
+#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
diff --git a/HLT/src/AliL3RootTypes.h b/HLT/src/AliL3RootTypes.h
new file mode 100644 (file)
index 0000000..afee044
--- /dev/null
@@ -0,0 +1,105 @@
+#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
diff --git a/HLT/src/AliL3SpacePointData.h b/HLT/src/AliL3SpacePointData.h
new file mode 100644 (file)
index 0000000..0782815
--- /dev/null
@@ -0,0 +1,17 @@
+#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 */
diff --git a/HLT/src/AliL3Track.cxx b/HLT/src/AliL3Track.cxx
new file mode 100644 (file)
index 0000000..6638705
--- /dev/null
@@ -0,0 +1,281 @@
+//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);
+}
+
diff --git a/HLT/src/AliL3Track.h b/HLT/src/AliL3Track.h
new file mode 100644 (file)
index 0000000..cd09ce3
--- /dev/null
@@ -0,0 +1,158 @@
+#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
+    
diff --git a/HLT/src/AliL3TrackArray.cxx b/HLT/src/AliL3TrackArray.cxx
new file mode 100644 (file)
index 0000000..72488ae
--- /dev/null
@@ -0,0 +1,405 @@
+//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;
+}
+
+
diff --git a/HLT/src/AliL3TrackArray.h b/HLT/src/AliL3TrackArray.h
new file mode 100644 (file)
index 0000000..3876c3f
--- /dev/null
@@ -0,0 +1,62 @@
+#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
diff --git a/HLT/src/AliL3TrackMerger.cxx b/HLT/src/AliL3TrackMerger.cxx
new file mode 100644 (file)
index 0000000..54bf977
--- /dev/null
@@ -0,0 +1,280 @@
+
+//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;
+}
+
+
diff --git a/HLT/src/AliL3TrackMerger.h b/HLT/src/AliL3TrackMerger.h
new file mode 100644 (file)
index 0000000..fcbec85
--- /dev/null
@@ -0,0 +1,36 @@
+#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
diff --git a/HLT/src/AliL3TrackSegmentData.h b/HLT/src/AliL3TrackSegmentData.h
new file mode 100644 (file)
index 0000000..ba1ffad
--- /dev/null
@@ -0,0 +1,27 @@
+#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_ */
diff --git a/HLT/src/AliL3Transform.cxx b/HLT/src/AliL3Transform.cxx
new file mode 100644 (file)
index 0000000..cdcd6ba
--- /dev/null
@@ -0,0 +1,574 @@
+
+//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);
+
+}
diff --git a/HLT/src/AliL3Transform.h b/HLT/src/AliL3Transform.h
new file mode 100644 (file)
index 0000000..a32bf6c
--- /dev/null
@@ -0,0 +1,65 @@
+#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
diff --git a/HLT/src/AliL3Vertex.cxx b/HLT/src/AliL3Vertex.cxx
new file mode 100644 (file)
index 0000000..cbd2365
--- /dev/null
@@ -0,0 +1,60 @@
+//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.;
+}
+
diff --git a/HLT/src/AliL3Vertex.h b/HLT/src/AliL3Vertex.h
new file mode 100644 (file)
index 0000000..7c7cddb
--- /dev/null
@@ -0,0 +1,49 @@
+#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
diff --git a/HLT/src/AliL3VertexArray.cxx b/HLT/src/AliL3VertexArray.cxx
new file mode 100644 (file)
index 0000000..b384d9e
--- /dev/null
@@ -0,0 +1,106 @@
+//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;}
+}
+
diff --git a/HLT/src/AliL3VertexArray.h b/HLT/src/AliL3VertexArray.h
new file mode 100644 (file)
index 0000000..1c34af2
--- /dev/null
@@ -0,0 +1,108 @@
+#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
diff --git a/HLT/src/AliL3VertexData.h b/HLT/src/AliL3VertexData.h
new file mode 100644 (file)
index 0000000..6a9ea87
--- /dev/null
@@ -0,0 +1,16 @@
+#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 */
diff --git a/HLT/src/AliL3VertexFinder.cxx b/HLT/src/AliL3VertexFinder.cxx
new file mode 100644 (file)
index 0000000..b406876
--- /dev/null
@@ -0,0 +1,99 @@
+//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();
+}
diff --git a/HLT/src/AliL3VertexFinder.h b/HLT/src/AliL3VertexFinder.h
new file mode 100644 (file)
index 0000000..e232673
--- /dev/null
@@ -0,0 +1,55 @@
+#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
diff --git a/HLT/src/AliLevel3.cxx b/HLT/src/AliLevel3.cxx
new file mode 100644 (file)
index 0000000..3e49864
--- /dev/null
@@ -0,0 +1,473 @@
+//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');
+}
diff --git a/HLT/src/AliLevel3.h b/HLT/src/AliLevel3.h
new file mode 100644 (file)
index 0000000..59ed0a5
--- /dev/null
@@ -0,0 +1,88 @@
+#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
diff --git a/HLT/src/AliLevel3_Root.cxx b/HLT/src/AliLevel3_Root.cxx
new file mode 100644 (file)
index 0000000..82c3f41
--- /dev/null
@@ -0,0 +1,448 @@
+//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');
+}
diff --git a/HLT/src/AliLevel3_Root.h b/HLT/src/AliLevel3_Root.h
new file mode 100644 (file)
index 0000000..ccfe2d9
--- /dev/null
@@ -0,0 +1,85 @@
+#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
diff --git a/HLT/src/Makefile b/HLT/src/Makefile
new file mode 100644 (file)
index 0000000..6ec7262
--- /dev/null
@@ -0,0 +1,84 @@
+############################### TPC Makefile ##################################
+
+# Include machine specific definitions
+
+include $(ALICE_ROOT)/conf/GeneralDef
+include $(ALICE_ROOT)/conf/MachineDef.$(ALICE_TARGET)
+
+PACKAGE = AliL3
+
+# C++ sources
+
+
+SRCS          = AliL3ConfMa