Imported files from the existing L3 code directories (../src, ../comp,
authortimms <timms@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 7 Sep 2005 11:39:43 +0000 (11:39 +0000)
committertimms <timms@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 7 Sep 2005 11:39:43 +0000 (11:39 +0000)
../kalman, ...)into this module. All files that are required to run the
unpacker, cluster finder, vertex finder, slice (was sector) tracker,
and global merger components have been included. Code needed for the
houh transformation has been explicitly excluded.
Renamed all instances of AliL3 and AliLevel3 to AliHLTTPC in the process.

73 files changed:
HLT/TPCLib/AliHLTTPC.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPC.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCBenchmark.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCBenchmark.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCClustFinderNew.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCClustFinderNew.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCClusterDataFormat.h
HLT/TPCLib/AliHLTTPCClusterFinderComponent.cxx
HLT/TPCLib/AliHLTTPCClusterFinderComponent.h
HLT/TPCLib/AliHLTTPCConfMapFit.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapFit.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapPoint.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapPoint.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapTrack.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapTrack.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapper.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCConfMapper.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDDLDataFileHandler.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDDLDataFileHandler.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDataCompressorHelper.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDataCompressorHelper.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDefinitions.h
HLT/TPCLib/AliHLTTPCDigitData.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDisplay.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDisplay.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCFileHandler.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCFileHandler.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCFitter.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCFitter.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCGlobalMerger.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCGlobalMerger.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCGlobalMergerComponent.cxx
HLT/TPCLib/AliHLTTPCGlobalMergerComponent.h
HLT/TPCLib/AliHLTTPCInterMerger.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCInterMerger.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCLinkDef.h
HLT/TPCLib/AliHLTTPCLog.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCLog.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCLogging.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCMemHandler.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCMemHandler.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCMerger.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCMerger.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCModelTrack.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCModelTrack.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCModels.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCRawDataFormat.h
HLT/TPCLib/AliHLTTPCRawDataUnpackerComponent.cxx
HLT/TPCLib/AliHLTTPCRootTypes.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCSliceTrackerComponent.cxx
HLT/TPCLib/AliHLTTPCSliceTrackerComponent.h
HLT/TPCLib/AliHLTTPCSpacePointData.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCStandardIncludes.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrack.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrack.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackArray.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackArray.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackMerger.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackMerger.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackSegmentData.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTrackletDataFormat.h
HLT/TPCLib/AliHLTTPCTransform.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCTransform.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertex.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertex.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexArray.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexArray.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexData.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexFinder.cxx [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexFinder.h [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCVertexFinderComponent.cxx
HLT/TPCLib/AliHLTTPCVertexFinderComponent.h
HLT/TPCLib/Makefile

diff --git a/HLT/TPCLib/AliHLTTPC.cxx b/HLT/TPCLib/AliHLTTPC.cxx
new file mode 100644 (file)
index 0000000..bd78aa1
--- /dev/null
@@ -0,0 +1,700 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#ifndef no_root
+#include <TFile.h>
+#include <TDirectory.h>
+#include <TClonesArray.h>
+#include <TStopwatch.h>
+#endif
+
+#ifdef use_newio
+#include <AliRunLoader.h>
+#endif
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPC.h"
+#include "AliHLTTPCConfMapper.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCVertexFinder.h"
+#include "AliHLTTPCTrackMerger.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCInterMerger.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCFitter.h"
+#ifdef use_aliroot
+#include "AliHLTTPCFileHandler.h"
+#endif
+#include "AliHLTTPCBenchmark.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCVertexData.h"
+#include "AliHLTTPCDDLDataFileHandler.h"
+
+/** \class AliHLTTPC
+<pre>
+//_____________________________________________________________
+//
+//  AliHLTTPC
+//
+//  Interface class for HLTTPC tracker.
+//  For example how to use, see exa/runtracker.C (root)
+//  or programs/runtracker.cxx (standalone program).
+//Begin_Html 
+//<img src="tpcsectorsnb.gif">
+//End_Html
+</pre>
+*/
+
+ClassImp(AliHLTTPC)
+
+Bool_t AliHLTTPC::fgDoVertexFit = kTRUE;//Include the vertex in the final track fit
+
+AliHLTTPC::AliHLTTPC()
+{
+  //Default constructor. Should also be used when input is from binary files.
+  //In that case the path to where the binary files are located has to be
+  //passed to the AliLevel::Init function.
+  
+  fVertexFinder=0;
+  fVertex=0;
+  fTracker=0;
+  fTrackMerger=0;
+  fInterMerger=0;
+  fFileHandler=0;
+  fGlobalMerger=0;
+  fInputFile=0;
+#ifdef use_newio
+  fRunLoader=0;
+#endif
+}
+
+AliHLTTPC::AliHLTTPC(Char_t *infile)
+{
+  //Constructor to use for when input is anything else but binary files,
+  //meaning rootfiles or raw files.
+  
+  fVertexFinder=0;
+  fVertex=0;
+  fTracker=0;
+  fTrackMerger=0;
+  fInterMerger=0;
+  fFileHandler=0;
+  fGlobalMerger=0;
+  fInputFile = infile;
+#ifdef use_newio
+  fRunLoader=0;
+#endif
+}
+
+#ifdef use_newio
+AliHLTTPC::AliHLTTPC(AliRunLoader *rl)
+{
+  //Constructor to use when input is aliroot runloader
+  fVertexFinder=0;
+  fVertex=0;
+  fTracker=0;
+  fTrackMerger=0;
+  fInterMerger=0;
+  fFileHandler=0;
+  fGlobalMerger=0;
+  fInputFile=0;
+  fRunLoader = rl;
+}
+#endif
+
+void AliHLTTPC::Init(Char_t *path,EFileType filetype,Int_t npatches)
+{
+  //Init the whole standard tracker chain
+#ifndef use_newio
+  if (filetype==kRunLoader){
+    LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+       <<"You have not supplied the input rootfile; if you want "
+       <<"to run with RunLoader use -Duse_newio for compiling!"<<ENDLOG;
+  }
+#endif
+
+  if((filetype!=kBinary) && (filetype!=kDate) 
+       && (filetype!=kRunLoader)&& !fInputFile)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+       <<"You have not supplied the input rootfile; use the appropriate ctor!"<<ENDLOG;
+      return;
+    }
+#if use_newio
+  if((filetype==kRunLoader) && !fRunLoader)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+       <<"You have not supplied the input runloader; use the appropriate ctor!"<<ENDLOG;
+      return;
+    }
+#endif
+  
+  fWriteOut = kFALSE;
+  fPileUp = kFALSE;
+  fNoCF=kFALSE;
+  fUseBinary = (filetype==kBinary);
+  SetPath(path);
+  
+  fDoRoi = kFALSE;
+  fDoNonVertex = kFALSE;
+  fFindVertex = kFALSE;
+  SetClusterFinderParam();
+
+  fEta[0] = 0.;
+  fEta[1] = 1.1;
+
+  fEvent=0;
+#ifdef use_aliroot /*just to be sure*/
+  AliHLTTPCFileHandler::CleanStaticIndex();
+#endif
+
+  switch(npatches){
+  case 0:
+    fNPatch = 1;
+    fRow[0][0] = AliHLTTPCTransform::GetFirstRow(3);
+    fRow[0][1] = AliHLTTPCTransform::GetLastRow(5);
+    break;
+  case 1:
+    fNPatch = 1;        //number of patches change row in process
+    fRow[0][0] = 0;
+    fRow[0][1] = AliHLTTPCTransform::GetLastRow(-1);
+    break;
+  case 2:
+    fNPatch = 2;        //number of patches change row in process
+    fRow[0][0] = 0;     // first row
+    fRow[0][1] = AliHLTTPCTransform::GetLastRow(1);
+    fRow[1][0] = AliHLTTPCTransform::GetFirstRow(2);
+    fRow[1][1] = AliHLTTPCTransform::GetLastRow(5);
+    break;
+  default: 
+    fNPatch = 6;        
+    fRow[0][0] = AliHLTTPCTransform::GetFirstRow(0);
+    fRow[0][1] = AliHLTTPCTransform::GetLastRow(0);
+    fRow[1][0] = AliHLTTPCTransform::GetFirstRow(1);
+    fRow[1][1] = AliHLTTPCTransform::GetLastRow(1);
+    fRow[2][0] = AliHLTTPCTransform::GetFirstRow(2);
+    fRow[2][1] = AliHLTTPCTransform::GetLastRow(2);
+    fRow[3][0] = AliHLTTPCTransform::GetFirstRow(3);
+    fRow[3][1] = AliHLTTPCTransform::GetLastRow(3);
+    fRow[4][0] = AliHLTTPCTransform::GetFirstRow(4);
+    fRow[4][1] = AliHLTTPCTransform::GetLastRow(4);
+    fRow[5][0] = AliHLTTPCTransform::GetFirstRow(5);
+    fRow[5][1] = AliHLTTPCTransform::GetLastRow(5);
+  }
+
+  fVertexFinder = new AliHLTTPCVertexFinder();
+  fVertex = new AliHLTTPCVertex();
+  fTracker = new AliHLTTPCConfMapper();
+  fTrackMerger = new AliHLTTPCTrackMerger(fNPatch);
+  fInterMerger = new AliHLTTPCInterMerger();
+  fGlobalMerger = new AliHLTTPCGlobalMerger();
+  SetMergerParameters();//Set default merger parameters
+#ifdef use_aliroot
+  if(filetype==kRoot){
+    fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
+    fFileHandler->SetAliInput(fInputFile);
+  }else if(filetype==kRaw){
+    fFileHandler = new AliHLTTPCDDLDataFileHandler();
+    fFileHandler->SetReaderInput(fInputFile);
+  }else if(filetype==kDate){
+    fFileHandler = new AliHLTTPCDDLDataFileHandler();
+    fFileHandler->SetReaderInput(fInputFile,-1);
+  }
+#if use_newio
+  else if(filetype==kRunLoader){
+    fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
+    fFileHandler->SetAliInput(fRunLoader);
+  }
+#endif
+  else{
+    fFileHandler = new AliHLTTPCMemHandler();
+  }
+#else
+  if(filetype==kRaw){
+    fFileHandler = new AliHLTTPCDDLDataFileHandler();
+    fFileHandler->SetReaderInput(fInputFile);
+  }else{
+    fFileHandler = new AliHLTTPCMemHandler();
+  }
+#endif
+  fBenchmark = new AliHLTTPCBenchmark();
+}
+
+void AliHLTTPC::DoBench(char* name)
+{ 
+  //dobench
+  fBenchmark->Analyze(name);
+  delete fBenchmark;
+  fBenchmark = new AliHLTTPCBenchmark();
+}
+
+void AliHLTTPC::DoMc(char* file)
+{ 
+  //domc
+#ifdef use_aliroot
+  if(!fFileHandler->IsDigit(fEvent))
+    fFileHandler->SetMCOutput(file);
+#endif
+}
+
+AliHLTTPC::~AliHLTTPC()
+{
+  //Destructor
+  if(fVertexFinder) delete fVertexFinder;
+  if(fVertex) delete fVertex;
+  if(fTracker) delete fTracker;
+  if(fTrackMerger) delete fTrackMerger;
+  if(fInterMerger) delete fInterMerger;
+  if(fFileHandler) delete fFileHandler;
+  if(fGlobalMerger) delete fGlobalMerger;
+}
+
+void AliHLTTPC::SetClusterFinderParam(Float_t fXYError, Float_t fZError, Bool_t deconv)
+{ 
+  //set cluster finder parameter
+  fXYClusterError=fXYError;
+  fZClusterError=fZError;
+  fClusterDeconv=deconv;
+}
+
+void AliHLTTPC::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,Double_t maxphi,Double_t maxeta,
+                               Bool_t vertexconstraint)
+{
+  //Set parameters input to the tracker
+  //If no arguments are given, default parameters will be used
+  
+  fTracker->SetNSegments(phi_segments,eta_segments);
+  fTracker->SetMaxDca(min_pt_fit);
+  fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexconstraint);
+  fTracker->SetTrackletCuts(maxangle,goodDist,vertexconstraint);
+  if(vertexconstraint)
+    fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack,maxphi,maxeta);
+  else
+    fTracker->NonVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
+  fTracker->InitVolumes();
+}
+
+void AliHLTTPC::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
+{
+  //set global merger parameter
+  fGlobalMerger->SetParameter(maxy,maxz,maxkappa,maxpsi,maxtgl);
+}
+
+void AliHLTTPC::ProcessEvent(Int_t first,Int_t last,Int_t event)
+{
+  //Do tracking on all slices in region [first,last]
+  //Slices numbering in TPC goes from 0-35, which means that one slice
+  //corresponds to inner+outer sector.E.g. slice 2 corresponds to
+  //inner=2 + outer=38.
+
+  fGlobalMerger->Setup(first,last);
+#ifdef use_aliroot
+  if(fEvent!=event) AliHLTTPCFileHandler::CleanStaticIndex();
+#endif
+  fEvent=event;
+  for(Int_t i=first; i<=last; i++){
+    ProcessSlice(i);
+    fGlobalMerger->SetVertex(fVertex);
+    fGlobalMerger->InitSlice(i);
+    fGlobalMerger->FillTracks(fNTrackData,fTrackData);
+    fFileHandler->Free();   //free the memory
+    fNTrackData=0;
+    fTrackData=0;
+  }
+  fBenchmark->Start("Global track merger");
+  //fGlobalMerger->AddAllTracks();
+  fGlobalMerger->Merge();
+  //fGlobalMerger->SlowMerge(fWriteOutPath);
+  fBenchmark->Stop("Global track merger");
+  
+  FitGlobalTracks();
+  
+  if(fWriteOut) WriteResults(); 
+  fFileHandler->FreeDigitsTree();
+}
+
+void AliHLTTPC::ProcessSlice(Int_t slice)
+{
+  //process slice
+  char name[256];
+  Bool_t UseCF = kFALSE;
+#ifdef use_aliroot
+  UseCF = fFileHandler->IsDigit(fEvent);
+#endif
+  if(fUseBinary)
+    UseCF = kTRUE;   //In case you are not using aliroot
+  if(fNoCF == kTRUE) //In case you don't want to run with cluster finder
+    UseCF = kFALSE;
+
+  const Int_t kmaxpoints=120000;
+  const Int_t kpointsize = kmaxpoints * sizeof(AliHLTTPCSpacePointData);
+  AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
+
+  fTrackMerger->Reset();
+  fTrackMerger->SetRows(fRow[0]);
+  
+  for(Int_t patch=fNPatch-1;patch>=0;patch--){
+    fFileHandler->Init(slice,patch,&fRow[patch][0]);
+    UInt_t npoints=0;
+    AliHLTTPCSpacePointData *points =0;
+    UInt_t ndigits=0;
+    AliHLTTPCDigitRowData *digits =0;
+    if(UseCF){
+      if(fUseBinary){
+        if(!fDoRoi){ 
+          if(1){     //Binary to Memory
+           fFileHandler->Free();
+            if(fNPatch == 1)
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+           else
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+           if(!fFileHandler->SetBinaryInput(name)) return;
+           if(fPileUp)
+             { //Read binary files which are not RLE
+               digits = (AliHLTTPCDigitRowData*)fFileHandler->Allocate();
+               fFileHandler->Binary2Memory(ndigits,digits); 
+             }
+           else //Read RLE binary files
+             digits= (AliHLTTPCDigitRowData *)fFileHandler->CompBinary2Memory(ndigits);
+
+           fFileHandler->CloseBinaryInput(); 
+          }
+
+          if(0){     //Binary to Memory with Benchmark 
+           fFileHandler->Free();
+            if(fNPatch == 1)
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+           else
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+            if(!memory->SetBinaryInput(name)) return;
+            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=(AliHLTTPCDigitRowData *)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);
+            if(fNPatch == 1)
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+           else
+             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+            if(!memory->SetBinaryInput(name)) return;
+            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=(AliHLTTPCDigitRowData*)fFileHandler->Allocate(dsize+rsize);
+            fBenchmark->Start("Unpacker");
+            fFileHandler->CompMemory2Memory(ndigits,digits,comp); 
+            fBenchmark->Stop("Unpacker");
+            memory->Free();
+          }
+        }
+
+        else{     //Binary to Memory with Roi
+          fFileHandler->Free();
+          Int_t sli[2]={0,0};
+          fFileHandler->SetROI(fEta,sli);
+          if(fNPatch==1)
+           sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+         else
+           sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+          if(!memory->SetBinaryInput(name)) return;
+          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=(AliHLTTPCDigitRowData *)fFileHandler->Allocate(datasize);
+          fBenchmark->Start("Unpacker"); 
+          datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp); 
+          fBenchmark->Stop("Unpacker"); 
+          memory->Free();
+        }
+      }//end UseBinary
+      else{
+#ifdef use_aliroot
+        fBenchmark->Start("Dummy Unpacker");
+        if(fNPatch==1)
+         sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,-1);
+       else
+         sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,patch);
+        fBenchmark->Stop("Dummy Unpacker");
+
+        if(0){   //Ali to Binary
+          fFileHandler->SetBinaryOutput(name);
+          fFileHandler->AliDigits2CompBinary();
+          fFileHandler->CloseBinaryOutput();
+        }
+  
+        if(1){   //Ali to Memory
+          digits=(AliHLTTPCDigitRowData *)fFileHandler->AliAltroDigits2Memory(ndigits,fEvent);
+          if(0){ //Memory to Binary
+            fFileHandler->SetBinaryOutput(name);
+            fFileHandler->Memory2CompBinary(ndigits,digits);
+            fFileHandler->CloseBinaryOutput();
+          }
+        }
+#endif
+      }//end else UseBinary
+
+      points = (AliHLTTPCSpacePointData *) memory->Allocate(kpointsize);
+      fClusterFinder = new AliHLTTPCClustFinderNew();
+      fClusterFinder->InitSlice(slice,patch,fRow[patch][0],fRow[patch][1],kmaxpoints);
+      fClusterFinder->SetDeconv(fClusterDeconv);
+      fClusterFinder->SetXYError(fXYClusterError);
+      fClusterFinder->SetZError(fZClusterError);
+      if((fXYClusterError>0)&&(fZClusterError>0))
+       fClusterFinder->SetCalcErr(kFALSE);
+      fClusterFinder->SetOutputArray(points);
+      fBenchmark->Start("Cluster finder");
+      fClusterFinder->Read(ndigits,digits);
+      fClusterFinder->ProcessDigits();
+      fBenchmark->Stop("Cluster finder");
+      npoints = fClusterFinder->GetNumberOfClusters();
+      delete fClusterFinder;
+      fClusterFinder = 0;
+      fFileHandler->Free();
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Cluster Finder")
+        <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
+    }//end UseCF
+    else{// if not use Clusterfinder
+      if(fUseBinary){//Binary to Memory
+        memory->Free();
+        if(fNPatch==1)
+         sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+       else
+         sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+        if(!memory->SetBinaryInput(name)) return;
+        points = (AliHLTTPCSpacePointData *) memory->Allocate();
+        memory->Binary2Memory(npoints,points);
+        memory->CloseBinaryInput();
+        LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Read Cluster")
+        <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points in File"<<ENDLOG;
+      }
+#ifdef use_aliroot
+      else{
+        points = fFileHandler->AliPoints2Memory(npoints);
+      }
+#endif
+      fBenchmark->Start("Dummy Unpacker");
+      fBenchmark->Stop("Dummy Unpacker");
+      fBenchmark->Start("Dummy CF");
+      fBenchmark->Stop("Dummy CF");
+    }
+   
+    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();
+        AliHLTTPCVertexData 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,fRow[patch],fEta);
+    fTracker->SetVertex(fVertex);
+    fBenchmark->Start("Tracker setup"); 
+    fTracker->ReadHits(npoints,points);
+    fTracker->MainVertexTracking_a();
+    fBenchmark->Stop("Tracker setup");
+    fBenchmark->Start("Track follower");
+    fTracker->MainVertexTracking_b();
+    fBenchmark->Stop("Track follower");
+    if(fDoNonVertex)
+      fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
+    fBenchmark->Start("Sector track fitting");
+    fTracker->FillTracks();
+    fBenchmark->Stop("Sector track fitting");
+
+    if(fWriteOut) 
+       WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
+
+    //free memory
+    if(UseCF)
+      memory->Free();
+    else
+      fFileHandler->Free();
+
+    UInt_t ntracks0 =0;
+    AliHLTTPCTrackSegmentData *trackdata0  = 
+         (AliHLTTPCTrackSegmentData *) memory->Allocate(fTracker->GetTracks());
+    memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
+
+    //write tracks
+    if(fWriteOut){
+      if(fNPatch==1)
+       sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
+      else
+       sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
+      memory->SetBinaryOutput(name);
+      memory->Memory2Binary(ntracks0,trackdata0);
+      memory->CloseBinaryOutput();
+    }
+
+    fInterMerger->Reset();
+    fInterMerger->Init(fRow[patch],patch);
+
+    fInterMerger->FillTracks(ntracks0,trackdata0);
+    
+    //fBenchmark->Start("Inter Merger");
+    // fInterMerger->Merge();
+    //    fInterMerger->SlowMerge();
+    
+    //fBenchmark->Stop("Inter Merger");
+    /*
+    //write inter merged tracks
+    if(fWriteOut){
+      sprintf(name,"%stracks_im_%d_%d.raw",fWriteOutPath,slice,patch);
+      WriteTracks(name,fInterMerger,'i'); //write output of intermerger
+      }
+    */
+    memory->Free();
+    
+    UInt_t ntracks1 =0;
+    AliHLTTPCTrackSegmentData *trackdata1 =
+      (AliHLTTPCTrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
+    memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
+
+    fTrackMerger->InitSector(slice,patch);
+    fTrackMerger->FillTracks(ntracks1,trackdata1);
+
+    memory->Free();
+  }
+  //fBenchmark->Start("Patch Merger");
+  //fTrackMerger->SlowMerge();
+  fTrackMerger->AddAllTracks();
+  //fTrackMerger->Merge();
+  //fBenchmark->Stop("Patch Merger");
+  /*
+  //write merged tracks
+  if(fWriteOut){
+    sprintf(name,"%stracks_tm_%d.raw",fWriteOutPath,slice);
+    WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
+  }
+  */
+  fTrackData = (AliHLTTPCTrackSegmentData *) 
+                         fFileHandler->Allocate(fTrackMerger->GetOutTracks());
+
+  fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
+                                                fTrackMerger->GetOutTracks());
+
+  delete memory;
+}
+
+void AliHLTTPC::FitGlobalTracks()
+{ 
+  //fit global tracks
+  AliHLTTPCFitter *fitter = new AliHLTTPCFitter(fVertex,AliHLTTPC::DoVertexFit());
+  if(fNPatch==1)
+    fitter->LoadClusters(fWriteOutPath,fEvent,kTRUE);
+  else
+    fitter->LoadClusters(fWriteOutPath,fEvent,kFALSE);
+  
+  fBenchmark->Start("Global track fitter");
+  AliHLTTPCTrackArray *tracks = fGlobalMerger->GetOutTracks();
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliHLTTPCTrack *tr = tracks->GetCheckedTrack(i);
+      if(!tr) continue;
+      fitter->FitHelix(tr);
+      tr->UpdateToFirstPoint();
+    }
+  fBenchmark->Stop("Global track fitter");
+  delete fitter;
+}
+
+void AliHLTTPC::WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+                                Int_t slice,Int_t patch) const
+{ 
+  //write space points
+  char name[256];
+  if(fNPatch==1)
+    sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
+  else
+    sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
+  AliHLTTPCMemHandler * memory = new AliHLTTPCMemHandler();
+  memory->SetBinaryOutput(name);
+  memory->Transform(npoints,points,slice);
+  memory->Memory2Binary(npoints,points);
+  memory->CloseBinaryOutput();
+  delete  memory;
+}
+
+Int_t AliHLTTPC::WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt) const
+{ 
+  //write tracks
+  AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
+  memory->SetBinaryOutput(filename);
+  if(opt=='a'||opt=='i'){  //add intracks
+    for(Int_t i=0;i<merger->GetNIn();i++){
+      AliHLTTPCTrackArray *tr=merger->GetInTracks(i);
+      memory->TrackArray2Binary(tr);
+    }
+  }
+
+  if(opt=='o'||opt=='a'){
+    AliHLTTPCTrackArray *tr=merger->GetOutTracks();
+    memory->TrackArray2Binary(tr);
+  }
+
+  memory->CloseBinaryOutput();
+  delete memory;
+  return 1;
+}
+
+void AliHLTTPC::WriteResults()
+{
+  //Write the resulting tracks to outputfile
+  Char_t fname[256];
+  sprintf(fname,"%s/tracks_%d.raw",fWriteOutPath,fEvent);
+  WriteTracks(fname,fGlobalMerger,'a');
+  //WriteTracks("tracks.raw",fGlobalMerger,'a');
+  sprintf(fname,"%s/tracks_gl_%d.raw",fWriteOutPath,fEvent);
+  WriteTracks(fname,fGlobalMerger,'o');
+  //WriteTracks("tracks_gl.raw",fGlobalMerger,'o');
+}
diff --git a/HLT/TPCLib/AliHLTTPC.h b/HLT/TPCLib/AliHLTTPC.h
new file mode 100644 (file)
index 0000000..93cbc26
--- /dev/null
@@ -0,0 +1,134 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_H
+#define ALIHLTTPC_H
+
+#ifndef no_root
+#include <TObject.h>
+#include <TFile.h>
+#endif
+
+#ifdef use_newio
+class AliRunLoader;
+#endif
+
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCDigitData;
+class AliHLTTPCConfMapper;
+class AliHLTTPCVertex;
+class AliHLTTPCVertexFinder;
+class AliHLTTPCTrackMerger;
+class AliHLTTPCGlobalMerger;
+#ifndef no_root
+class TDirectory;
+#endif
+class AliHLTTPCClustFinderNew;
+class AliHLTTPCMerger;
+class AliHLTTPCInterMerger;
+class AliHLTTPCFileHandler;
+class AliHLTTPCMemHandler;
+class AliHLTTPCBenchmark;
+
+#ifdef no_root
+class AliHLTTPC {
+#else
+class AliHLTTPC : public TObject {
+#endif
+
+ private:
+  UInt_t fNTrackData; //count data
+  AliHLTTPCTrackSegmentData* fTrackData; //!
+  AliHLTTPCConfMapper *fTracker; //!
+  AliHLTTPCVertex *fVertex; //! 
+  AliHLTTPCVertexFinder *fVertexFinder; //!
+  AliHLTTPCTrackMerger *fTrackMerger; //!
+  AliHLTTPCGlobalMerger *fGlobalMerger; //!
+  AliHLTTPCInterMerger *fInterMerger; //!
+  AliHLTTPCClustFinderNew *fClusterFinder; //! 
+  AliHLTTPCMemHandler *fFileHandler; //!
+  AliHLTTPCBenchmark *fBenchmark;//!
+
+  Int_t fEvent;    //event number
+  Int_t fNPatch;   //number of patches
+  Int_t fRow[6][2];//rows
+  Float_t fEta[2]; //eta
+  
+  Char_t *fInputFile;//!
+#ifdef use_newio
+  AliRunLoader *fRunLoader; //runloader
+#endif
+  Char_t fPath[256]; //path to aliroot
+  Char_t fWriteOutPath[256]; //path to store
+  
+  Bool_t fDoRoi; //do region of interest
+  Bool_t fFindVertex; //find vertex
+  Bool_t fDoNonVertex;//do non vertex pass
+  Bool_t fPileUp; //do pileup
+  Bool_t fNoCF; //dont do cluster finder
+  
+  Bool_t fUseBinary; //use binary input
+  Bool_t fWriteOut; //write tracks
+  
+  static Bool_t fgDoVertexFit; //do vertex fix
+
+  Bool_t fClusterDeconv; //do cluster deconv
+  Float_t fXYClusterError; //Cluster error
+  Float_t fZClusterError; //Cluster error
+
+  void WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+                        Int_t slice,Int_t patch) const;
+  Int_t WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt='o') const;  
+  void WriteResults();
+  void FitGlobalTracks();
+  void SetPath(char *p){sprintf(fPath,"%s",p);}
+
+ public:
+  AliHLTTPC ();
+  AliHLTTPC(Char_t *infile);
+#ifdef use_newio
+  AliHLTTPC(AliRunLoader *rl);
+#endif
+  virtual ~AliHLTTPC();
+  enum EFileType {kBinary, kBinary8, kRoot, kRaw, kDate, kRunLoader};
+  void Init(Char_t *path,EFileType filetype=kBinary,Int_t npatches=6);
+  void SetMergerParameters(Double_t maxy=1.2,Double_t maxz=1.6,Double_t maxkappa=0.003,
+                          Double_t maxpsi=0.02,Double_t maxtgl=0.03);
+  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,Double_t maxphi=0.1,Double_t maxeta=0.1,
+                       Bool_t vertexconstraint=kTRUE);
+  void SetClusterFinderParam(Float_t fXYError=0.2,Float_t fZError=0.3,Bool_t deconv=kTRUE);
+
+  void ProcessEvent(Int_t first,Int_t last,Int_t event=0);
+  void ProcessSlice(Int_t slice);
+
+  void DoMc(char* file="point_mc.dat");
+  void DoNonVertexTracking() {fDoNonVertex=kTRUE;}
+  void FindVertex() {fFindVertex=kTRUE;}
+  void DoBench(char* name="benchmark");
+  void DoPileup() {fPileUp = kTRUE;}
+  void NoCF() {fNoCF=kTRUE;}
+  void DoRoi(Float_t e0=0.4,Float_t e1=0.5){fEta[0]=e0;fEta[1]=e1;fDoRoi=kTRUE;}
+  void WriteFiles(Char_t *path="./"){fWriteOut = kTRUE; sprintf(fWriteOutPath,"%s",path);}
+  
+  static void SetVertexFit(Bool_t f)   {fgDoVertexFit=f;}
+  static Bool_t DoVertexFit()          {return fgDoVertexFit;}
+
+  ClassDef(AliHLTTPC,1) //Interface class for HLTTPC-tracking
+};
+
+#endif
+
+
+
+
+
diff --git a/HLT/TPCLib/AliHLTTPCBenchmark.cxx b/HLT/TPCLib/AliHLTTPCBenchmark.cxx
new file mode 100644 (file)
index 0000000..a83e70c
--- /dev/null
@@ -0,0 +1,195 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+/** \class AliHLTTPCBenchmark
+</pre>
+//_____________________________________________________________
+//
+// AliHLTTPCBenchmark
+//
+//   Benchmark class for level3 code
+//  
+//
+</pre>
+*/
+
+#ifndef no_root
+#include <TFile.h>
+#include <TGraphAsymmErrors.h>
+#include <TString.h>
+#include <TStopwatch.h>
+#include <TMath.h>
+#endif
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCBenchmark.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCBenchmark)
+
+AliHLTTPCBenchmark::AliHLTTPCBenchmark()
+{
+  //Constructor
+  fNbench = 0;
+  fNmax   = 20;
+  fNames  = 0;
+  fTimer  = 0;
+  fSum    = 0;
+  fMin    = 0;
+  fMax    = 0;
+  fCount  = 0;
+}
+
+AliHLTTPCBenchmark::~AliHLTTPCBenchmark()
+{
+  //deconstructor
+   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;}
+}
+
+Int_t AliHLTTPCBenchmark::GetBench(const Char_t *name)
+{
+  //get bench with name
+   for (Int_t i=0;i<fNbench;i++) {
+      if (!strcmp(name,(const Char_t*)fNames[i])) return i;
+   }
+   return -1;
+}
+
+
+void AliHLTTPCBenchmark::Start(const Char_t *name)
+{
+  //start the benchmark with name
+   if (!fNbench) {
+#ifdef no_root
+     fNames=new Char_t*[fNmax];
+     fTimer = new AliHLTTPCStopwatch[fNmax];
+#else
+     fNames = new TString[fNmax];
+     fTimer = new TStopwatch[fNmax];
+#endif
+
+     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
+#ifdef no_root
+     fNames[fNbench]=new Char_t[strlen(name)+1];
+     strcpy(fNames[fNbench],name);
+#else
+      fNames[fNbench] = name;
+#endif
+      bench = fNbench;
+      fNbench++;
+      fTimer[bench].Reset();
+      fTimer[bench].Start();
+   } else if (bench >=0) {
+   // Resume the existent benchmark
+      fTimer[bench].Reset();
+      fTimer[bench].Start();
+   }
+   else
+     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCBenchmark::Start","Start")
+     <<"too many benches"<<ENDLOG;
+}
+
+void AliHLTTPCBenchmark::Stop(const char *name)
+{
+  //stop the benchmark with name
+   Int_t bench = GetBench(name);
+   if (bench < 0) return;
+
+   fTimer[bench].Stop();
+   Float_t val = fTimer[bench].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 AliHLTTPCBenchmark::Analyze(const Char_t* name)
+{
+  //get results of benchmark
+  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_t 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;
+#ifdef no_root
+    fprintf(f,"%2d. %s: ",i+1,fNames[i]);
+#else
+    fprintf(f,"%2d. %s: ",i+1,fNames[i].Data());
+#endif
+    fprintf(f,"total %4.0f patch %4.0f -%4.0f +%4.0f ms\n",fSum[i],av*1000,eyl[i],eyh[i]);
+  }
+  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);
+*/
+#ifndef no_root
+  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;
+#endif
+  delete[] x;
+  delete[] y;
+  delete[] eyl;
+  delete[] eyh;
+}
+
+Double_t AliHLTTPCBenchmark::GetCpuTime()
+{
+  //get cpu time
+  {return (Double_t)(clock()) / CLOCKS_PER_SEC;}
+}
diff --git a/HLT/TPCLib/AliHLTTPCBenchmark.h b/HLT/TPCLib/AliHLTTPCBenchmark.h
new file mode 100644 (file)
index 0000000..8101d53
--- /dev/null
@@ -0,0 +1,52 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPCBenchmarkH
+#define AliHLTTPCBenchmarkH
+
+//_____________________________________________________________
+//
+// AliHLTTPCBenchmark
+//
+//   Benchmark class for level3 code
+//  
+//
+
+#ifndef no_root
+class TStopwatch;
+class TString;
+#else
+class  AliHLTTPCStopwatch;
+#endif
+
+class AliHLTTPCBenchmark {
+
+public:
+   AliHLTTPCBenchmark();
+   virtual ~AliHLTTPCBenchmark();
+   Int_t      GetBench(const char *name);
+   void       Start(const char *name);
+   void       Stop(const char *name);
+   void       Analyze(const char* name);
+   
+   static Double_t GetCpuTime();
+
+private:
+
+   Int_t      fNbench;          //Number of active benchmarks
+   Int_t      fNmax;            //Maximum number of benchmarks initialized
+#ifndef no_root
+   TString    *fNames;          //Names of benchmarks
+   TStopwatch *fTimer;          //Timers
+#else
+   Char_t **fNames;             //Names of benchmarks
+   AliHLTTPCStopwatch *fTimer;      //Timers
+#endif
+   Float_t    *fSum;  //sum of time
+   Float_t    *fMin;  //min of time
+   Float_t    *fMax;  //max of time
+   Int_t      *fCount;// counter
+
+   ClassDef(AliHLTTPCBenchmark,0)  //HLTTPC benchmark
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCClustFinderNew.cxx b/HLT/TPCLib/AliHLTTPCClustFinderNew.cxx
new file mode 100644 (file)
index 0000000..eb78ea6
--- /dev/null
@@ -0,0 +1,505 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+/** \class AliHLTTPCClustFinderNew
+<pre>
+//_____________________________________________________________
+// AliHLTTPCClustFinderNew
+//
+// The current cluster finder for HLT
+// (Based on STAR L3)
+// 
+// The cluster finder is initialized with the Init function, 
+// providing the slice and patch information to work on. 
+// The input is a AliHLTTPCDigitRowData structure using the 
+// Read function. The resulting space points will be in the
+// array given by the SetOutputArray function.
+// 
+// There are several setters which control the behaviour:
+//
+// - SetXYError(Float_t):   set fixed error in XY direction
+// - SetZError(Float_t):    set fixed error in Z  direction
+//                            (used if errors are not calculated) 
+// - SetDeconv(Bool_t):     switch on/off deconvolution
+// - SetThreshold(UInt_t):  set charge threshold for cluster
+// - SetMatchWidth(UInt_t): set the match distance in 
+//                            time for sequences to be merged 
+// - SetSTDOutput(Bool_t):  switch on/off output about found clusters   
+// - SetCalcErr(Bool_t):    switch on/off calculation of 
+//                          space point errors (or widths in raw system)
+// - SetRawSP(Bool_t):      switch on/off convertion to raw system
+//
+//
+// Example Usage:
+//
+// AliHLTTPCFileHandler *file = new AliHLTTPCFileHandler();
+// file->SetAliInput(digitfile); //give some input file
+// for(int slice=0; slice<=35; slice++){
+//   for(int patch=0; pat<6; pat++){
+//     file->Init(slice,patch);
+//     UInt_t ndigits=0;
+//     UInt_t maxclusters=100000;
+//     UInt_t pointsize = maxclusters*sizeof(AliHLTTPCSpacePointData);
+//     AliHLTTPCSpacePointData *points = (AliHLTTPCSpacePointData*)memory->Allocate(pointsize);
+//     AliHLTTPCDigitRowData *digits = (AliHLTTPCDigitRowData*)file->AliAltroDigits2Memory(ndigits,event);
+//     AliHLTTPCClustFinderNew *cf = new AliHLTTPCClustFinderNew();
+//     cf->SetMatchWidth(2);
+//     cf->InitSlice(slice,patch,maxclusters);
+//     cf->SetSTDOutput(kTRUE);    //Some output to standard IO
+//     cf->SetRawSP(kFALSE);       //Convert space points to local system
+//     cf->SetThreshold(5);        //Threshold of cluster charge
+//     cf->SetDeconv(kTRUE);       //Deconv in pad and time direction
+//     cf->SetCalcErr(kTRUE);      //Calculate the errors of the spacepoints
+//     cf->SetOutputArray(points); //Move the spacepoints to the array
+//     cf->Read(ndigits,digits);   //give the data to the cf
+//     cf->ProcessDigits();        //process the rows given by init
+//     Int_t npoints = cf->GetNumberOfClusters();
+//     AliHLTTPCMemHandler *out= new AliHLTTPCMemHandler();
+//     out->SetBinaryOutput(fname);
+//     out->Memory2Binary(npoints,points); //store the spacepoints
+//     out->CloseBinaryOutput();
+//     delete out;
+//     file->free();
+//     delete cf;
+//   }
+// }
+</pre> 
+*/
+
+ClassImp(AliHLTTPCClustFinderNew)
+
+AliHLTTPCClustFinderNew::AliHLTTPCClustFinderNew()
+{
+  //constructor
+  fMatch = 1;
+  fThreshold = 10;
+  fXYErr = 0.2;
+  fZErr = 0.3;
+  fDeconvPad = kTRUE;
+  fDeconvTime = kTRUE;
+  fStdout = kFALSE;
+  fCalcerr = kTRUE;
+  fRawSP = kFALSE;
+  fFirstRow=0;
+  fLastRow=0;
+}
+
+AliHLTTPCClustFinderNew::~AliHLTTPCClustFinderNew()
+{
+  //destructor
+  ;
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
+{
+  //init slice
+  fNClusters = 0;
+  fMaxNClusters = nmaxpoints;
+  fCurrentSlice = slice;
+  fCurrentPatch = patch;
+  fFirstRow = firstrow;
+  fLastRow = lastrow;
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
+{
+  //init slice
+  fNClusters = 0;
+  fMaxNClusters = nmaxpoints;
+  fCurrentSlice = slice;
+  fCurrentPatch = patch;
+  fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
+  fLastRow=AliHLTTPCTransform::GetLastRow(patch);
+}
+
+void AliHLTTPCClustFinderNew::SetOutputArray(AliHLTTPCSpacePointData *pt)
+{
+  //set pointer to output
+  fSpacePointData = pt;
+}
+
+void AliHLTTPCClustFinderNew::Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr)
+{
+  //set input pointer
+  fNDigitRowData = ndigits;
+  fDigitRowData = ptr;
+}
+
+void AliHLTTPCClustFinderNew::ProcessDigits()
+{
+  //Loop over rows, and call processrow
+  AliHLTTPCDigitRowData *tempPt = (AliHLTTPCDigitRowData*)fDigitRowData;
+  fNClusters = 0; 
+  for(Int_t i=fFirstRow; i<=fLastRow; i++)
+    {
+      fCurrentRow = i;
+      if((Int_t)tempPt->fRow!=fCurrentRow){
+       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCClustFinderNew::ProcessDigits","Digits")
+         <<"Row number should match! "<<tempPt->fRow<<" "<<fCurrentRow<<ENDLOG;
+       continue;
+      }
+      ProcessRow(tempPt);
+      Byte_t *tmp = (Byte_t*)tempPt;
+      Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+      tmp += size;
+      tempPt = (AliHLTTPCDigitRowData*)tmp;
+    }
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCClustFinderNew::ProcessDigits","Space points")
+    <<"Cluster finder found "<<fNClusters<<" clusters in slice "<<fCurrentSlice
+    <<" patch "<<fCurrentPatch<<ENDLOG;
+}
+
+void AliHLTTPCClustFinderNew::ProcessRow(AliHLTTPCDigitRowData *tempPt)
+{
+  //process row
+  UInt_t lastpad = 123456789;
+
+  AliClusterData *pad1[5000]; //2 lists for internal memory=2pads
+  AliClusterData *pad2[5000]; //2 lists for internal memory=2pads
+  AliClusterData clusterlist[10000]; //Clusterlist
+
+  AliClusterData **currentPt;  //List of pointers to the current pad
+  AliClusterData **previousPt; //List of pointers to the previous pad
+  currentPt = pad2;
+  previousPt = pad1;
+  UInt_t nprevious=0,ncurrent=0,ntotal=0;
+
+  //Loop over sequences of this row:
+  for(UInt_t bin=0; bin<tempPt->fNDigit; bin++)
+    {
+      AliHLTTPCDigitData *data = tempPt->fDigitData;
+      if(data[bin].fPad != lastpad)
+       {
+         //This is a new pad
+         
+         //Switch the lists:
+         if(currentPt == pad2)
+           {
+             currentPt = pad1;
+             previousPt = pad2;
+           }
+         else 
+           {
+             currentPt = pad2;
+             previousPt = pad1;
+           }
+         nprevious = ncurrent;
+         ncurrent = 0;
+         if(bin[data].fPad != lastpad+1)
+           {
+             //this happens if there is a pad with no signal.
+             nprevious = ncurrent = 0;
+           }
+         lastpad = data[bin].fPad;
+       }
+
+      Bool_t newcluster = kTRUE;
+      UInt_t seqcharge=0,seqaverage=0,seqerror=0;
+      UInt_t lastcharge=0,lastwas_falling=0;
+      Int_t newbin=-1;
+
+      if(fDeconvTime)
+       {
+       redo: //This is a goto.
+         if(newbin > -1)
+           {
+             bin = newbin;
+             newbin = -1;
+           }
+         
+         lastcharge=0;
+         lastwas_falling = 0;
+       }
+      
+      while(1) //Loop over current sequence
+       {
+         if(data[bin].fTime >= AliHLTTPCTransform::GetNTimeBins())
+           {
+             LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Digits")
+               <<"Timebin out of range "<<(Int_t)data[bin].fTime<<ENDLOG;
+             break;
+           }
+
+         //Get the current ADC-value
+         UInt_t charge = data[bin].fCharge;
+         
+         if(fDeconvTime)
+           {
+             //Check if the last pixel in the sequence is smaller than this
+             if(charge > lastcharge)
+               {
+                 if(lastwas_falling)
+                   {
+                     newbin = bin;
+                     break;
+                   }
+               }
+             else lastwas_falling = 1; //last pixel was larger than this
+             lastcharge = charge;
+           }
+         
+         //Sum the total charge of this sequence
+         seqcharge += charge;
+         seqaverage += data[bin].fTime*charge;
+         seqerror += data[bin].fTime*data[bin].fTime*charge;
+
+         //Check where to stop:
+         if(bin >= tempPt->fNDigit - 1) //out of range
+           break;
+         if(data[bin+1].fPad != data[bin].fPad) //new pad
+           break;
+         if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence
+           break;
+         
+         bin++;
+       }//end loop over sequence
+      
+      //Calculate mean of sequence:
+      Int_t seqmean=0;
+      if(seqcharge)
+       seqmean = seqaverage/seqcharge;
+      else
+       {
+         LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Data")
+           <<"Error in data given to the cluster finder"<<ENDLOG;
+         seqmean = 1;
+         seqcharge = 1;
+       }
+      
+      //Calculate mean in pad direction:
+      Int_t padmean = seqcharge*data[bin].fPad;
+      Int_t paderror = data[bin].fPad*padmean;
+
+      //Compare with results on previous pad:
+      for(UInt_t p=0; p<nprevious; p++)
+       {
+         //dont merge sequences on the same pad twice
+         if(previousPt[p]->fLastMergedPad==data[bin].fPad) continue;
+
+         Int_t difference = seqmean - previousPt[p]->fMean;
+         if(difference < -fMatch) break;
+
+         if(difference <= fMatch) //There is a match here!!
+           {
+             AliClusterData *local = previousPt[p];
+
+             if(fDeconvPad)
+               {
+                 if(seqcharge > local->fLastCharge)
+                   {
+                     if(local->fChargeFalling) //The previous pad was falling
+                       {                       
+                         break; //create a new cluster
+                       }                   
+                   }
+                 else
+                   local->fChargeFalling = 1;
+                 local->fLastCharge = seqcharge;
+               }
+             
+             //Don't create a new cluster, because we found a match
+             newcluster = kFALSE;
+             
+             //Update cluster on current pad with the matching one:
+             local->fTotalCharge += seqcharge;
+             local->fPad += padmean;
+             local->fPad2 += paderror;
+             local->fTime += seqaverage;
+             local->fTime2 += seqerror;
+             local->fMean = seqmean;
+             local->fFlags++; //means we have more than one pad 
+             local->fLastMergedPad = data[bin].fPad;
+
+             currentPt[ncurrent] = local;
+             ncurrent++;
+             
+             break;
+           } //Checking for match at previous pad
+       } //Loop over results on previous pad.
+      
+      if(newcluster)
+       {
+         //Start a new cluster. Add it to the clusterlist, and update
+         //the list of pointers to clusters in current pad.
+         //current pad will be previous pad on next pad.
+
+         //Add to the clusterlist:
+         AliClusterData *tmp = &clusterlist[ntotal];
+         tmp->fTotalCharge = seqcharge;
+         tmp->fPad = padmean;
+         tmp->fPad2 = paderror;
+         tmp->fTime = seqaverage;
+         tmp->fTime2 = seqerror;
+         tmp->fMean = seqmean;
+         tmp->fFlags = 0;  //flags for single pad clusters
+         tmp->fLastMergedPad = data[bin].fPad;
+
+         if(fDeconvPad)
+           {
+             tmp->fChargeFalling = 0;
+             tmp->fLastCharge = seqcharge;
+           }
+
+         //Update list of pointers to previous pad:
+         currentPt[ncurrent] = &clusterlist[ntotal];
+         ntotal++;
+         ncurrent++;
+       }
+
+      if(fDeconvTime)
+       if(newbin >= 0) goto redo;
+    }//Loop over digits on this padrow
+  
+  WriteClusters(ntotal,clusterlist);
+}
+
+void AliHLTTPCClustFinderNew::WriteClusters(Int_t nclusters,AliClusterData *list)
+{
+  //write cluster to output pointer
+  Int_t thisrow,thissector;
+  UInt_t counter = fNClusters;
+  
+  for(int j=0; j<nclusters; j++)
+    {
+      if(!list[j].fFlags) continue; //discard single pad clusters
+      if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
+
+      Float_t xyz[3];      
+      Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
+      Float_t fpad2=fXYErr*fXYErr; //fixed given error
+      Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
+      Float_t ftime2=fZErr*fZErr;  //fixed given error
+
+      if(fCalcerr) { //calc the errors, otherwice take the fixed error 
+       Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
+       UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
+       Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
+       sy2/=q2;
+       if(sy2 < 0) {
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
+             <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
+           continue;
+       } else {
+         if(!fRawSP){
+           fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
+           if(sy2 != 0){
+             fpad2*=0.108; //constants are from offline studies
+             if(patch<2)
+               fpad2*=2.07;
+           }
+         } else fpad2=sy2; //take the width not the error
+       }
+       Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
+       sz2/=q2;
+       if(sz2 < 0){
+         LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
+           <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
+         continue;
+       } else {
+         if(!fRawSP){
+           ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
+           if(sz2 != 0) {
+             ftime2 *= 0.169; //constants are from offline studies
+             if(patch<2)
+               ftime2 *= 1.77;
+           }
+         } else ftime2=sz2; //take the width, not the error
+       }
+      }
+      if(fStdout==kTRUE)
+       cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
+      
+      if(!fRawSP){
+       AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
+       AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
+       
+       if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
+         <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
+       if(fNClusters >= fMaxNClusters)
+         {
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
+             <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
+           return;
+         }  
+       
+       fSpacePointData[counter].fX = xyz[0];
+       fSpacePointData[counter].fY = xyz[1];
+       fSpacePointData[counter].fZ = xyz[2];
+       
+      } else {
+       fSpacePointData[counter].fX = fCurrentRow;
+       fSpacePointData[counter].fY = fpad;
+       fSpacePointData[counter].fZ = ftime;
+      }
+      
+      fSpacePointData[counter].fCharge = list[j].fTotalCharge;
+      fSpacePointData[counter].fPadRow = fCurrentRow;
+      fSpacePointData[counter].fSigmaY2 = fpad2;
+      fSpacePointData[counter].fSigmaZ2  = ftime2;
+
+      Int_t patch=fCurrentPatch;
+      if(patch==-1) patch=0; //never store negative patch number
+      fSpacePointData[counter].fID = counter
+       +((fCurrentSlice&0x7f)<<25)+((patch&0x7)<<22);//Uli
+#ifdef do_mc
+      Int_t trackID[3];
+      GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
+
+      fSpacePointData[counter].fTrackID[0] = trackID[0];
+      fSpacePointData[counter].fTrackID[1] = trackID[1];
+      fSpacePointData[counter].fTrackID[2] = trackID[2];
+
+      //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
+#endif
+      
+      fNClusters++;
+      counter++;
+    }
+}
+
+#ifdef do_mc
+void AliHLTTPCClustFinderNew::GetTrackID(Int_t pad,Int_t time,Int_t *trackID)
+{
+  //get mc id
+  AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
+  
+  trackID[0]=trackID[1]=trackID[2]=-2;
+  //cout<<"Looking for pad "<<pad<<" time "<<time<<endl;
+  for(Int_t i=fFirstRow; i<=fLastRow; i++){
+    if(rowPt->fRow < (UInt_t)fCurrentRow){
+      AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
+      continue;
+    }
+    AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
+    for(UInt_t j=0; j<rowPt->fNDigit; j++){
+      Int_t cpad = digPt[j].fPad;
+      Int_t ctime = digPt[j].fTime;
+      if(cpad != pad) continue;
+      if(ctime != time) continue;
+
+      trackID[0] = digPt[j].fTrackID[0];
+      trackID[1] = digPt[j].fTrackID[1];
+      trackID[2] = digPt[j].fTrackID[2];
+      
+      //cout<<"Reading row "<<fCurrentRow<<" pad "<<cpad<<" time "<<ctime<<" trackID "<<digPt[j].fTrackID[0]<<endl;
+      break;
+    }
+    break;
+  }
+}
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCClustFinderNew.h b/HLT/TPCLib/AliHLTTPCClustFinderNew.h
new file mode 100644 (file)
index 0000000..560a7d9
--- /dev/null
@@ -0,0 +1,79 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_ClustFinderNew
+#define AliHLTTPC_ClustFinderNew
+
+class AliHLTTPCDigitRowData;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCClustFinderNew {
+
+ public:
+  struct AliClusterData
+  {
+    UInt_t fTotalCharge;   //tot charge of cluster
+    UInt_t fPad;           //pad value
+    UInt_t fTime;          //time value
+    ULong64_t fPad2;       //for error in XY direction
+    ULong64_t fTime2;      //for error in Z  direction
+    UInt_t fMean;          //mean in time
+    UInt_t fFlags;         //different flags
+    UInt_t fChargeFalling; //for deconvolution
+    UInt_t fLastCharge;    //for deconvolution
+    UInt_t fLastMergedPad; //dont merge twice per pad
+  };
+  typedef struct AliClusterData AliClusterData; //!
+
+ private:
+  AliHLTTPCDigitRowData *fDigitRowData; //!
+  AliHLTTPCSpacePointData *fSpacePointData; //!
+  Bool_t fDeconvTime; //deconv in time direction
+  Bool_t fDeconvPad;  //deconv in pad direction
+  Bool_t fStdout;     //have print out in write clusters
+  Bool_t fCalcerr;    //calculate centroid sigmas
+  Bool_t fRawSP;      //store centroids in raw system
+
+  UInt_t fNDigitRowData; //ndigts on row
+  Int_t fFirstRow;       //first row
+  Int_t fLastRow;        //last row
+  Int_t fCurrentRow;     //current active row
+  Int_t fCurrentSlice;   //current slice
+  Int_t fCurrentPatch;   //current patch
+  Int_t fMatch;          //size of match
+  UInt_t fThreshold;     //threshold for clusters
+  Int_t fNClusters;      //number of found clusters
+  Int_t fMaxNClusters;   //max. number of clusters
+  Float_t fXYErr;        //fixed error in XY
+  Float_t fZErr;         //fixed error in Z
+
+#ifdef do_mc
+  void GetTrackID(Int_t pad,Int_t time,Int_t *trackID);
+#endif
+  
+ public:
+  AliHLTTPCClustFinderNew();
+  virtual ~AliHLTTPCClustFinderNew();
+  
+  void Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr);
+  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 ProcessDigits();
+  void ProcessRow(AliHLTTPCDigitRowData *tempPt);
+  void SetOutputArray(AliHLTTPCSpacePointData *pt);
+  void WriteClusters(Int_t n_clusters,AliClusterData *list);
+
+  void SetXYError(Float_t f) {fXYErr=f;}
+  void SetZError(Float_t f) {fZErr=f;}
+  void SetDeconv(Bool_t f) {fDeconvPad=f; fDeconvTime=f;}
+  void SetThreshold(UInt_t i) {fThreshold=i;}
+  void SetMatchWidth(UInt_t i) {fMatch=i;}
+  void SetSTDOutput(Bool_t f=kFALSE) {fStdout=f;}  
+  void SetCalcErr(Bool_t f=kTRUE) {fCalcerr=f;}
+  void SetRawSP(Bool_t f=kFALSE) {fRawSP=f;}
+  Int_t GetNumberOfClusters() const {return fNClusters;}
+  
+  ClassDef(AliHLTTPCClustFinderNew,1) //Fast cluster finder
+};
+#endif
+
+
index 1a4ccc6..0dbc384 100644 (file)
@@ -10,7 +10,7 @@
 struct AliHLTTPCClusterData
     {
        AliHLTUInt32_t fSpacePointCnt;
-       AliL3SpacePointData fSpacePoints[];
+       AliHLTTPCSpacePointData fSpacePoints[];
     };
 
 #endif // _ALIHLTTPCCLUSTERFORMAT_H_
index ed9e08d..b19cd6b 100644 (file)
@@ -27,11 +27,11 @@ using namespace std;
 #endif
 
 #include "AliHLTTPCClusterFinderComponent.h"
-#include "AliL3ClustFinderNew.h"
-#include "AliL3SpacePointData.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCSpacePointData.h"
 #include "AliHLTTPCRawDataFormat.h"
 #include "AliHLTTPCClusterDataFormat.h"
-#include "AliL3Transform.h"
+#include "AliHLTTPCTransform.h"
 #include <stdlib.h>
 #include <errno.h>
 
@@ -87,14 +87,14 @@ int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
     {
     if ( fClusterFinder )
        return EINPROGRESS;
-    fClusterFinder = new AliL3ClustFinderNew();
+    fClusterFinder = new AliHLTTPCClustFinderNew();
     fClusterDeconv = true;
     fXYClusterError = -1;
     fZClusterError = -1;
     int i = 0;
     while ( i < argc )
        {
-       if ( !strcmp( argv[i], "-pp-run" ) )
+       if ( !strcmp( argv[i], "pp-run" ) )
            {
            fClusterDeconv = false;
            i++;
@@ -135,13 +135,19 @@ int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponent_EventData& e
        iter = blocks+ndx;
        mysize = 0;
        offset = tSize;
+       char tmp1[14], tmp2[14];
+       DataType2Text( iter->fDataType, tmp1 );
+       DataType2Text( AliHLTTPCDefinitions::gkUnpackedRawDataType, tmp2 );
+       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Event received", 
+                "Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
+                evtData.fEventID, evtData.fEventID, tmp1, tmp2 );
        if ( iter->fDataType != AliHLTTPCDefinitions::gkUnpackedRawDataType )
            continue;
        
        slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
        patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
-       row[0] = AliL3Transform::GetFirstRow( patch );
-       row[1] = AliL3Transform::GetLastRow( patch );
+       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
+       row[1] = AliHLTTPCTransform::GetLastRow( patch );
        
        Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints", 
                 "Input: Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
@@ -150,7 +156,7 @@ int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponent_EventData& e
        outPtr = (AliHLTTPCClusterData*)outBPtr;
        
        inPtr = (AliHLTTPCUnpackedRawData*)iter->fPtr;
-       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliL3SpacePointData);
+       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
        
        fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
        fClusterFinder->SetDeconv( fClusterDeconv );
@@ -167,7 +173,7 @@ int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponent_EventData& e
                 "Number of spacepoints found: %lu.", realPoints );
        
        outPtr->fSpacePointCnt = realPoints;
-       nSize = sizeof(AliL3SpacePointData)*realPoints;
+       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
        mysize += nSize+sizeof(AliHLTTPCClusterData);
        
        Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints", 
index f7b7ab1..fd41c02 100644 (file)
@@ -12,7 +12,7 @@
 #include "AliHLTProcessor.h"
 #include "AliHLTTPCDefinitions.h"
 
-class AliL3ClustFinderNew;
+class AliHLTTPCClustFinderNew;
 
 class AliHLTTPCClusterFinderComponent : public AliHLTProcessor
     {
@@ -43,7 +43,7 @@ class AliHLTTPCClusterFinderComponent : public AliHLTProcessor
        
     private:
 
-       AliL3ClustFinderNew* fClusterFinder;
+       AliHLTTPCClustFinderNew* fClusterFinder;
 
        bool fClusterDeconv;
        float fXYClusterError;
diff --git a/HLT/TPCLib/AliHLTTPCConfMapFit.cxx b/HLT/TPCLib/AliHLTTPCConfMapFit.cxx
new file mode 100644 (file)
index 0000000..60d945b
--- /dev/null
@@ -0,0 +1,506 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCConfMapFit.h"
+
+/** \class AliHLTTPCConfMapFit
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapFit
+//
+// Fit class for conformal mapping tracking
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapFit)
+
+
+AliHLTTPCConfMapFit::AliHLTTPCConfMapFit(AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex)
+{
+  //constructor
+  fTrack = track;
+  fVertex = vertex;
+}
+
+Int_t AliHLTTPCConfMapFit::FitHelix()
+{
+  //fit the helix
+  if(FitCircle())
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+       "Problems during circle fit"<<ENDLOG;
+      return 1;
+    }
+  if(FitLine())
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+       "Problems during line fit"<<ENDLOG;
+      return 1;
+    }
+  return 0;
+}
+
+Int_t AliHLTTPCConfMapFit::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++;
+      AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+      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(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::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())
+    { 
+      //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint *)hits->At(hit_counter);
+      AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+      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())  
+    { 
+      //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);  
+      AliHLTTPCConfMapPoint* cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+
+      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(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::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
+//
+  Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
+
+  fTrack->SetCharge(q);
+  
+  
+  //Set the first point on the track to the space point coordinates of the innermost track
+  //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
+  Double_t x0,y0,psi,pt ;
+  AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fTrack->GetLastHit();
+  x0 = lHit->GetX();
+  y0 = lHit->GetY();
+  fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
+
+  psi  = (Double_t)atan2(bcent-y0,acent-x0) ;
+  psi  = psi + q * AliHLTTPCTransform::PiHalf();
+  if ( psi < 0 ) psi = psi + AliHLTTPCTransform::TwoPi();
+  pt   = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * radius ) ;
+  
+  //Update the track parameters with the parameters from this fit:
+  fTrack->SetPsi(psi);
+  fTrack->SetPt(pt);
+  fTrack->SetRadius(radius);
+  fTrack->SetCenterX(acent);
+  fTrack->SetCenterY(bcent);
+
+  //
+//    Get errors from fast fit
+//
+  //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+  return 0 ;
+  
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//    Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliHLTTPCConfMapFit::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() / AliHLTTPCTransform::GetBFieldValue() ) ;
+
+  //TObjArray *hits = fTrack->GetHits();
+  //Int_t num_of_hits = fTrack->GetNumberOfPoints();
+
+  if (0)// fTrack->ComesFromMainVertex() == true ) 
+    {
+      dx = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetX() - fVertex->GetX();
+      dy = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetY() - fVertex->GetY() ;
+    }
+  else 
+    {
+      dx = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetX() ;
+      dy = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetY() ;
+      //dx = ((AliHLTTPCConfMapPoint *)hits->First())->GetX() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetX() ;
+      //dy = ((AliHLTTPCConfMapPoint *)hits->First())->GetY() - ((AliHLTTPCConfMapPoint *)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 * AliHLTTPCTransform::Pi() ;
+    } 
+  
+  AliHLTTPCConfMapPoint *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())  
+    {
+      // AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+      AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+      // if ( GetCurrentHit() != GetFirstHit() ) 
+      if(cHit != fTrack->GetFirstHit())//  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())  
+    {
+      //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+      AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+      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/TPCLib/AliHLTTPCConfMapFit.h b/HLT/TPCLib/AliHLTTPCConfMapFit.h
new file mode 100644 (file)
index 0000000..0fc0b5c
--- /dev/null
@@ -0,0 +1,26 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapFit
+#define ALIHLTTPC_ConfMapFit
+
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapFit {
+
+ private:
+  AliHLTTPCConfMapTrack *fTrack; //!
+  AliHLTTPCVertex *fVertex; //!
+  
+ public:
+  AliHLTTPCConfMapFit (AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex);
+  virtual ~AliHLTTPCConfMapFit() {};
+
+  Int_t FitHelix();
+  Int_t FitCircle();
+  Int_t FitLine();
+
+  ClassDef(AliHLTTPCConfMapFit,1) //Conformal mapping fit class
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCConfMapPoint.cxx b/HLT/TPCLib/AliHLTTPCConfMapPoint.cxx
new file mode 100644 (file)
index 0000000..83637d0
--- /dev/null
@@ -0,0 +1,245 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+
+/**
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapPoint
+//
+// Hit class for conformal mapper
+</pre
+*/
+
+ClassImp(AliHLTTPCConfMapPoint)
+
+Bool_t AliHLTTPCConfMapPoint::fgDontMap=kFALSE;
+
+AliHLTTPCConfMapPoint::AliHLTTPCConfMapPoint()
+{
+  //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);
+}
+
+AliHLTTPCConfMapPoint::~AliHLTTPCConfMapPoint()
+{
+  // Destructor.
+  ;
+}
+
+Bool_t AliHLTTPCConfMapPoint::ReadHits(AliHLTTPCSpacePointData* hits )
+{
+  //read the 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->fSigmaY2));
+  SetYerr(sqrt(hits->fSigmaY2));
+  SetZerr(sqrt(hits->fSigmaZ2));
+  return kTRUE;
+}
+
+void AliHLTTPCConfMapPoint::Reset()
+{
+  //Reset this point.
+  SetUsage(kFALSE);
+  SetS(0);
+  fNextRowHit = 0;
+  fNextVolumeHit=0;
+  fNextTrackHit=0;
+}
+
+void AliHLTTPCConfMapPoint::Setup(AliHLTTPCVertex *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 AliHLTTPCConfMapPoint::SetIntPoint(Double_t inx, Double_t iny, Double_t inz,
+                                   Double_t inxerr, Double_t inyerr, Double_t inzerr)
+{
+  // Defines a new interaction point. This point is needed to calculate
+  // the conformal coordinates.
+
+  SetXt(inx);
+  SetYt(iny);
+  SetZt(inz);
+  SetXterr(inxerr);
+  SetYterr(inyerr);
+  SetZterr(inzerr);
+
+  return;
+}
+
+void AliHLTTPCConfMapPoint::SetAllCoord(const AliHLTTPCConfMapPoint *precedinghit)
+{
+  // 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 == precedinghit) {
+    SetIntPoint(precedinghit->GetX(),    precedinghit->GetY(),    precedinghit->GetZ(),
+                precedinghit->GetXerr(), precedinghit->GetYerr(), precedinghit->GetZerr());
+  }
+
+  else {
+    SetIntPoint(precedinghit->GetXt(),    precedinghit->GetYt(),    precedinghit->GetZt(),
+                precedinghit->GetXterr(), precedinghit->GetYterr(), precedinghit->GetZterr());
+  }
+
+  SetShiftedCoord();
+  SetConfCoord();
+
+  return;
+}
+
+void AliHLTTPCConfMapPoint::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 AliHLTTPCConfMapPoint::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.
+
+  if(fgDontMap){
+    fXprime = fx;
+    fYprime = fy;
+    fWxy = 0;
+    fs = 0; //track trajectory
+    fWz = 0;
+    return;
+  }
+
+  Double_t r2;
+  Double_t xyErrorScale = 1;
+  Double_t szErrorScale = 1;
+
+  if ((r2 = fXv*fXv + fYv*fYv)) 
+    {
+      fXprime =  fXv / r2;
+      fYprime = -fYv / r2;
+      
+      //set weights:
+      fWxy = r2*r2 / ((xyErrorScale*xyErrorScale)*((fxerr*fxerr)+(fyerr*fyerr)));
+      fs = 0; //track trajectory
+      fWz = (Double_t)(1./(szErrorScale*fzerr*fzerr));
+    } else {
+    fXprime    = 0.;
+    fYprime    = 0.;
+    fXprimeerr = 0.;
+    fYprimeerr = 0.;
+    fWxy = 0;
+    fWz = 0;
+    fs = 0;
+  }
+
+  return;
+}
+
+void AliHLTTPCConfMapPoint::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(fy,fx);
+  //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;
+}
+
+/*
+AliHLTTPCConfMapTrack *AliHLTTPCConfMapPoint::GetTrack(TClonesArray *tracks) const
+{
+  // Returns the pointer to the track to which this hit belongs.
+  
+  return (AliHLTTPCConfMapTrack*)tracks->At(this->GetTrackNumber());
+}
+*/
diff --git a/HLT/TPCLib/AliHLTTPCConfMapPoint.h b/HLT/TPCLib/AliHLTTPCConfMapPoint.h
new file mode 100644 (file)
index 0000000..dc14fe7
--- /dev/null
@@ -0,0 +1,197 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCConfMapPointH
+#define ALIHLTTPCConfMapPointH
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapPoint {
+
+ private:
+
+  Int_t fHitNumber;     //hit number
+  Int_t fTrackNumber;   //track number
+  Int_t fNextHitNumber; //next hit number
+  Bool_t fUsed;         //flag is used
+  Int_t fPadrow;        //padrow
+  Int_t fSector;        //sector
+
+  //global coordinates and their errors
+  Double_t fx;    //glob x
+  Double_t fy;    //glob y
+  Double_t fz;    //glob z
+  Double_t fxerr; //glob xerr
+  Double_t fyerr; //glob yerr
+  Double_t fzerr; //glob zerr
+
+  Double_t fWxy;  // x-y weight on x-y
+  Double_t fWz;   // z weight on z
+  Float_t fs;      //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
+  
+  AliHLTTPCConfMapPoint *fNextVolumeHit; //!
+  AliHLTTPCConfMapPoint *fNextRowHit;    //!
+  AliHLTTPCConfMapPoint *fNextTrackHit;  //! Linked chain of points in a track
+  Short_t fPhiIndex; //phi index
+  Short_t fEtaIndex; //eta index
+  Double_t fXYChi2; //xy chi
+  Double_t fSZChi2; //z chi
+  Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+  static Bool_t fgDontMap; //flag to switch off mapping  
+
+ public:
+
+  AliHLTTPCConfMapPoint();
+  virtual ~AliHLTTPCConfMapPoint();
+  
+  void Reset();
+  Bool_t ReadHits(AliHLTTPCSpacePointData* hits );
+  
+   // getter
+  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;}
+  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 fs;}
+
+  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;}
+  
+  AliHLTTPCConfMapPoint* GetNextVolumeHit(){return fNextVolumeHit;}
+  AliHLTTPCConfMapPoint* GetNextRowHit(){return fNextRowHit;}
+  AliHLTTPCConfMapPoint* GetNextTrackHit(){return fNextTrackHit;}
+  Short_t GetPhiIndex() const {return fPhiIndex;}
+  Short_t GetEtaIndex() const {return fEtaIndex;}
+  Double_t GetXYChi2() const {return fXYChi2;}
+  Double_t GetSZChi2() const {return fSZChi2;}
+  //Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+  // setter
+  void SetNextVolumeHit(AliHLTTPCConfMapPoint* p){fNextVolumeHit=p;}
+  void SetNextRowHit(AliHLTTPCConfMapPoint* p){fNextRowHit=p;}
+  void SetNextTrackHit(AliHLTTPCConfMapPoint* p){fNextTrackHit=p;}
+
+  void SetPhiIndex(Short_t p){fPhiIndex=p;}
+  void SetEtaIndex(Short_t p){fEtaIndex=p;}
+  void SetXYChi2(Double_t d) {fXYChi2=d;}
+  void SetSZChi2(Double_t d) {fSZChi2=d;}
+
+  static void SetDontMap(Bool_t b){fgDontMap=b;}
+
+  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 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){fs = 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(AliHLTTPCVertex *vertex);// does the usual setup in the right order
+  void SetAngles();               // calculate spherical angles and set values
+  void SetIntPoint(Double_t inx = 0., Double_t iny = 0.,
+                  Double_t inz = 0., Double_t inxerr = 0., 
+                  Double_t inyerr = 0., Double_t inzerr = 0.);  
+  //-> set interaction point
+  void SetShiftedCoord();// set shifted coordinates  
+  void SetAllCoord(const AliHLTTPCConfMapPoint *hit);// set conformal mapping coordinates in respect to given hit
+  void SetConfCoord();// conformal mapping
+
+  ClassDef(AliHLTTPCConfMapPoint, 1)   //Conformal mapping hit class.
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCConfMapTrack.cxx b/HLT/TPCLib/AliHLTTPCConfMapTrack.cxx
new file mode 100644 (file)
index 0000000..2515436
--- /dev/null
@@ -0,0 +1,261 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group 
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCConfMapFit.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPC.h"
+
+/** \class AliHLTTPCConfMapTrack
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapTrack
+//
+// Track class for conformal mapper
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapTrack)
+
+
+AliHLTTPCConfMapTrack::AliHLTTPCConfMapTrack()
+{
+  //Constructor
+  fChiSq[0] = 0.;
+  fChiSq[1] = 0.;
+}
+
+AliHLTTPCConfMapTrack::~AliHLTTPCConfMapTrack()
+{
+  //deconstructor
+}
+
+void AliHLTTPCConfMapTrack::DeleteCandidate()
+{
+  //Deletes this track by resetting all its parameters. Does not delete
+  //the object itself.
+
+  AliHLTTPCConfMapPoint *curHit = (AliHLTTPCConfMapPoint*)fFirstHit;
+  AliHLTTPCConfMapPoint *nextHit;
+  
+  while(curHit != 0)
+    {
+      nextHit = (AliHLTTPCConfMapPoint*)curHit->GetNextTrackHit();
+      curHit->SetNextTrackHit(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 AliHLTTPCConfMapTrack::SetProperties(Bool_t usage)
+{
+  //Set the hits to this track to 'usage'
+  for(StartLoop(); LoopDone(); GetNextHit())
+    {
+      AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)fCurrentHit;
+      p->SetUsage(usage);
+    }
+  return;
+}
+
+void AliHLTTPCConfMapTrack::Reset()
+{
+  //Resets the fit parameters of this track.
+
+  //xy-plane
+  fs11Xy   = 0;
+  fs12Xy   = 0;
+  fs22Xy   = 0;
+  fg1Xy    = 0;
+  fg2Xy    = 0;
+  fChiSq[0]  = 0.;
+    
+  //sz-plane
+  fs11Sz = 0;
+  fs12Sz = 0;
+  fs22Sz = 0;
+  fg1Sz  = 0;
+  fg2Sz  = 0;
+  fChiSq[1] = 0; 
+  SetLength(0);
+  SetNHits(0);
+}
+
+void AliHLTTPCConfMapTrack::UpdateParam(AliHLTTPCConfMapPoint *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)  
+    fFirstHit = thisHit;
+  else
+    ((AliHLTTPCConfMapPoint*)fLastHit)->SetNextTrackHit(thisHit);
+  fLastHit = thisHit;
+
+  
+  fs11Xy = fs11Xy + thisHit->GetXYWeight() ;
+  fs12Xy = fs12Xy + thisHit->GetXYWeight() * thisHit->GetXprime() ;
+  fs22Xy = fs22Xy + thisHit->GetXYWeight() * pow((thisHit->GetXprime()),2) ;
+  fg1Xy  = fg1Xy  + thisHit->GetXYWeight() * thisHit->GetYprime() ;
+  fg2Xy  = fg2Xy  + thisHit->GetXYWeight() * thisHit->GetXprime() * thisHit->GetYprime() ;
+    
+  fddXy  = fs11Xy * fs22Xy - pow((fs12Xy),2) ;
+  if ( fddXy != 0 ) 
+    {
+      fa1Xy  = ( fg1Xy * fs22Xy - fg2Xy * fs12Xy ) / fddXy ;
+      fa2Xy  = ( fg2Xy * fs11Xy - fg1Xy * fs12Xy ) / fddXy ;
+    }
+
+  //     Now in the sz plane
+  fs11Sz = fs11Sz + thisHit->GetZWeight() ;
+  fs12Sz = fs12Sz + thisHit->GetZWeight() * thisHit->GetS() ;
+  fs22Sz = fs22Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetS() ;
+  fg1Sz  = fg1Sz  + thisHit->GetZWeight() * thisHit->GetZ() ;
+  fg2Sz  = fg2Sz  + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetZ() ;
+  
+        
+  fddSz  = fs11Sz * fs22Sz -  fs12Sz * fs12Sz ;
+  if ( fddSz != 0 ) {
+    fa1Sz  = ( fg1Sz * fs22Sz - fg2Sz * fs12Sz ) / fddSz ;
+    fa2Sz  = ( fg2Sz * fs11Sz - fg1Sz * fs12Sz ) / fddSz ;
+  }
+}
+
+
+void AliHLTTPCConfMapTrack::Fill(AliHLTTPCVertex *vertex,Double_t max_Dca)
+{
+  //Fill track variables with or without fit.
+  
+  //fRadius = sqrt(fa2Xy*fa2Xy+1)/(2*fabs(fa1Xy));
+  Double_t radius = sqrt(fa2Xy*fa2Xy+1)/(2*fabs(fa1Xy));
+  SetRadius(radius);
+
+  //fPt = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * fRadius);
+  Double_t pt = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * GetRadius());
+  SetPt(pt);
+
+  if(GetPt() > max_Dca) //go for fit of helix in real space
+    {
+      AliHLTTPCConfMapFit *fit = new AliHLTTPCConfMapFit(this,vertex);
+      ComesFromMainVertex(AliHLTTPC::DoVertexFit());
+      fit->FitHelix();
+      
+      //AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fLastHit;
+      AliHLTTPCConfMapPoint *fHit = (AliHLTTPCConfMapPoint*)fFirstHit;
+      SetLastPoint(fHit->GetX(),fHit->GetY(),fHit->GetZ());
+      
+      UpdateToFirstPoint();
+      
+      delete fit;
+    }
+  else if(GetPt() == 0)
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapTrack::Fill","Tracks")<<AliHLTTPCLog::kDec<<
+      "Found track with Pt=0!!!"<<ENDLOG;
+  else
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapTrack::Fill","Tracks")<<AliHLTTPCLog::kDec<<
+       "Track with pt<max_Dca :"<<GetPt()<<ENDLOG;
+    }
+}
+
+Int_t AliHLTTPCConfMapTrack::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++) {
+    AliHLTTPCConfMapPoint *c=(AliHLTTPCConfMapPoint*)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++) {
+    AliHLTTPCConfMapPoint *c=(AliHLTTPCConfMapPoint*)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++) {
+    AliHLTTPCConfMapPoint *c = (AliHLTTPCConfMapPoint*)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/TPCLib/AliHLTTPCConfMapTrack.h b/HLT/TPCLib/AliHLTTPCConfMapTrack.h
new file mode 100644 (file)
index 0000000..6632b55
--- /dev/null
@@ -0,0 +1,93 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapTrack
+#define ALIHLTTPC_ConfMapTrack
+
+#include <string.h>
+
+#include "AliHLTTPCTrack.h"
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCConfMapPoint.h"
+
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapTrack :public AliHLTTPCTrack {
+
+ public:
+  
+  AliHLTTPCConfMapTrack();
+  virtual ~AliHLTTPCConfMapTrack();
+  void Fill(AliHLTTPCVertex *vertex,Double_t max_Dca);
+  void Reset();
+  void UpdateParam(AliHLTTPCConfMapPoint *hit);
+  void DeleteCandidate();
+
+  void StartLoop() {fCurrentHit = fFirstHit;}
+  void GetNextHit() {fCurrentHit = ((AliHLTTPCConfMapPoint*)fCurrentHit)->GetNextTrackHit();}
+  Int_t LoopDone() const {return fCurrentHit != 0;}
+
+  // setter   
+  void  SetChiSq1(Double_t f) {fChiSq[0]=f;} 
+  void  SetChiSq2(Double_t f) {fChiSq[1]=f;}
+  void  SetProperties(Bool_t fUsage);
+
+  // getter
+  Double_t const  *GetChiSq()   const { return fChiSq;}
+  Double_t GetChiSq1() const { return fChiSq[0]; }
+  Double_t GetChiSq2() const { return fChiSq[1]; }
+
+  /*
+  Double_t GetS11Xy() const {return fs11Xy;}
+  Double_t GetS12Xy() const {return fs12Xy;}
+  Double_t GetS22Xy() const {return fs22Xy;}
+  Double_t GetG1Xy()  const {return fg1Xy;}
+  Double_t GetG2Xy()  const {return fg2Xy;}
+  Double_t GetS11Sz() const {return fs11Sz;}
+  Double_t GetS12Sz() const {return fs12Sz;}
+  Double_t GetS22z()  const {return fs22Sz;}
+  Double_t GetG1Sz()  const {return fg1Sz;}
+  Double_t GetG2Sz()  const { return fg2Sz;}
+  */
+
+  Double_t GetDDXy() const {return fddXy;} 
+  Double_t GetA1Xy() const {return fa1Xy;} 
+  Double_t GetA2Xy() const {return fa2Xy;}   
+  Double_t GetDDSz() const {return fddSz;} 
+  Double_t GetA1Sz() const {return fa1Sz;} 
+  Double_t GetA2Sz() const {return fa2Sz;}  
+
+  AliHLTTPCConfMapPoint* GetFirstHit()   const {return fFirstHit;}
+  AliHLTTPCConfMapPoint* GetLastHit()    const {return fLastHit;}
+  AliHLTTPCConfMapPoint* GetCurrentHit() const {return fCurrentHit;}
+  Int_t GetMCLabel();
+
+ protected:
+
+  AliHLTTPCConfMapPoint *fCurrentHit;  //!
+  AliHLTTPCConfMapPoint *fLastHit;  //!
+  AliHLTTPCConfMapPoint *fFirstHit;  //!
+
+
+  Double_t fChiSq[2]; //chi squared
+  
+  //fit parameters. Bad naming convention, i know...
+  Double_t    fs11Xy; //helper
+  Double_t    fs12Xy; //helper
+  Double_t    fs22Xy; //helper
+  Double_t    fg1Xy;  //helper
+  Double_t    fg2Xy;  //helper       
+  Double_t    fs11Sz; //helper
+  Double_t    fs12Sz; //helper
+  Double_t    fs22Sz; //helper
+  Double_t    fg1Sz;  //helper
+  Double_t    fg2Sz;  //helper 
+  
+  Double_t    fddXy, fa1Xy, fa2Xy ;    /*fit par in xy */
+  Double_t    fddSz, fa1Sz, fa2Sz ;    /*fit par in sz */
+  
+  ClassDef(AliHLTTPCConfMapTrack,1) //Conformal mapping track class
+};
+    
+#endif
+    
diff --git a/HLT/TPCLib/AliHLTTPCConfMapper.cxx b/HLT/TPCLib/AliHLTTPCConfMapper.cxx
new file mode 100644 (file)
index 0000000..9ce5591
--- /dev/null
@@ -0,0 +1,889 @@
+// @(#) $Id$
+
+/** \class AliHLTTPCConfMapper
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapper
+//
+// Conformal mapping base class
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+// Copyright &copy ALICE HLT Group
+</pre>
+*/
+
+#include <sys/time.h>
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCLogging.h" 
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCConfMapper.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapper)
+
+AliHLTTPCConfMapper::AliHLTTPCConfMapper()
+{
+  //Default constructor
+  fVertex = NULL;
+  fTrack = NULL;
+  fHit = NULL;
+  fVolume = NULL;
+  fRow = NULL;
+  fBench = (Bool_t)true;
+  fVertexConstraint = (Bool_t)true;
+  fParamSet[0]=0;
+  fParamSet[1]=0;
+}
+
+
+AliHLTTPCConfMapper::~AliHLTTPCConfMapper()
+{
+  // Destructor.
+  if(fVolume) {
+    delete [] fVolume;
+  }
+  if(fRow) {
+    delete [] fRow;
+  }
+  if(fHit) {
+    delete [] fHit;
+  }
+  if(fTrack) {
+    delete fTrack;
+  }
+}
+void AliHLTTPCConfMapper::InitVolumes()
+{
+  //Data organization.
+  //Allocate volumes, set conformal coordinates and pointers.
+  
+  //Should be done after setting the track parameters
+  
+  fNumRowSegmentPlusOne = AliHLTTPCTransform::GetNRows();//NumRows[0]; //Maximum 32.
+  fNumPhiSegmentPlusOne = fNumPhiSegment+1;
+  fNumEtaSegmentPlusOne = fNumEtaSegment+1;
+  fNumPhiEtaSegmentPlusOne = fNumPhiSegmentPlusOne*fNumEtaSegmentPlusOne;
+  fBounds = fNumRowSegmentPlusOne * fNumPhiSegmentPlusOne * fNumEtaSegmentPlusOne;
+  
+  //Allocate volumes:
+  if(fVolume) delete [] fVolume;
+  if(fRow) delete [] fRow;
+  
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
+    "Allocating "<<fBounds*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
+    "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
+  
+  fVolume = new AliHLTTPCConfMapContainer[fBounds];
+  fRow = new AliHLTTPCConfMapContainer[fNumRowSegmentPlusOne];
+  
+  memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
+  memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
+  
+  Int_t maxnumoftracks = 2000;
+  Int_t maxnumofhits = 120000;
+  
+  if(fHit)
+    delete [] fHit;
+  if(fTrack)
+    delete fTrack;
+    
+  fHit = new AliHLTTPCConfMapPoint[maxnumofhits];
+  fTrack = new AliHLTTPCTrackArray("AliHLTTPCConfMapTrack",maxnumoftracks);
+}
+
+void AliHLTTPCConfMapper::InitSector(Int_t sector,Int_t *rowrange,Float_t *etarange)
+{ //sector means slice here
+  //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...)
+    
+  //Define tracking area:
+  if(rowrange)
+    {
+      fRowMin = rowrange[0];
+      fRowMax = rowrange[1];
+    }
+  else //complete sector
+    {
+      fRowMin = 0;
+      fRowMax = AliHLTTPCTransform::GetNRows() - 1;
+    }
+  if(etarange)
+    {
+      fEtaMin = etarange[0];
+      fEtaMax = sector < 18 ? etarange[1] : -etarange[1];
+    }
+  else
+    {
+      fEtaMin = 0;
+      fEtaMax = sector < 18 ? 0.9 : -0.9;
+    }
+  
+  //Set the angles to sector 2:
+  fPhiMin = -10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) - 10/todeg;
+  fPhiMax =  10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) + 10/todeg;
+
+  fNTracks=0;
+  fMainVertexTracks = 0;
+  fClustersUnused = 0;
+  fEtaHitsOutOfRange=0;
+  fPhiHitsOutOfRange=0;
+  
+  fNumRowSegment = fRowMax - fRowMin; //number of rows to be considered by tracker
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitSector","B-field")
+    <<"Tracker initializing with a magnetic field of "<<AliHLTTPCTransform::GetBField()<<ENDLOG;
+  
+  fTrack->Reset();
+}
+
+Bool_t AliHLTTPCConfMapper::ReadHits(UInt_t count, AliHLTTPCSpacePointData* hits )
+{
+  //read hits
+  Int_t nhit=(Int_t)count; 
+  for (Int_t i=0;i<nhit;i++)
+    {
+      fHit[i].Reset();
+      fHit[i].ReadHits(&(hits[i]));
+    }
+  fClustersUnused += nhit;
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::ReadHits","#hits")
+    <<AliHLTTPCLog::kDec<<"hit_counter: "<<nhit<<" count: "<<count<<ENDLOG;
+  
+  return true;
+}
+
+void AliHLTTPCConfMapper::SetPointers()
+{
+  //Check if there are not enough clusters to make a track in this sector
+  //Can happen in pp events.
+
+  if(fClustersUnused < fMinPoints[fVertexConstraint])
+    return;
+  
+  //Reset detector volumes
+  memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
+  memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
+  
+  Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
+  Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
+
+  Int_t volumeIndex;
+  Int_t localcounter=0;
+  for(Int_t j=0; j<fClustersUnused; j++)
+    {
+      //AliHLTTPCConfMapPoint *thisHit = (AliHLTTPCConfMapPoint*)fHit->At(j);
+      AliHLTTPCConfMapPoint *thisHit = &(fHit[j]);
+
+      thisHit->Setup(fVertex);
+      
+      Int_t localrow = thisHit->GetPadRow();
+      
+      if(localrow < fRowMin || localrow > fRowMax)
+       continue;
+
+      //Get indexes:
+      thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1));
+      
+      if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment)
+       {
+         //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
+         fPhiHitsOutOfRange++;
+         continue;
+       }
+      
+      thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1));
+      if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment)
+       {
+         //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
+         fEtaHitsOutOfRange++;
+         continue;
+       }
+      localcounter++;
+      
+      volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne + 
+                    thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex();
+      
+      if(fVolume[volumeIndex].first == NULL)
+       fVolume[volumeIndex].first = (void *)thisHit;
+      else
+       ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit);
+      fVolume[volumeIndex].last = (void *)thisHit;
+      
+      
+      //set row pointers
+      if(fRow[(localrow-fRowMin)].first == NULL)
+       fRow[(localrow-fRowMin)].first = (void *)thisHit;
+      else
+       ((AliHLTTPCConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit);
+       fRow[(localrow-fRowMin)].last = (void *)thisHit;
+    }
+  
+  if(fClustersUnused>0 && localcounter==0)
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::SetPointers","Parameters")
+      <<AliHLTTPCLog::kDec<<"No points passed to track finder, hits out of range: "
+      <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG;
+
+  Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange);
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::SetPointers","Setup")
+    <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange
+    <<" hits accepted "<<hits_accepted<<ENDLOG;
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking_a()
+{
+  //Tracking with vertex constraint.
+
+  if(!fParamSet[(Int_t)kTRUE])
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+       "Tracking parameters not set!"<<ENDLOG;
+      return;
+    }
+
+  Double_t initCpuTime,cpuTime;
+  initCpuTime = CpuTime();
+
+  SetPointers();
+  SetVertexConstraint(true);
+  cpuTime = CpuTime() - initCpuTime;
+  if(fBench)
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_a","Timing")
+      <<AliHLTTPCLog::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+  
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking_b()
+{
+  //Tracking with vertex constraint.
+
+  if(!fParamSet[(Int_t)kTRUE])
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+       "Tracking parameters not set!"<<ENDLOG;
+      return;
+    }
+  Double_t initCpuTime,cpuTime;
+  initCpuTime = CpuTime();
+  
+  ClusterLoop();
+  cpuTime = CpuTime() - initCpuTime;
+  if(fBench)
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_b","Timing")
+      <<AliHLTTPCLog::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking()
+{
+  //Tracking with vertex constraint.
+
+  if(!fParamSet[(Int_t)kTRUE])
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+       "Tracking parameters not set!"<<ENDLOG;
+      return;
+    }
+
+  Double_t initCpuTime,cpuTime;
+  initCpuTime = CpuTime();
+  
+  SetPointers();
+  SetVertexConstraint(true);
+      
+  ClusterLoop();
+
+  cpuTime = CpuTime() - initCpuTime;
+  if(fBench)
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking","Timing")<<AliHLTTPCLog::kDec<<
+      "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+  
+  return;
+}
+
+void AliHLTTPCConfMapper::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.
+  
+  if(!fParamSet[(Int_t)kFALSE])
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::NonVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+       "Tracking parameters not set!"<<ENDLOG;
+      return;
+    }
+  
+  SetVertexConstraint(false);
+  ClusterLoop();
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::NonVertexTracking","ntracks")<<AliHLTTPCLog::kDec<<
+    "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG;
+  return;
+}
+
+void AliHLTTPCConfMapper::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;
+  SetParamDone(kTRUE);
+}
+
+void AliHLTTPCConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
+                                       Int_t rowscopetracklet, Int_t rowscopetrack)
+{
+  //set parameters for non-vertex tracking
+  SetTrackletLength(trackletlength,(Bool_t)false);
+  SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
+  SetRowScopeTrack(rowscopetrack, (Bool_t)false);
+  SetMinPoints(tracklength,(Bool_t)false);
+  SetParamDone(kFALSE);
+}
+
+void AliHLTTPCConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint)
+{
+  //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
+  
+  SetHitChi2Cut(hitChi2Cut,vertexconstraint);
+  SetGoodHitChi2(goodHitChi2,vertexconstraint);
+  SetTrackChi2Cut(trackChi2Cut,vertexconstraint);
+  SetMaxDist(maxdist,vertexconstraint);
+}
+
+void AliHLTTPCConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc)
+{
+  //Sets cuts of tracklets. Right now this is only:
+  //maxangle:  Maximum angle when forming segments (if trackletlength > 2)
+  fGoodDist=goodDist;
+  SetMaxAngleTracklet(maxangle, vc);
+}
+
+void AliHLTTPCConfMapper::ClusterLoop()
+{
+  //Loop over hits, starting at outermost padrow, and trying to build segments.
+  
+  //Check if there are not enough clusters to make a track in this sector
+  //Can happen in pp events.
+  if(fClustersUnused < fMinPoints[fVertexConstraint])
+    return;
+  
+  Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
+  AliHLTTPCConfMapPoint *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(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--)
+    {
+      if(fRow[(rowsegm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
+       break;
+
+      for(hit = (AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit())
+       {
+         if(hit->GetUsage() == true)
+           continue;
+         else
+           CreateTrack(hit);
+       }
+    }
+  
+  return;
+}
+
+
+void AliHLTTPCConfMapper::CreateTrack(AliHLTTPCConfMapPoint *hit)
+{
+  //Tries to create a track from the initial hit given by ClusterLoop()
+
+  AliHLTTPCConfMapPoint *closesthit = NULL;
+  AliHLTTPCConfMapTrack *track = NULL;
+  
+  Int_t point;
+  Int_t tracks = fNTracks;
+  fNTracks++;
+
+  track = (AliHLTTPCConfMapTrack*)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((closesthit = GetNextNeighbor(hit)))
+       {//closest hit exist
+         
+         //   Calculate track length in sz plane
+         dx = ((AliHLTTPCConfMapPoint*)closesthit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
+         dy = ((AliHLTTPCConfMapPoint*)closesthit)->GetY() - ((AliHLTTPCConfMapPoint*)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);
+
+         //closesthit->SetS(track->fLength);
+         closesthit->SetS(track->GetLength());
+
+         //update fit parameters
+         track->UpdateParam(closesthit);
+         trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
+       
+         hit = closesthit;
+       }
+      else
+       {
+         //closest hit does not exist:
+         track->DeleteCandidate();
+         fTrack->RemoveLast();
+         fNTracks--;
+         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();
+         fNTracks--;
+       }
+      
+      else//good tracklet ->proceed, follow the trackfit
+       {
+         tracks++;
+                                 
+         //define variables to keep the total chi:
+         Double_t xyChi2 = track->GetChiSq1();
+         Double_t szChi2 = track->GetChiSq2();
+         
+         for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
+           {
+             track->SetChiSq1(fHitChi2Cut[fVertexConstraint]);
+             closesthit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->GetLastHit(),track);
+             
+             if(closesthit)
+               {
+                 //keep total chi:
+                 Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2();
+                 xyChi2 += lxyChi2;
+                 closesthit->SetXYChi2(lxyChi2);
+                                 
+                 //update track length:
+                 track->SetLength(closesthit->GetS());
+                 szChi2 += track->GetChiSq2();
+                 closesthit->SetSZChi2(track->GetChiSq2());
+                 
+                 track->UpdateParam(closesthit);
+                 trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
+                 
+                 //add closest hit to track
+                 closesthit->SetUsage(true);
+                 closesthit->SetTrackNumber(tracks-1);
+                 
+               }//closesthit
+             
+             else
+               {
+                 //closest hit does not exist
+                 point = fNumRowSegment; //continue with next hit in segment
+               }//else
+             
+           }//create tracks
+         
+         //store track chi2:
+         track->SetChiSq1(xyChi2);
+         track->SetChiSq2(szChi2);
+         Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints();
+         
+         //remove tracks with not enough points already now
+         if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint])
+           {
+             track->SetProperties(false);
+             fNTracks--;
+             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;
+}
+
+AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *starthit,
+                                         AliHLTTPCConfMapTrack *track)
+{
+  //When forming segments: Finds closest hit to input hit
+  //When forming tracks: Find closest hit to track fit.
+  
+  Double_t dist,closestdist = fMaxDist[fVertexConstraint];
+  
+  AliHLTTPCConfMapPoint *hit = NULL;
+  AliHLTTPCConfMapPoint *closesthit = NULL;
+    
+  Int_t subrowsegm;
+  Int_t subphisegm;
+  Int_t subetasegm;
+  Int_t volumeIndex;
+  Int_t testhit;
+
+  Int_t maxrow = starthit->GetPadRow()-1;
+  Int_t minrow;
+
+  if(track) //finding hit close to trackfit
+    {
+      minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
+    }
+  else
+    {
+      minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
+    }
+
+  //make a smart loop
+  Int_t loopeta[25] = {0,0,0,-1,-1,-1,1,1,1, 0,0,-1,-1,1,1,-2,-2,-2,-2,-2,2,2,2,2,2};
+  Int_t loopphi[25] = {0,-1,1,0,-1,1,0,-1,1, -2,2,-2,2,-2,2,-2,-1,0,1,2,-2,-1,0,1,2};
+  
+  if(minrow < fRowMin)
+    minrow = fRowMin;
+  if(maxrow < fRowMin)
+    return 0;  //reached the last padrow under consideration
+
+  else
+    {
+      //loop over sub rows
+      for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--)
+       {
+         //loop over subsegments, in the order defined above.
+         for(Int_t i=0; i<9; i++)  
+           {
+             subphisegm = starthit->GetPhiIndex() + loopphi[i];
+             
+             if(subphisegm < 0 || subphisegm >= fNumPhiSegment)
+               continue;
+             /*
+               if(subphisegm<0)
+               subphisegm += fNumPhiSegment;
+               
+               else if(subphisegm >=fNumPhiSegment)
+               subphisegm -= fNumPhiSegment;
+             */
+             //loop over sub eta segments
+             
+             subetasegm = starthit->GetEtaIndex() + loopeta[i];
+             
+             if(subetasegm < 0 || subetasegm >=fNumEtaSegment)
+               continue;//segment exceeds bounds->skip it
+             
+             //loop over hits in this sub segment:
+             volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne +
+               subphisegm*fNumEtaSegmentPlusOne + subetasegm;
+             
+             if(volumeIndex<0)
+               {//debugging
+                 LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::GetNextNeighbor","Memory")<<AliHLTTPCLog::kDec<<
+                   "VolumeIndex error "<<volumeIndex<<ENDLOG;
+               }
+             
+             for(hit = (AliHLTTPCConfMapPoint*)fVolume[volumeIndex].first;
+                 hit!=0; hit = hit->GetNextVolumeHit())
+               {
+                 
+                 if(!hit->GetUsage())
+                   {//hit was not used before
+                     
+                     //set conformal mapping if looking for nonvertex tracks:
+                     if(!fVertexConstraint)
+                       {
+                         hit->SetAllCoord(starthit);
+                       }
+                    
+                     if(track)//track search - look for nearest neighbor to extrapolated track
+                       {
+                         if(!VerifyRange(starthit,hit))
+                           continue;
+                                                 
+                         testhit = EvaluateHit(starthit,hit,track);
+                         
+                         if(testhit == 0)//chi2 not good enough, keep looking
+                           continue;
+                         else if(testhit==2)//chi2 good enough, return it
+                           return hit;
+                         else
+                           closesthit = hit;//chi2 acceptable, but keep looking
+                         
+                       }//track search
+                     
+                     else //tracklet search, look for nearest neighbor
+                       {
+                         
+                         if((dist=CalcDistance(starthit,hit)) < closestdist)
+                           {
+                             if(!VerifyRange(starthit,hit))
+                               continue;
+                             closestdist = dist;
+                             closesthit = hit;
+                        
+                             //if this hit is good enough, return it:
+                             if(closestdist < fGoodDist)
+                               return closesthit;
+                           }
+                         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(closesthit)// && closestdist < mMaxDist)
+    return closesthit;
+  else
+    return 0;
+}
+
+Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *starthit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track) 
+{
+  //Check if space point gives a fit with acceptable chi2.
+  
+  Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
+  temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy());
+  dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.);
+  
+  //Calculate chi2
+  lchi2 = (dxy*hit->GetXYWeight());
+  
+  if(lchi2 > track->GetChiSq1())//chi2 was worse than before.
+    return 0;
+    
+  //calculate s and the distance hit-line
+  dx = starthit->GetX()-hit->GetX();
+  dy = starthit->GetY()-hit->GetY();
+  //slocal = track->fLength+sqrt(dx*dx+dy*dy);
+  slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
+  
+  temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz());
+  dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1);
+  
+  //calculate chi2
+  lszChi2 = dsz*hit->GetZWeight();
+  lchi2 += lszChi2;
+  
+    
+  //check whether chi2 is better than previous one:
+  if(lchi2 < track->GetChiSq1())
+    {
+      track->SetChiSq1(lchi2);
+      track->SetChiSq2(lszChi2);
+    
+      hit->SetS(slocal);
+  
+      //if chi2 good enough, stop here:
+      if(lchi2 < fGoodHitChi2[fVertexConstraint]) 
+        return 2;
+      
+      return 1;
+    }
+  
+  return 0;
+  
+}
+
+Double_t AliHLTTPCConfMapper::CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
+{
+  //Return distance between two clusters, defined by Pablo
+  
+  Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() );
+  if (phidiff > AliHLTTPCTransform::Pi()) phidiff = AliHLTTPCTransform::TwoPi() - phidiff;
+  
+  return AliHLTTPCTransform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) * 
+         (phidiff + fabs( hit1->GetEta() - hit2->GetEta()))));
+}
+
+Bool_t AliHLTTPCConfMapper::VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *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 > AliHLTTPCTransform::Pi()) dphi = fabs(AliHLTTPCTransform::TwoPi() - dphi);
+  if(dphi > fMaxPhi) return false;
+  
+  deta = fabs(hit1->GetEta() - hit2->GetEta());
+  if(deta > fMaxEta) return false;
+
+  return true;
+
+}
+
+Double_t AliHLTTPCConfMapper::TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n) const
+{
+  // Returns the angle 'between' the last three points (started at point number n) on this track.
+  
+  if(n > track->GetNumberOfPoints())
+    n = track->GetNumberOfPoints();
+  
+  if(n<3)
+    return 0;
+  
+  Double_t x1[2];
+  Double_t x2[2];
+  Double_t x3[2];
+  Double_t angle1,angle2;
+  Int_t counter=0;
+  for(track->StartLoop(); track->LoopDone(); track->GetNextHit())
+    {
+      AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)track->GetCurrentHit();
+      if( (n-1) == counter)
+       {
+         x1[0] = p->GetX();
+         x1[1] = p->GetY();
+       }
+      else if( (n-2) == counter)
+       {
+         x2[0] = p->GetX();
+         x2[1] = p->GetY();
+       }
+      else if( (n-3) == counter)
+       {
+         x3[0] = p->GetX();
+         x3[1] = p->GetY();
+       }
+      counter++;
+    }
+  
+  angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]);
+  angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]);
+  
+  return fabs(angle1-angle2);
+  
+  /*
+    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] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetX();
+  x1[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetY();
+
+  x2[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX();
+  x2[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY();
+  
+  angle1 = atan2(x1[1],x1[0]);
+  angle2 = atan2(x2[1],x1[0]);
+  return fabs(angle1-angle2);
+  */
+}
+
+Int_t AliHLTTPCConfMapper::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 numoftracks = fNTracks;
+  if(fNTracks == 0)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
+       "No tracks found!!"<<ENDLOG;
+      return 0;
+    }
+
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
+    "Number of found tracks: "<<fNTracks<<ENDLOG;
+  
+  //  fTrack->Sort();
+  for(Int_t i=0; i<numoftracks; i++)
+    {
+      AliHLTTPCConfMapTrack *track = (AliHLTTPCConfMapTrack*)fTrack->GetTrack(i);
+      track->Fill(fVertex,fMaxDca);
+    }
+  return 1;
+}
+
+Double_t AliHLTTPCConfMapper::CpuTime()
+{
+  //Return the Cputime in seconds.
+ struct timeval tv;
+ gettimeofday( &tv, NULL );
+ return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
+}
diff --git a/HLT/TPCLib/AliHLTTPCConfMapper.h b/HLT/TPCLib/AliHLTTPCConfMapper.h
new file mode 100644 (file)
index 0000000..f4c0758
--- /dev/null
@@ -0,0 +1,145 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCCONFMAPPER_H
+#define ALIHLTTPCCONFMAPPER_H
+
+//
+//Conformal mapping base class
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+
+class AliHLTTPCConfMapPoint;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+class AliHLTTPCTrackArray;
+class AliHLTTPCSpacePointData;
+
+
+class AliHLTTPCConfMapper {
+
+ public:
+
+  AliHLTTPCConfMapper();
+  //  AliHLTTPCConfMapper(AliTPCParam *param,AliHLTTPCVertex *vertex,Bool_t bench=(Bool_t)false);
+  virtual ~AliHLTTPCConfMapper();
+  
+  void InitVolumes();
+  void InitSector(Int_t sector,Int_t *rowrange=0,Float_t *etarange=0);
+  void SetVertex(AliHLTTPCVertex *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, AliHLTTPCSpacePointData* hits );
+  void ClusterLoop();
+  void CreateTrack(AliHLTTPCConfMapPoint *hit);
+  AliHLTTPCConfMapPoint *GetNextNeighbor(AliHLTTPCConfMapPoint *start_hit,AliHLTTPCConfMapTrack *track=NULL);
+  Int_t EvaluateHit(AliHLTTPCConfMapPoint *start_hit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track);
+
+  Double_t CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const;
+  Double_t TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n=3) const;
+  Bool_t VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const;
+  Int_t FillTracks();
+  
+  //getters
+  Int_t GetNumberOfTracks()    const {return fNTracks;}
+  AliHLTTPCTrackArray *GetTracks() const {return fTrack;}
+  Double_t GetMaxDca()         const {return fMaxDca;}
+  AliHLTTPCVertex* GetVertex()     const {return fVertex;}
+  Double_t CpuTime();
+
+  //setters
+  void SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut, Int_t maxdist,Bool_t vertexconstraint); 
+  void SetTrackletCuts(Double_t maxangle,Double_t goodDist,Bool_t vc);    //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 SetMaxDca(Double_t f) {fMaxDca = f;}
+
+  //setter:
+  void SetMinPoints(Int_t f,Bool_t vconstraint) {fMinPoints[(Int_t)vconstraint] = f; }  
+  void SetVertexConstraint(Bool_t f) {fVertexConstraint =f;}
+  
+  void SetHitChi2Cut(Double_t f,Bool_t vert) {fHitChi2Cut[(Int_t)vert]=f;}
+  void SetGoodHitChi2(Double_t f,Bool_t vert) {fGoodHitChi2[(Int_t)vert]=f;}
+  void SetTrackChi2Cut(Double_t f,Bool_t vert) {fTrackChi2Cut[(Int_t)vert]=f;}
+  void SetMaxDist(Int_t f,Bool_t vert) {fMaxDist[(Int_t)vert]=f;}
+  void SetTrackletLength(Int_t f,Bool_t vert) {fTrackletLength[(Int_t)vert]=f;}
+  void SetRowScopeTrack(Int_t f, Bool_t vc){fRowScopeTrack[(Int_t)vc] = f;}
+  void SetRowScopeTracklet(Int_t f, Bool_t vc){fRowScopeTracklet[(Int_t)vc] = f;}
+  void SetMaxAngleTracklet(Double_t f, Bool_t vc){fMaxAngleTracklet[(Int_t)vc] = f;}
+
+  void SetPointers();
+  void SetParamDone(Bool_t vconstraint) {fParamSet[(Int_t)vconstraint] = kTRUE;}
+
+ private:
+
+  struct AliHLTTPCConfMapContainer 
+  {
+    void *first; // first track
+    void *last;  // last track
+  };
+
+  Bool_t fBench; //run-time measurements
+  Int_t fNTracks; //number of tracks build.
+
+  AliHLTTPCVertex *fVertex; //!
+  Bool_t fParamSet[2];  //!
+  Bool_t fVertexFinder; //Include vertexfinding or not 
+                        //(latter case vertex=(0,0,0))
+
+  AliHLTTPCConfMapPoint *fHit;  //!
+  AliHLTTPCTrackArray *fTrack;  //!
+  Double_t fMaxDca;      //cut value for momentum fit
+  
+  AliHLTTPCConfMapContainer *fVolume;  //!  Segment volume
+  AliHLTTPCConfMapContainer *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;   // row+1
+  Int_t  fNumPhiSegmentPlusOne;   // phi+1
+  Int_t  fNumEtaSegmentPlusOne;   // eta+1
+  Int_t  fNumPhiEtaSegmentPlusOne;// phieta+1
+  Int_t  fBounds;                 // bounds
+  Int_t  fPhiHitsOutOfRange;      // phi hits out of range
+  Int_t  fEtaHitsOutOfRange;      // eta hits out of range
+
+  //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[2];              //maximum distance between two hits 
+  Double_t fHitChi2Cut[2];        //Maximum hit chi2
+  Double_t fGoodHitChi2[2];       //Chi2 to stop looking for next hit
+  Double_t fTrackChi2Cut[2];      //Maximum track chi2
+  Double_t fGoodDist;             //In segment building, distance consider good enough
+  Double_t fMaxPhi;               //Maximum phi
+  Double_t fMaxEta;               //Maximum eta
+
+  // Tracking informtion
+  Int_t fMainVertexTracks; //number of tracks coming from the main vertex
+  Int_t fClustersUnused;   //number of unused clusters
+
+  ClassDef(AliHLTTPCConfMapper,1) //Base class for conformal mapping tracking
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCDDLDataFileHandler.cxx b/HLT/TPCLib/AliHLTTPCDDLDataFileHandler.cxx
new file mode 100644 (file)
index 0000000..4e3e72c
--- /dev/null
@@ -0,0 +1,416 @@
+// @(#) $Id$
+
+// Author: C. Loizides <loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCDigitData.h"
+#ifdef use_newio
+#include "AliRawReaderRoot.h"
+#include "AliRawReaderDate.h"
+#else
+#include "AliHLTTPCDDLTPCRawStream.h"
+#include "AliHLTTPCDDLRawReaderFile.h"
+#endif
+#include "AliHLTTPCDDLDataFileHandler.h"
+
+#if __GNUC__ == 3
+using namespace std;
+#endif
+
+/** \class AliHLTTPCDDLDataFileHandler 
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDDLDataFileHandler
+//
+//  This class does converts from the DDL format of offline
+//  into the memory I/O handling of the HLT binary files.
+//  
+//  Examples: see ddl2binary in exa and the general 
+//            AliHLTTPCMemHandler class description
+//
+</pre>
+*/
+
+ClassImp(AliHLTTPCDDLDataFileHandler)
+
+AliHLTTPCDDLDataFileHandler::AliHLTTPCDDLDataFileHandler()
+{
+  // default constructor
+  fReader=0;
+  fTPCStream=0;
+}
+
+AliHLTTPCDDLDataFileHandler::~AliHLTTPCDDLDataFileHandler()
+{
+  // destructor
+  FreeAll();
+}
+
+void AliHLTTPCDDLDataFileHandler::FreeAll()
+{
+  // frees all heap memory
+  if(fReader) delete fReader;
+  fReader = 0;
+  if(fTPCStream) delete fTPCStream;
+  fTPCStream = 0;
+}
+
+
+#ifdef use_newio
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(AliRawEvent *rawevent)
+{
+  // sets the input of the reader
+  fEvent=-1;
+  fFilename="";
+  if(fReader) delete fReader;
+  fReader=new AliRawReaderRoot(rawevent);
+  if(fTPCStream) delete fTPCStream;
+  fTPCStream=new AliTPCRawStream(fReader);
+
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name,Int_t event)
+{
+  // sets the input of the reader
+  fEvent=event;
+  if(fReader) delete fReader;
+  if(fTPCStream) delete fTPCStream;
+  if(event>=0){
+    fFilename=name;
+    fReader=new AliRawReaderRoot(name,event);
+  } else {
+    fFilename="";
+    fReader=new AliRawReaderDate((void *)name);
+  }
+  fTPCStream=new AliTPCRawStream(fReader);
+
+  return kTRUE;
+}
+#else
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name, Bool_t add)
+{
+  // sets the input of the reader
+  if(fReader){
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::SetReaderInput","File Open")
+      <<"Reader ptr is already in use"<<ENDLOG;
+    return kFALSE;
+  }
+  fReader=new AliHLTTPCDDLRawReaderFile(name,add);
+  fTPCStream=new AliHLTTPCDDLTPCRawStream(fReader);
+  
+  return kTRUE;
+}
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(AliHLTTPCDDLRawReaderFile *rf)
+{
+  // sets the input of the reader
+  if(fReader){
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCRawDataFileHandler::SetReaderInput","File Open")
+      <<"Reader ptr is already in use, delete it first"<<ENDLOG;
+    return kFALSE;
+  }
+
+  //Open the raw data file with given file.
+  fReader = rf;
+  fTPCStream=new AliHLTTPCDDLTPCRawStream(fReader);
+
+  return kTRUE;
+}
+#endif
+
+void AliHLTTPCDDLDataFileHandler::CloseReaderInput()
+{
+  // closes the input of the reader
+  if(!fReader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCRawDataFileHandler::CloseReaderInput","File Close")
+      <<"Nothing to Close"<<ENDLOG;
+    return;
+  }
+
+  delete fReader;
+  delete fTPCStream;
+  fReader = 0;
+  fTPCStream = 0;
+}
+
+#ifdef use_newio
+Bool_t AliHLTTPCDDLDataFileHandler::IsDigit(Int_t /*i*/) const
+{
+  // dummy
+  return kTRUE;
+}
+#endif
+
+#ifndef fast_raw
+AliHLTTPCDigitRowData * AliHLTTPCDDLDataFileHandler::DDLData2Memory(UInt_t &nrow,Int_t event)
+{
+  // transfers the DDL data to the memory
+#ifdef use_newio
+  if((fEvent>=0)&&(event!=fEvent)){
+    fEvent=event;
+    if(fReader) delete fReader;
+    if(fTPCStream) delete fTPCStream;
+    fReader=new AliRawReaderRoot(fFilename,event);
+    fTPCStream=new AliTPCRawStream(fReader);
+  }
+#endif
+  AliHLTTPCDigitRowData *data = 0;
+  nrow=0;
+
+  if(!fReader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCDDLDataFileHandler::DDLData2Memory","File")
+    <<"No Input avalible: no object AliHLTTPCDDLRawReaderFile"<<ENDLOG;
+    return 0; 
+  }
+  
+  Int_t nrows=fRowMax-fRowMin+1;
+  Int_t ndigitcount=0;
+  Int_t * ndigits = new Int_t[nrows];
+  UShort_t ***charges=new UShort_t**[nrows];
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t lrow=r-fRowMin;
+    charges[lrow]=new UShort_t*[AliHLTTPCTransform::GetNPads(r)];
+    for(Int_t k=0;k<AliHLTTPCTransform::GetNPads(r);k++){
+      charges[lrow][k]=new UShort_t[AliHLTTPCTransform::GetNTimeBins()];
+      for(Int_t j=0;j<AliHLTTPCTransform::GetNTimeBins();j++) charges[lrow][k][j]=0;
+    }
+  }
+
+  Int_t ddlsToSearch=0;
+  Int_t ddls[9]={-1,-1,-1,-1,-1,-1,-1,-1,-1};
+  Int_t ddlid=-1,lddlid=-1;
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    ndigits[r-fRowMin] = 0; //now digits on row
+
+    Int_t patch=AliHLTTPCTransform::GetPatch(r);
+    Int_t sector,row;
+    AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+
+    if(sector<36) //taken from AliTPCBuffer160.cxx
+      ddlid=sector*2+patch;
+    else
+      ddlid=70+(sector-36)*4+patch;
+
+    if((lddlid!=ddlid-1)&&(r==30)){ //dont forget the split row on the last ddl
+      ddls[ddlsToSearch++]=ddlid-1;    
+      lddlid=ddlid-1;
+    }
+
+    if((lddlid==-1)||(ddlid!=lddlid)){
+      ddls[ddlsToSearch++]=ddlid;
+      lddlid=ddlid;
+    }
+    if((r==90)||(r==139)){ //dont forget the split row on the next ddl
+      ddls[ddlsToSearch++]=ddlid+1;    
+      lddlid=ddlid+1;
+    }
+  }
+
+  //  for(Int_t i=0;i<ddlsToSearch;i++) cout << ddls[i] <<endl;
+
+  if(ddls[0]>ddls[ddlsToSearch-1]) {
+    Int_t tempddl = ddls[0];
+    ddls[0] = ddls[ddlsToSearch-1];
+    ddls[ddlsToSearch-1] = tempddl;
+  }
+#ifdef use_newio
+    fReader->Reset();
+    fReader->Select(0,ddls[0],ddls[ddlsToSearch-1]);
+    fTPCStream->Reset();
+#else
+    fTPCStream->SetDDLID(ddls[i]); //ddl to read out
+#endif
+    Int_t zerosup = AliHLTTPCTransform::GetZeroSup();
+    Int_t adcsat = AliHLTTPCTransform::GetADCSat();
+    Int_t slice,srow;
+    Int_t lrow=-1;
+
+    while (fTPCStream->Next()){
+
+      if(fTPCStream->IsNewSector() || fTPCStream->IsNewRow()) {
+       Int_t sector=fTPCStream->GetSector();
+       Int_t row=fTPCStream->GetRow();
+       AliHLTTPCTransform::Sector2Slice(slice,srow,sector,row);
+       if(slice!=fSlice){
+         LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Slice")
+           <<AliHLTTPCLog::kDec<<"Found slice "<<slice<<", expected "<<fSlice<<ENDLOG;
+         continue;
+       }
+       lrow=srow-fRowMin;
+      }
+
+      //test row criteria (patch boundaries)
+      if((srow<fRowMin)||(srow>fRowMax))continue;
+
+      Int_t pad=fTPCStream->GetPad();
+      if(fTPCStream->IsNewPad()) {
+       if((pad<0)||(pad>=AliHLTTPCTransform::GetNPads(srow))){
+         LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Pad")
+           <<AliHLTTPCLog::kDec<<"Pad value out of bounds "<<pad<<" "
+           <<AliHLTTPCTransform::GetNPads(srow)<<ENDLOG;
+         continue;
+       }
+      }
+
+      Int_t time=fTPCStream->GetTime();
+      if((time<0)||(time>=AliHLTTPCTransform::GetNTimeBins())){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Time")
+         <<AliHLTTPCLog::kDec<<"Time out of bounds "<<time<<" "
+         <<AliHLTTPCTransform::GetNTimeBins()<<ENDLOG;
+       continue;
+      }
+
+      //store digit
+      UShort_t dig=fTPCStream->GetSignal();
+      if(dig <= zerosup) continue;
+      if(dig >= adcsat) dig = adcsat;
+
+      ndigits[lrow]++; //for this row only
+      ndigitcount++;   //total number of digits to be published
+
+      charges[lrow][pad][time]=dig;
+    }
+
+  Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+    + nrows*sizeof(AliHLTTPCDigitRowData);
+
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Digits")
+    <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+  
+  data=(AliHLTTPCDigitRowData*) Allocate(size);
+  nrow = (UInt_t)nrows;
+  AliHLTTPCDigitRowData *tempPt = data;
+
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t lrow=r-fRowMin;
+    tempPt->fRow = r;
+    tempPt->fNDigit = ndigits[lrow];
+  
+    Int_t localcount=0;
+    for(Int_t pad=0;pad<AliHLTTPCTransform::GetNPads(r);pad++){
+      for(Int_t time=0;time<AliHLTTPCTransform::GetNTimeBins();time++){
+       UShort_t dig=charges[lrow][pad][time];
+       if(!dig) continue;
+
+       if(localcount >= ndigits[lrow])
+         LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLDataFileHandler::DDLDigits2Binary","Memory")
+           <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+           <<ndigits[lrow]<<ENDLOG;
+       
+
+       tempPt->fDigitData[localcount].fCharge=dig;
+       tempPt->fDigitData[localcount].fPad=pad;
+       tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+       tempPt->fDigitData[localcount].fTrackID[0] = 0;
+       tempPt->fDigitData[localcount].fTrackID[1] = 0;
+       tempPt->fDigitData[localcount].fTrackID[2] = 0;
+#endif
+       localcount++;
+      }
+    }
+
+    if(localcount != ndigits[lrow])
+      LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLDataFileHandler::DDLDigits2Binary","Memory")
+       <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+       <<ndigits[lrow]<<ENDLOG;
+
+
+    Byte_t *tmp = (Byte_t*)tempPt;
+    Int_t size = sizeof(AliHLTTPCDigitRowData)
+                                      + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
+    tmp += size;
+    tempPt = (AliHLTTPCDigitRowData*)tmp;
+  }
+
+  //delete charge array
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t lrow=r-fRowMin;
+    for(Int_t k=0;k<AliHLTTPCTransform::GetNPads(r);k++)
+       delete charges[lrow][k];
+    delete charges[lrow];
+  }
+  delete charges;
+  delete [] ndigits;
+
+  return data;
+}
+#else
+AliHLTTPCDigitRowData * AliHLTTPCDDLDataFileHandler::DDLData2Memory(UInt_t &nrow,Int_t event)
+{
+  // transfers the DDL data to the memory
+#ifdef use_newio
+  if((fEvent>=0)&&(event!=fEvent)){
+    fEvent=event;
+    if(fReader) delete fReader;
+    if(fTPCStream) delete fTPCStream;
+    fReader=new AliRawReaderRoot(fFilename,event);
+    fTPCStream=new AliTPCRawStream(fReader);
+  }
+#endif
+  AliHLTTPCDigitRowData *data = 0;
+  nrow=0;
+
+  if(!fReader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCDDLDataFileHandler::DDLData2Memory","File")
+    <<"No Input avalible: no object AliHLTTPCDDLRawReaderFile"<<ENDLOG;
+    return 0; 
+  }
+  
+  Int_t nrows=fRowMax-fRowMin+1;
+
+  Int_t ddlsToSearch=0;
+  Int_t ddls[9]={-1,-1,-1,-1,-1,-1,-1,-1,-1};
+  Int_t ddlid=-1,lddlid=-1;
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+
+    Int_t patch=AliHLTTPCTransform::GetPatch(r);
+    Int_t sector,row;
+    AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+
+    if(sector<36) //taken from AliTPCBuffer160.cxx
+      ddlid=sector*2+patch;
+    else
+      ddlid=70+(sector-36)*4+patch;
+
+    if((lddlid==-1)||(ddlid!=lddlid)){
+      ddls[ddlsToSearch++]=ddlid;
+      lddlid=ddlid;
+    }
+  }
+
+  //  for(Int_t i=0;i<ddlsToSearch;i++) cout << ddls[i] <<endl;
+
+#ifdef use_newio
+  fReader->Reset();
+  fReader->Select(0,ddls[0],ddls[ddlsToSearch-1]);
+  fTPCStream->Reset();
+#else
+  fTPCStream->SetDDLID(ddls[i]); //ddl to read out
+#endif
+
+  nrow = (UInt_t)nrows;
+
+  return data;
+}
+#endif
+
+Bool_t AliHLTTPCDDLDataFileHandler::DDLData2CompBinary(Int_t event)
+{
+  // transfers the DDL data to the memory and converts it 
+  // to comp binary 
+  Bool_t out = kTRUE;
+  UInt_t ndigits=0;
+  AliHLTTPCDigitRowData *digits=0;
+  digits = DDLData2Memory(ndigits,event);
+  out = Memory2CompBinary(ndigits,digits);
+  Free();
+  return out;
+}
diff --git a/HLT/TPCLib/AliHLTTPCDDLDataFileHandler.h b/HLT/TPCLib/AliHLTTPCDDLDataFileHandler.h
new file mode 100644 (file)
index 0000000..d90cf5f
--- /dev/null
@@ -0,0 +1,55 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLDATAFILEHANDLER_H
+#define ALIHLTTPCDDLDATAFILEHANDLER_H
+
+#ifdef use_newio
+#include "../RAW/AliRawEvent.h"
+#include "../RAW/AliRawReader.h"
+#include "../RAW/AliTPCRawStream.h"
+#include <TString.h>
+#else
+#include "AliHLTTPCDDLRawReaderFile.h"
+#include "AliHLTTPCDDLTPCRawStream.h"
+#endif
+#include "AliHLTTPCMemHandler.h"
+
+class AliHLTTPCDDLDataFileHandler:public AliHLTTPCMemHandler{
+  public:
+
+   AliHLTTPCDDLDataFileHandler();
+   virtual ~AliHLTTPCDDLDataFileHandler();
+
+#ifdef use_newio
+   Bool_t SetReaderInput(AliRawEvent *rawevent);
+   Bool_t SetReaderInput(Char_t *name,Int_t event=0);
+   Bool_t IsDigit(Int_t i=0) const;
+   AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & nrow,Int_t event=0,Bool_t /*eventmerge*/=kFALSE){return DDLData2Memory(nrow,event);};
+#else
+   Bool_t SetReaderInput(Char_t *name,Bool_t add=kTRUE);
+   Bool_t SetReaderInput(AliHLTTPCDDLRawReaderFile *rf);
+#endif
+
+   void CloseReaderInput();
+   void FreeAll(); //like AliHLTTPCMemHandler::Free() or AliHLTTPCFileHandler::FreeDigitsTree
+
+   AliHLTTPCDigitRowData* DDLData2Memory(UInt_t &nrow,Int_t event=-1);
+   Bool_t DDLData2CompBinary(Int_t event=-1);
+
+   AliTPCRawStream* GetTPCRawStream(){return fTPCStream;}
+
+  private:
+#ifdef use_newio
+   TString          fFilename; // IO file name
+   Int_t            fEvent;    // event number
+   AliRawReader    *fReader;   // raw reader
+   AliTPCRawStream *fTPCStream;// TPC raw stream
+#else
+   AliHLTTPCDDLRawReaderFile *fReader; // raw reader
+   AliHLTTPCDDLTPCRawStream *fTPCStream; // TPC raw stream
+#endif
+
+   ClassDef(AliHLTTPCDDLDataFileHandler,1)   //DDL Data Filehandler class
+};
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCDataCompressorHelper.cxx b/HLT/TPCLib/AliHLTTPCDataCompressorHelper.cxx
new file mode 100644 (file)
index 0000000..b3d2dce
--- /dev/null
@@ -0,0 +1,170 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCTransform.h"
+
+#include "AliHLTTPCDataCompressorHelper.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+//_____________________________________________________________
+//
+//  AliHLTTPCDataCompression
+//
+// Interface class; binary <-> AliROOT handling of TPC data compression classes.
+//
+
+
+ClassImp(AliHLTTPCDataCompressorHelper)
+
+
+Int_t AliHLTTPCDataCompressorHelper::fgNumTimeBits = 12;
+Int_t AliHLTTPCDataCompressorHelper::fgNumPadBits = 12;
+Int_t AliHLTTPCDataCompressorHelper::fgNumChargeBits = 14;
+Int_t AliHLTTPCDataCompressorHelper::fgNumShapeBits = 14;
+Float_t AliHLTTPCDataCompressorHelper::fgXYResidualStep1 = 0.03;
+Float_t AliHLTTPCDataCompressorHelper::fgXYResidualStep2 = 0.03;
+Float_t AliHLTTPCDataCompressorHelper::fgXYResidualStep3 = 0.03;
+Float_t AliHLTTPCDataCompressorHelper::fgZResidualStep1 = 0.05;
+Float_t AliHLTTPCDataCompressorHelper::fgZResidualStep2 = 0.05;
+Float_t AliHLTTPCDataCompressorHelper::fgZResidualStep3 = 0.05;
+Float_t AliHLTTPCDataCompressorHelper::fgXYWidthStep = 0.005;
+Float_t AliHLTTPCDataCompressorHelper::fgZWidthStep = 0.005;
+Int_t AliHLTTPCDataCompressorHelper::fgClusterCharge = 100;
+Int_t AliHLTTPCDataCompressorHelper::fgNumPadBitsRemaining = 18;
+Int_t AliHLTTPCDataCompressorHelper::fgNumTimeBitsRemaining = 19;
+Int_t AliHLTTPCDataCompressorHelper::fgNumShapeBitsRemaining = 11;
+
+void AliHLTTPCDataCompressorHelper::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
+{
+  // sets the numbers of bits
+  fgNumPadBits = pad;
+  fgNumTimeBits = time;
+  fgNumChargeBits = charge;
+  fgNumShapeBits = shape;
+}
+
+void AliHLTTPCDataCompressorHelper::SetTransverseResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width)
+{
+  // sets the transverse resolution
+  fgXYResidualStep1 = res1;
+  fgXYResidualStep2 = res2;
+  fgXYResidualStep3 = res3;
+  fgXYWidthStep = width;
+}
+
+void AliHLTTPCDataCompressorHelper::SetLongitudinalResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width)
+{
+  // sets the longitudinal resolution
+  fgZResidualStep1 = res1;
+  fgZResidualStep2 = res2;
+  fgZResidualStep3 = res3;
+  fgZWidthStep = width;
+}
+
+void AliHLTTPCDataCompressorHelper::SetRemainingBitNumbers(Int_t pad,Int_t time,Int_t shape)
+{
+  // sets the numbers of remaining bits
+  fgNumPadBitsRemaining = pad;
+  fgNumTimeBitsRemaining = time;
+  fgNumShapeBitsRemaining = shape;
+}
+
+Float_t AliHLTTPCDataCompressorHelper::GetXYResidualStep(Int_t row) 
+{
+  // gets the XY residual step
+  if(row < AliHLTTPCTransform::GetNRowLow())
+    return fgXYResidualStep1;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1())
+    return fgXYResidualStep2;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1() + AliHLTTPCTransform::GetNRowUp2())
+    return fgXYResidualStep3;
+  else
+    {
+      cerr<<"AliHLTTPCDataCompressorHelper::GetXYResidualStep : Wrong row number "<<row<<endl;
+      return -1;
+    }
+}
+
+Float_t AliHLTTPCDataCompressorHelper::GetZResidualStep(Int_t row) 
+{
+  // gets the Z residual step
+  if(row < AliHLTTPCTransform::GetNRowLow())
+    return fgZResidualStep1;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1())
+    return fgZResidualStep2;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1() + AliHLTTPCTransform::GetNRowUp2())
+    return fgZResidualStep3;
+  else
+    {
+      cerr<<"AliHLTTPCDataCompressorHelper::GetXYResidualStep : Wrong row number "<<row<<endl;
+      return -1;
+    }
+}
+
+Float_t AliHLTTPCDataCompressorHelper::GetPadPrecisionFactor()
+{
+  // gets pad precision factor
+  Int_t nbits = fgNumPadBitsRemaining;
+  if(nbits >=21)
+    return 10000;
+  if(nbits >= 18)
+    return 1000;
+  if(nbits >= 14) 
+    return 100;
+  if(nbits >= 11)
+    return 10;
+  if(nbits >= 8)
+    return 1;
+  else 
+    {
+      cerr<<"AliHLTTPCDataCompressorHelper::GetRemainingPadFactor : Too few bits for the pad direction: "<<nbits<<endl;
+      return 1;
+    }
+}
+
+Float_t AliHLTTPCDataCompressorHelper::GetTimePrecisionFactor()
+{
+  // gest time precision factor
+  Int_t nbits = fgNumTimeBitsRemaining;
+  if(nbits >=23)
+    return 10000;
+  if(nbits >= 19)
+    return 1000;
+  if(nbits >= 16) 
+    return 100;
+  if(nbits >= 13)
+    return 10;
+  if(nbits >= 9)
+    return 1;
+  else 
+    {
+      cerr<<"AliHLTTPCDataCompressorHelper::GetRemainingPadFactor : Too few bits for the pad direction: "<<nbits<<endl;
+      return 1;
+    }
+}
+
+
+Int_t AliHLTTPCDataCompressorHelper::Nint(Double_t x)
+{
+   // Round to nearest integer. Rounds half integers 
+   // to the nearest even integer.
+
+   Int_t i=0;
+   if (x >= 0) {
+      i = Int_t(x + 0.5);
+      if (x + 0.5 == Double_t(i) && i & 1) i--;
+   } else {
+      i = Int_t(x - 0.5);
+      if (x - 0.5 == Double_t(i) && i & 1) i++;
+
+   }
+   return i;
+}
diff --git a/HLT/TPCLib/AliHLTTPCDataCompressorHelper.h b/HLT/TPCLib/AliHLTTPCDataCompressorHelper.h
new file mode 100644 (file)
index 0000000..8eabb44
--- /dev/null
@@ -0,0 +1,61 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_DataCompressorHelper
+#define AliHLTTPC_DataCompressorHelper
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCDataCompressorHelper {
+  
+ public:
+  virtual ~AliHLTTPCDataCompressorHelper() {}
+
+  static void SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape);
+  static void SetTransverseResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width=0.005);
+  static void SetLongitudinalResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width=0.005);
+  static void SetRemainingBitNumbers(Int_t pad,Int_t time,Int_t shape);
+  static Int_t GetNPadBits() {return fgNumPadBits;}
+  static Int_t GetNTimeBits() {return fgNumTimeBits;}
+  static Int_t GetNChargeBits() {return fgNumChargeBits;}
+  static Int_t GetNShapeBits() {return fgNumShapeBits;}
+  static Float_t GetXYWidthStep() {return fgXYWidthStep;}
+  static Float_t GetZWidthStep() {return fgZWidthStep;}
+  static Int_t GetClusterCharge() {return fgClusterCharge;}
+  static Float_t GetXYResidualStep(Int_t row);
+  static Float_t GetZResidualStep(Int_t row);
+  static Int_t GetNPadBitsRemaining() {return fgNumPadBitsRemaining;}
+  static Int_t GetNTimeBitsRemaining() {return fgNumTimeBitsRemaining;}
+  static Int_t GetNShapeBitsRemaining() {return fgNumShapeBitsRemaining;}
+  static Float_t GetPadPrecisionFactor();
+  static Float_t GetTimePrecisionFactor();
+
+  //taken from TMath
+  static Int_t Nint(Double_t x); 
+  static Int_t Abs(Int_t d) { return (d > 0) ? d : -d; }
+  static Double_t Abs(Double_t d) { return (d > 0) ? d : -d; }
+
+ private:
+  static Int_t fgNumPadBits; // Number of pad bits
+  static Int_t fgNumTimeBits; // Number of time bits
+  static Int_t fgNumChargeBits; // Number of charge bits
+  static Int_t fgNumShapeBits; // Number of shape bits
+  static Int_t fgNumPadBitsRemaining; // Number of remaining pad bits
+  static Int_t fgNumTimeBitsRemaining; // Number of remaining time bits
+  static Int_t fgNumShapeBitsRemaining; // Number of remaining shape bits
+
+  static Float_t fgXYResidualStep1; // XY resbual at step 1
+  static Float_t fgXYResidualStep2; // XY residual at step 2
+  static Float_t fgXYResidualStep3; // XY resudual at step 3
+  static Float_t fgZResidualStep1; // Z residual at step 1
+  static Float_t fgZResidualStep2; // Z resudual at step 2
+  static Float_t fgZResidualStep3; // Z resudual at step 3
+  static Float_t fgXYWidthStep; // Width of XY step
+  static Float_t fgZWidthStep;  // Width of Z step
+  static Int_t fgClusterCharge; // Cluster charge
+
+
+  ClassDef(AliHLTTPCDataCompressorHelper,1) 
+
+};
+
+#endif
index 96d3261..f58852b 100644 (file)
@@ -20,18 +20,34 @@ class AliHLTTPCDefinitions
                {
                return (AliHLTUInt8_t)( (block.fSpecification & 0x00FF0000) >> 16 );
                }
+       static AliHLTUInt8_t GetMinSliceNr( ULong_t spec )
+               {
+               return (AliHLTUInt8_t)( (spec & 0x00FF0000) >> 16 );
+               }
        static AliHLTUInt8_t GetMaxSliceNr( const AliHLTComponent_BlockData& block )
                {
                return (AliHLTUInt8_t)( (block.fSpecification & 0xFF000000) >> 24 );
                }
+       static AliHLTUInt8_t GetMaxSliceNr( ULong_t spec )
+               {
+               return (AliHLTUInt8_t)( (spec & 0xFF000000) >> 24 );
+               }
        static AliHLTUInt8_t GetMinPatchNr( const AliHLTComponent_BlockData& block )
                {
                return (AliHLTUInt8_t)( (block.fSpecification & 0x000000FF) );
                }
+       static AliHLTUInt8_t GetMinPatchNr( ULong_t spec )
+               {
+               return (AliHLTUInt8_t)( (spec & 0x000000FF) );
+               }
        static AliHLTUInt8_t GetMaxPatchNr( const AliHLTComponent_BlockData& block )
                {
                return (AliHLTUInt8_t)( (block.fSpecification & 0x0000FF00) >> 8 );
                }
+       static AliHLTUInt8_t GetMaxPatchNr( ULong_t spec )
+               {
+               return (AliHLTUInt8_t)( (spec & 0x0000FF00) >> 8 );
+               }
        
        static AliHLTUInt32_t EncodeDataSpecification( AliHLTUInt8_t minSliceNr, 
                                                AliHLTUInt8_t maxSliceNr,
diff --git a/HLT/TPCLib/AliHLTTPCDigitData.h b/HLT/TPCLib/AliHLTTPCDigitData.h
new file mode 100644 (file)
index 0000000..5cc72ae
--- /dev/null
@@ -0,0 +1,42 @@
+// @(#) $Id$
+
+#ifndef _ALIHLTTPCDIGITDATA_H_
+#define _ALIHLTTPCDIGITDATA_H_
+
+#include "AliHLTTPCRootTypes.h" 
+
+struct AliHLTTPCDigitData
+{
+#ifdef do_mc
+  Int_t fTrackID[3];
+#endif
+  UShort_t fCharge;
+  UChar_t fPad;
+  UShort_t fTime;
+#ifdef IA64
+  UChar_t dummy1;
+  UChar_t dummy2;
+#endif
+};
+typedef struct AliHLTTPCDigitData AliHLTTPCDigitData;
+
+struct AliHLTTPCDigitRowData
+{
+  UInt_t fNDigit;
+  UInt_t fRow;
+#if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC)
+  AliHLTTPCDigitData fDigitData[1];
+#else
+  AliHLTTPCDigitData fDigitData[0];
+#endif
+};
+typedef struct AliHLTTPCDigitRowData AliHLTTPCDigitRowData;
+
+struct AliHLTTPCRandomDigitData{
+  UChar_t fRow;
+  UShort_t fCharge;
+  UChar_t fPad;
+  UShort_t fTime;
+};
+typedef struct AliHLTTPCRandomDigitData AliHLTTPCRandomDigitData;
+#endif /* _ALIHLTTPCDIGITDATA_H_ */
diff --git a/HLT/TPCLib/AliHLTTPCDisplay.cxx b/HLT/TPCLib/AliHLTTPCDisplay.cxx
new file mode 100644 (file)
index 0000000..4f5586e
--- /dev/null
@@ -0,0 +1,557 @@
+// @(#) $Id$
+
+/** \class AliHLTTPCDisplay
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDisplay
+//
+// Simple display class for the HLT tracks.
+</pre>
+*/
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group 
+
+#include "AliHLTTPCStandardIncludes.h"
+#include <TView.h>
+#include <TPolyMarker3D.h>
+#include <TPolyLine3D.h>
+#include <TH2.h>
+#include <TTree.h>
+#include <TNode.h>
+#include <TGeometry.h>
+#include <TShape.h>
+#include <TParticle.h>
+#include <TFile.h>
+#ifdef use_aliroot
+#include <TClonesArray.h>
+#include <AliRun.h>
+#include <AliSimDigits.h>
+#include <AliTPCParam.h>
+#endif
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCDisplay.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if __GNUC__ == 3
+using namespace std;
+#endif
+
+
+ClassImp(AliHLTTPCDisplay)
+
+AliHLTTPCDisplay::AliHLTTPCDisplay()
+{
+  //constructor
+  fGeom = NULL;
+  fTracks = NULL;
+  fc1 = new TCanvas("c1","",700,700);
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+  memset(fNcl, 0, 36*6*sizeof(UInt_t));
+}
+
+AliHLTTPCDisplay::AliHLTTPCDisplay(Int_t *slice,Char_t *gfile)
+{
+  //ctor. Specify which slices you want to look at.
+  LoadGeometrie(gfile);
+  if (slice) {
+    SetSlices(slice[0], slice[1]);
+  }
+
+  fc1 = new TCanvas("c1","",700,700);
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+  memset(fNcl, 0, 36*6*sizeof(UInt_t));
+}
+
+AliHLTTPCDisplay::~AliHLTTPCDisplay()
+{
+  //destructor
+  if(fTracks)
+    delete fTracks;
+  if (fc1)
+    delete fc1;
+}
+
+Bool_t AliHLTTPCDisplay::SetSlices(Int_t minslice, Int_t maxslice) {
+  fMinSlice = minslice;
+  fMaxSlice = maxslice;
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDisplay::LoadGeometrie(Char_t *gfile)
+{
+  if (gfile) {
+  TFile *file = TFile::Open(gfile);
+  if(!file)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::AliHLTTPCDisplay","File Open")
+       <<"Geometry file " << gfile << " does not exist!"<<ENDLOG;
+      return kFALSE;
+    }
+  
+  fGeom = (TGeometry*)file->Get("AliceGeom");
+
+  file->Close();
+  delete file;
+  }
+  return kTRUE;
+}
+
+void AliHLTTPCDisplay::SetupClusterDataForPatch(Int_t slice, Int_t patch, UInt_t nofClusters, AliHLTTPCSpacePointData* data)
+{
+  if (data && slice>=0 && slice<36 && patch>=0 && patch<AliHLTTPCTransform::GetNPatches()) {
+    if (fClusters[slice][patch]!=NULL) {
+      delete(fClusters[slice][patch]);
+      fClusters[slice][patch]=NULL;
+    }
+    Int_t arraysize=nofClusters*sizeof(AliHLTTPCSpacePointData);
+    fClusters[slice][patch] = (AliHLTTPCSpacePointData*)new Byte_t[arraysize];
+    if (fClusters[slice][patch]) {
+      memcpy(fClusters[slice][patch], data, arraysize);
+      fNcl[slice][patch]=nofClusters;
+    } else {
+      fNcl[slice][patch]=nofClusters;
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::SetupClusterDataForPatch","memory allocation")
+       <<"mmemory allocation failed "<<ENDLOG; 
+    }
+  } else {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::SetupClusterDataForPatch","argument check")
+      <<"invalid argument "<<ENDLOG; 
+  } 
+}
+
+void AliHLTTPCDisplay::Setup(Char_t *trackfile,Char_t *path,Int_t event,Bool_t sp)
+{
+  //Read in the hit and track information from produced files.
+  
+  Char_t fname[256];
+  AliHLTTPCMemHandler *clusterfile[36][6];
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+  for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+    {
+      for(Int_t p=0; p<AliHLTTPCTransform::GetNPatches(); p++)
+       {
+         Int_t patch;
+         if(sp==kTRUE)
+           patch=-1;
+         else
+           patch=p;
+         clusterfile[s][p] = new AliHLTTPCMemHandler();
+         if(event<0)
+           sprintf(fname,"%s/points_%d_%d.raw",path,s,patch);
+         else
+           sprintf(fname,"%s/points_%d_%d_%d.raw",path,event,s,patch);
+         if(!clusterfile[s][p]->SetBinaryInput(fname))
+           {
+             LOG(AliHLTTPCLog::kError,"AliHLTTPCEvaluation::Setup","File Open")
+               <<"Inputfile "<<fname<<" does not exist"<<ENDLOG; 
+             delete clusterfile[s][p];
+              clusterfile[s][p] = 0; 
+             continue;
+           }
+         fClusters[s][p] = (AliHLTTPCSpacePointData*)clusterfile[s][p]->Allocate();
+         clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+         clusterfile[s][p]->CloseBinaryInput();
+         if(sp==kTRUE)
+           break;
+       }
+    }
+  
+  if(!trackfile) return;
+  AliHLTTPCMemHandler *tfile = new AliHLTTPCMemHandler();
+  if(!tfile->SetBinaryInput(trackfile))
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCEvaluation::Setup","File Open")
+       <<"Inputfile "<<trackfile<<" does not exist"<<ENDLOG; 
+      return;
+    }
+  fTracks = new AliHLTTPCTrackArray();
+  tfile->Binary2TrackArray(fTracks);
+  tfile->CloseBinaryInput();
+  delete tfile;
+
+}
+
+void AliHLTTPCDisplay::DisplayTracks(Int_t minhits,Bool_t x3don,Float_t thr)
+{
+  //Display the found tracks.
+
+  if (!fc1) return;
+  fc1->cd();
+  
+  TView *v = new TView(1);
+  v->SetRange(-430,-560,-430,430,560,1710);
+  fc1->Clear();
+  fc1->SetFillColor(1);
+  fc1->SetTheta(45.);
+  fc1->SetPhi(0.);
+    
+  Int_t ntracks = fTracks->GetNTracks();
+  TPolyLine3D *line = new TPolyLine3D[ntracks];
+  Float_t xcl[176];
+  Float_t ycl[176];
+  Float_t zcl[176];
+  
+  for(Int_t j=0; j<ntracks; j++)
+    {
+      AliHLTTPCTrack *gtrack = fTracks->GetCheckedTrack(j); 
+      if(!gtrack) continue;
+      if((thr>=0)&&(gtrack->GetPt()<thr)) continue;        
+      Int_t nHits = gtrack->GetNHits();
+      UInt_t *hitnum = gtrack->GetHitNumbers();
+      if(nHits < minhits) continue;
+      TPolyMarker3D *pm = new TPolyMarker3D(nHits);
+      Int_t hitcount=0;
+      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;           
+         //cout << h << " id " << pos << endl;
+         AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+         if(slice < fMinSlice || slice > fMaxSlice)
+           continue;
+
+         if(!points) {
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::DisplayTracks","Clusterarray")
+             <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
+           continue;
+         }
+         if(pos>=fNcl[slice][patch]){
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::DisplayTracks","Clusterarray")
+             <<"Pos is too large: pos "<<pos <<" ncl "<<fNcl[slice][patch]<<ENDLOG;
+           continue;
+         }
+
+         Float_t xyztmp[3];
+         xyztmp[0] = points[pos].fX;
+         xyztmp[1] = points[pos].fY;
+         xyztmp[2] = points[pos].fZ;
+                 
+         xcl[h] = xyztmp[0];
+         ycl[h] = xyztmp[1];
+         zcl[h] = xyztmp[2];
+         
+         pm->SetPoint(h,xcl[h],ycl[h],zcl[h]);
+         hitcount++;
+       }
+      if(hitcount==0) continue;
+      pm->SetMarkerColor(2);
+      pm->Draw();
+      TPolyLine3D *currentline = &(line[j]);
+      currentline = new TPolyLine3D(nHits,xcl,ycl,zcl,"");
+      
+      currentline->SetLineColor(4);
+      currentline->Draw("same");
+            
+    }
+  
+  //Take this if you want black&white display for printing.
+  Char_t fname[256];
+  Int_t i;
+  Int_t color = 1;
+  fc1->SetFillColor(10);
+  for(i=0; i<10; i++)
+    {
+      sprintf(fname,"LS0%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+      sprintf(fname,"US0%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+    }
+  for(i=10; i<18; i++)
+    {
+      sprintf(fname,"LS%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+      sprintf(fname,"US%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+    }
+  
+  fGeom->Draw("same");
+  
+  if(x3don) fc1->x3d();
+  
+}
+
+void AliHLTTPCDisplay::DisplayClusters(Bool_t x3don, Float_t* etaRange)
+{
+  //Display all clusters.
+  
+  if (!fc1) return;
+  fc1->cd();
+
+  TView *v = new TView(1);
+  v->SetRange(-430,-560,-430,430,560,1710);
+  fc1->Clear();
+  fc1->SetFillColor(1);
+  fc1->SetTheta(90.);
+  fc1->SetPhi(0.);
+  
+  Int_t processed = 0, discarded = 0;
+  for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+    {
+      for(Int_t p=0;p<6;p++)
+       {
+         AliHLTTPCSpacePointData *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;
+             if ( etaRange )
+                 {
+                 Double_t pointEta = AliHLTTPCTransform::GetEta( xyz );
+                 if ( pointEta<etaRange[0] || pointEta>etaRange[1] )
+                     {
+                     discarded++;
+                     continue;
+                     }
+                 }
+             processed++;
+             //AliHLTTPCTransform::Local2Global(xyz,s);
+             pm->SetPoint(i,xyz[0],xyz[1],xyz[2]); 
+           }
+         pm->SetMarkerColor(2);
+         pm->Draw("");
+       }
+    }
+  printf( "Processed: %d - Discarded: %d\n", processed, discarded );
+  fGeom->Draw("same");
+  fc1->Draw();
+  
+  if(x3don) fc1->x3d(); 
+  fc1->Modified();
+  fc1->Update();
+}
+
+
+void AliHLTTPCDisplay::DisplayAll(Int_t minhits,Bool_t x3don, Float_t* etaRange)
+{
+  //Display tracks & all hits.
+
+  if (!fc1) return;
+  fc1->cd();
+  TView *v = new TView(1);
+  v->SetRange(-430,-560,-430,430,560,1710);
+  fc1->Clear();
+  fc1->SetFillColor(1);
+  fc1->SetTheta(90.);
+  fc1->SetPhi(0.);
+  
+  Int_t processed = 0, discarded = 0;
+  for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
+    {
+      for(Int_t p=0;p<6;p++)
+       {
+         AliHLTTPCSpacePointData *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;
+           if ( etaRange )
+               {
+               Double_t pointEta = AliHLTTPCTransform::GetEta( xyz );
+               if ( pointEta<etaRange[0] || pointEta>etaRange[1] )
+                     {
+                     discarded++;
+                     continue;
+                     }
+               }
+           processed++;
+           
+           pm->SetPoint(i,xyz[0],xyz[1],xyz[2]); 
+           
+         }
+         pm->SetMarkerColor(2);
+         pm->Draw("");
+       }
+    }
+  printf( "Processed: %d - Discarded: %d\n", processed, discarded );
+  
+  Int_t ntracks = fTracks->GetNTracks();
+  TPolyLine3D *line = new TPolyLine3D[ntracks];
+  Float_t xcl[176];
+  Float_t ycl[176];
+  Float_t zcl[176];
+  
+  for(Int_t j=0; j<ntracks; j++)
+    {
+      AliHLTTPCTrack *gtrack = fTracks->GetCheckedTrack(j); 
+      if(!gtrack) continue;        
+      Int_t nHits = gtrack->GetNHits();
+      UInt_t *hitnum = gtrack->GetHitNumbers();
+      if(nHits < minhits) continue;
+      TPolyMarker3D *pm = new TPolyMarker3D(nHits);
+      Int_t hitcount=0;
+      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;           
+         if(slice < fMinSlice || slice > fMaxSlice)
+           continue;
+         
+         AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+         if(!points) {
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::DisplayAll","Clusterarray")
+             <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
+           continue;
+         }
+         if(pos>=fNcl[slice][patch]) {
+           LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::DisplayAll","Clusterarray")
+             <<"Pos is too large: pos "<<pos <<" ncl "<<fNcl[slice][patch]<<ENDLOG;
+           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]);
+         hitcount++;
+       }
+      if(hitcount==0) continue;
+      pm->SetMarkerColor(3);
+      pm->Draw();
+      TPolyLine3D *currentline = &(line[j]);
+      currentline = new TPolyLine3D(nHits,xcl,ycl,zcl,"");
+      currentline->SetLineColor(4);
+      currentline->SetLineWidth(2);
+      currentline->Draw("same");
+    }
+  
+  Char_t fname[256];
+  Int_t i;
+  Int_t color = 1;
+  fc1->SetFillColor(10);
+  for(i=0; i<10; i++)
+    {
+      sprintf(fname,"LS0%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+      sprintf(fname,"US0%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+    }
+  for(i=10; i<18; i++)
+    {
+      sprintf(fname,"LS%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+      sprintf(fname,"US%d",i);
+      fGeom->GetNode(fname)->SetLineColor(color);
+    }
+    
+  fGeom->Draw("same");
+  
+  if(x3don) fc1->x3d();
+}
+
+void AliHLTTPCDisplay::DisplayClusterRow(Int_t slice,Int_t padrow,Char_t *digitsFile,Char_t *type)
+{
+  //Display the found clusters on this row together with the raw data.
+  
+  if (!fc1) return;
+#ifdef use_aliroot
+  TFile *file = new TFile(digitsFile);
+  AliTPCParam *param = (AliTPCParam*)file->Get(AliHLTTPCTransform::GetParamName());
+
+  Char_t dname[100];
+  sprintf(dname,"TreeD_%s_0",AliHLTTPCTransform::GetParamName());
+  TTree *td=(TTree*)file->Get(dname);
+  AliSimDigits da, *digits=&da;
+  td->GetBranch("Segment")->SetAddress(&digits); //Return pointer to branch segment.
+  
+  Int_t sector,row;
+  AliHLTTPCTransform::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);
+  TH2F *histpart = new TH2F("histpart","",npads,0,npads-1,ntimes,0,ntimes-1);
+
+  
+  Int_t sectorsbyrows=(Int_t)td->GetEntries();
+  Int_t i;
+  for (i=0; i<sectorsbyrows; 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);
+    }
+  }
+  
+  /*file->cd();
+  AliRun *gAlice = (AliRun*)file->Get("gAlice");
+  gAlice->GetEvent(0);
+  TClonesArray *fParticles=gAlice->Particles(); 
+  TParticle *part = (TParticle*)fParticles->UncheckedAt(0);
+  AliHLTTPCEvaluate *eval = new AliHLTTPCEvaluate();
+  Float_t xyzcross[3];
+  */
+  
+  for(Int_t p=0;p<6;p++)
+    {
+      AliHLTTPCSpacePointData *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;
+         AliHLTTPCTransform::Global2Raw(xyz,sector,row);
+         //AliHLTTPCTransform::Local2Raw(xyz,sector,row);
+         histfast->Fill(xyz[1],xyz[2],1);
+         
+         
+       }
+      
+    }
+  
+  fc1->cd();
+  histdig->Draw();
+  histfast->SetMarkerColor(2);
+  histfast->SetMarkerStyle(4);
+  histpart->SetMarkerColor(2);
+  histpart->SetMarkerStyle(3);
+
+  histdig->GetXaxis()->SetTitle("Pad #");
+  histdig->GetYaxis()->SetTitle("Timebin #");
+  histdig->Draw(type);
+  histfast->Draw("psame");
+  //histpart->Draw("psame");
+
+#endif
+  return;
+}
diff --git a/HLT/TPCLib/AliHLTTPCDisplay.h b/HLT/TPCLib/AliHLTTPCDisplay.h
new file mode 100644 (file)
index 0000000..e8f8fe4
--- /dev/null
@@ -0,0 +1,56 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDISPLAY_H
+#define ALIHLTTPCDISPLAY_H
+
+/** \class AliHLTTPCDisplay
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDisplay
+//
+// Simple display class for the HLT tracks.
+</pre>
+*/
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group 
+
+#include <TObject.h>
+#include <TCanvas.h>
+class TGeometry;
+class AliHLTTPCSpacePointData;
+class AliHLTTPCTrackArray;
+
+class AliHLTTPCDisplay : public TObject {
+
+ public:
+  AliHLTTPCDisplay();
+  AliHLTTPCDisplay(Int_t *slice, Char_t *gfile="$(ALIHLT_BASEDIR)/geo/alice.geom");
+  virtual ~AliHLTTPCDisplay();
+
+  void Setup(Char_t *trackfile,Char_t *path,Int_t event=-1,Bool_t sp=kFALSE);
+  void SetupClusterDataForPatch(Int_t slice, Int_t patch, UInt_t nofClusters, AliHLTTPCSpacePointData* data);
+  Bool_t SetSlices(Int_t minslice, Int_t maxslice);
+  Bool_t LoadGeometrie(Char_t *gfile);
+  void DisplayTracks(Int_t min_hits=10,Bool_t x3don=kTRUE,Float_t thr=0.);
+  void DisplayAll(Int_t min_hits=10,Bool_t x3don=kTRUE,Float_t* etaRange=NULL);
+  void DisplayClusters(Bool_t x3don=kTRUE,Float_t* etaRange=NULL);
+
+  void DisplayClusterRow(Int_t slice,Int_t padrow,Char_t *digitsFile,Char_t *type="hist");
+  void SetTracks(AliHLTTPCTrackArray *tracks) {fTracks=tracks;}
+
+ private:
+  AliHLTTPCDisplay(const AliHLTTPCDisplay &/*d*/):TObject(){;}
+  AliHLTTPCDisplay& operator=(const AliHLTTPCDisplay &/*d*/){return *this;}
+
+  TGeometry *fGeom; //!
+  AliHLTTPCSpacePointData *fClusters[36][6]; //!
+  AliHLTTPCTrackArray *fTracks; //!
+  UInt_t fNcl[36][6]; //number of cluster
+  Int_t fMinSlice; //min slice
+  Int_t fMaxSlice; //max slice
+  TCanvas *fc1;
+  ClassDef(AliHLTTPCDisplay,1) //Display class
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCFileHandler.cxx b/HLT/TPCLib/AliHLTTPCFileHandler.cxx
new file mode 100644 (file)
index 0000000..cbf89bb
--- /dev/null
@@ -0,0 +1,1330 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>, C. Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group 
+
+#include "AliHLTTPCStandardIncludes.h"
+#include <TClonesArray.h>
+#include <TSystem.h>
+#include <TMath.h>
+
+#ifdef use_newio
+#include <AliRunLoader.h>
+#endif
+#include <AliTPCParamSR.h>
+#include <AliTPCDigitsArray.h>
+#include <AliTPCClustersArray.h>
+#include <AliTPCcluster.h>
+#include <AliTPCClustersRow.h>
+#include <AliSimDigits.h>
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCFileHandler.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+/** \class AliHLTTPCFileHandler
+<pre>
+//_____________________________________________________________
+// AliHLTTPCFileHandler
+//
+// The HLT ROOT <-> binary files handling class
+//
+// This class provides the interface between AliROOT files,
+// and HLT binary files. It should be used for converting 
+// TPC data stored in AliROOT format (outputfile from a simulation),
+// into the data format currently used by in the HLT framework. 
+// This enables the possibility to always use the same data format, 
+// whether you are using a binary file as an input, or a AliROOT file.
+//
+// For example on how to create binary files from a AliROOT simulation,
+// see example macro exa/Binary.C.
+//
+// For reading a AliROOT file into HLT format in memory, do the following:
+//
+// AliHLTTPCFileHandler file;
+// file.Init(slice,patch);
+// file.SetAliInput("galice.root");
+// AliHLTTPCDigitRowData *dataPt = (AliHLTTPCDigitRowData*)file.AliDigits2Memory(nrows,eventnr);
+// 
+// All the data are then stored in memory and accessible via the pointer dataPt.
+// Accesing the data is then identical to the example 1) showed in AliHLTTPCMemHandler class.
+//
+// For converting the data back, and writing it to a new AliROOT file do:
+//
+// AliHLTTPCFileHandler file;
+// file.Init(slice,patch);
+// file.SetAliInput("galice.root");
+// file.Init(slice,patch,NumberOfRowsInPatch);
+// file.AliDigits2RootFile(dataPt,"new_galice.root");
+// file.CloseAliInput();
+</pre>
+*/
+
+ClassImp(AliHLTTPCFileHandler)
+
+// of course on start up the index is not created
+Bool_t AliHLTTPCFileHandler::fgStaticIndexCreated=kFALSE;
+Int_t  AliHLTTPCFileHandler::fgStaticIndex[36][159]; 
+
+void AliHLTTPCFileHandler::CleanStaticIndex() 
+{ 
+  // use this static call to clean static index after
+  // running over one event
+  for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+    for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+      fgStaticIndex[i][j]=-1;
+  }
+  fgStaticIndexCreated=kFALSE;
+}
+
+Int_t AliHLTTPCFileHandler::SaveStaticIndex(Char_t *prefix,Int_t event) 
+{ 
+  // use this static call to store static index after
+  if(!fgStaticIndexCreated) return -1;
+
+  Char_t fname[1024];
+  if(prefix)
+    sprintf(fname,"%s-%d.txt",prefix,event);
+  else
+    sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
+
+  ofstream file(fname,ios::trunc);
+  if(!file.good()) return -1;
+
+  for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+    for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+      file << fgStaticIndex[i][j] << " ";
+    file << endl;
+  }
+  file.close();
+  return 0;
+}
+
+Int_t AliHLTTPCFileHandler::LoadStaticIndex(Char_t *prefix,Int_t event) 
+{ 
+  // use this static call to store static index after
+  if(fgStaticIndexCreated){
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::LoadStaticIndex","Inxed")
+       <<"Static index already created, will overwrite"<<ENDLOG;
+      CleanStaticIndex();
+  }
+
+  Char_t fname[1024];
+  if(prefix)
+    sprintf(fname,"%s-%d.txt",prefix,event);
+  else
+    sprintf(fname,"TPC.Digits.staticindex-%d.txt",event);
+
+  ifstream file(fname);
+  if(!file.good()) return -1;
+
+  for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+    for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+      file >> fgStaticIndex[i][j];
+  }
+  file.close();
+
+  fgStaticIndexCreated=kTRUE;
+  return 0;
+}
+
+AliHLTTPCFileHandler::AliHLTTPCFileHandler(Bool_t b)
+{
+  //Default constructor
+  fInAli = 0;
+#ifdef use_newio
+  fUseRunLoader = kFALSE;
+#endif
+  fParam = 0;
+  fMC =0;
+  fDigits=0;
+  fDigitsTree=0;
+  fIndexCreated=kFALSE;
+  fUseStaticIndex=b;
+
+  for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++)
+    for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++) 
+      fIndex[i][j]=-1;
+
+  if(fUseStaticIndex&&!fgStaticIndexCreated) CleanStaticIndex();
+}
+
+AliHLTTPCFileHandler::~AliHLTTPCFileHandler()
+{
+  //Destructor
+  if(fMC) CloseMCOutput();
+  FreeDigitsTree();
+  if(fInAli) CloseAliInput();
+}
+
+void AliHLTTPCFileHandler::FreeDigitsTree()
+{ 
+  //free digits tree
+  if(!fDigitsTree)
+    {
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::FreeDigitsTree()","Pointer")
+       <<"Cannot free digitstree, it is not present"<<ENDLOG;
+      return;
+    }
+  delete fDigits;
+  fDigits=0;
+#ifndef use_newio
+  fDigitsTree->Delete();
+#endif
+  fDigitsTree=0;
+
+  for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+    for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+      fIndex[i][j]=-1;
+  }
+  fIndexCreated=kFALSE;
+}
+
+Bool_t AliHLTTPCFileHandler::SetMCOutput(Char_t *name)
+{ 
+  //set mc input
+  fMC = fopen(name,"w");
+  if(!fMC){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
+      <<"Pointer to File = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCFileHandler::SetMCOutput(FILE *file)
+{ 
+  //set mc output
+  fMC = file;
+  if(!fMC){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetMCOutput","File Open")
+      <<"Pointer to File = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+void AliHLTTPCFileHandler::CloseMCOutput()
+{ 
+  //close mc output
+  if(!fMC){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseMCOutPut","File Close")
+      <<"Nothing to Close"<<ENDLOG;
+    return;
+  }
+  fclose(fMC);
+  fMC =0;
+}
+
+Bool_t AliHLTTPCFileHandler::SetAliInput()
+{ 
+  //set ali input
+#ifdef use_newio
+  fInAli->CdGAFile();
+  fParam = (AliTPCParam*)gFile->Get("75x40_100x60_150x60");
+  if(!fParam){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
+      <<"No TPC parameters found in \""<<gFile->GetName()
+      <<"\", creating standard parameters "
+      <<"which might not be what you want!"<<ENDLOG;
+    fParam = new AliTPCParamSR;
+  }
+  if(!fParam){ 
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
+      <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<gFile->GetName()<<ENDLOG;
+    return kFALSE;
+  }
+#else
+  if(!fInAli->IsOpen()){
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
+      <<"Ali File "<<fInAli->GetName()<<" does not exist"<<ENDLOG;
+    return kFALSE;
+  }
+  fParam = (AliTPCParam*)fInAli->Get(AliHLTTPCTransform::GetParamName());
+  if(!fParam){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File")
+      <<"No TPC parameters found in \""<<fInAli->GetName()
+      <<"\", creating standard parameters "
+      <<"which might not be what you want!"<<ENDLOG;
+    fParam = new AliTPCParamSR;
+  }
+  if(!fParam){ 
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::SetAliInput","File Open")
+      <<"No AliTPCParam "<<AliHLTTPCTransform::GetParamName()<<" in File "<<fInAli->GetName()<<ENDLOG;
+    return kFALSE;
+  }
+#endif
+
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCFileHandler::SetAliInput(Char_t *name)
+{ 
+  //Open the AliROOT file with name.
+#ifdef use_newio
+  fInAli= AliRunLoader::Open(name);
+#else
+  fInAli= new TFile(name,"READ");
+#endif
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
+    <<"Pointer to fInAli = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return SetAliInput();
+}
+
+#ifdef use_newio
+Bool_t AliHLTTPCFileHandler::SetAliInput(AliRunLoader *runLoader)
+{ 
+  //set ali input as runloader
+  fInAli=runLoader;
+  fUseRunLoader = kTRUE;
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
+    <<"Pointer to AliRunLoader = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return SetAliInput();
+}
+#endif
+
+#ifdef use_newio
+Bool_t AliHLTTPCFileHandler::SetAliInput(TFile */*file*/)
+{
+  //Specify already opened AliROOT file to use as an input.
+  LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::SetAliInput","File Open")
+    <<"This function is not supported for NEWIO, check ALIHLT_USENEWIO settings in Makefile.conf"<<ENDLOG;
+  return kFALSE;
+}
+#else
+Bool_t AliHLTTPCFileHandler::SetAliInput(TFile *file)
+{ 
+  //Specify already opened AliROOT file to use as an input.
+  fInAli=file;
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::SetAliInput","File Open")
+    <<"Pointer to fInAli = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return SetAliInput();
+}
+#endif
+
+void AliHLTTPCFileHandler::CloseAliInput()
+{ 
+  //close ali input
+#ifdef use_newio
+  if(fUseRunLoader) return;
+#endif
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::CloseAliInput","RunLoader")
+      <<"Nothing to Close"<<ENDLOG;
+    return;
+  }
+#ifndef use_newio
+  if(fInAli->IsOpen()) fInAli->Close();
+#endif
+
+  delete fInAli;
+  fInAli = 0;
+}
+
+Bool_t AliHLTTPCFileHandler::IsDigit(Int_t event)
+{
+  //Check if there is a TPC digit tree in the current file.
+  //Return kTRUE if tree was found, and kFALSE if not found.
+  
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::IsDigit","File")
+    <<"Pointer to fInAli = 0x0 "<<ENDLOG;
+    return kTRUE;  //maybe you are using binary input which is Digits!
+  }
+#ifdef use_newio
+  AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+  if(!tpcLoader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandlerNewIO::IsDigit","File")
+    <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  fInAli->GetEvent(event);
+  tpcLoader->LoadDigits();
+  TTree *t=tpcLoader->TreeD();
+#else
+  Char_t name[1024];
+  sprintf(name,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
+  TTree *t=(TTree*)fInAli->Get(name);
+#endif
+  if(t){
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
+    <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
+    return kTRUE;
+  }
+  else{
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
+    <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
+    return kFALSE;
+  }
+}
+
+///////////////////////////////////////// Digit IO  
+Bool_t AliHLTTPCFileHandler::AliDigits2Binary(Int_t event,Bool_t altro)
+{
+  //save alidigits as binary
+  Bool_t out = kTRUE;
+  UInt_t nrow;
+  AliHLTTPCDigitRowData* data = 0;
+  if(altro)
+    data = AliAltroDigits2Memory(nrow,event);
+  else
+    data = AliDigits2Memory(nrow,event);
+  out = Memory2Binary(nrow,data);
+  Free();
+  return out;
+}
+
+Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
+{
+  //Convert AliROOT TPC data, into HLT data format.
+  //event specifies the event you want in the aliroot file.
+  
+  Bool_t out = kTRUE;
+  UInt_t ndigits=0;
+  AliHLTTPCDigitRowData *digits=0;
+  if(altro)
+    digits = AliAltroDigits2Memory(ndigits,event);
+  else
+    digits = AliDigits2Memory(ndigits,event);
+  out = Memory2CompBinary(ndigits,digits);
+  Free();
+  return out;
+}
+
+Bool_t AliHLTTPCFileHandler::CreateIndex()
+{
+  //create the access index or copy from static index
+  fIndexCreated=kFALSE;
+
+  if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index 
+    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+      <<"Starting to create index, this can take a while."<<ENDLOG;
+
+    for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
+      Int_t sector, row;
+      Int_t lslice,lrow;
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
+         <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
+         <<sector<<" "<<row<<ENDLOG;
+       return kFALSE;
+      }
+      if(fIndex[lslice][lrow]==-1) {
+       fIndex[lslice][lrow]=n;
+      }
+    }
+    if(fUseStaticIndex) { // create static index
+      for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+       for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+         fgStaticIndex[i][j]=fIndex[i][j];
+      }
+      fgStaticIndexCreated=kTRUE; //remember that index has been created
+    }
+
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+    <<"Index successfully created."<<ENDLOG;
+
+  } else if(fUseStaticIndex) { //simply copy static index
+    for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+      for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+       fIndex[i][j]=fgStaticIndex[i][j];
+    }
+
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+    <<"Index successfully taken from static copy."<<ENDLOG;
+  }
+  fIndexCreated=kTRUE;
+  return kTRUE;
+}
+
+AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event)
+{
+  //Read data from AliROOT file into memory, and store it in the HLT data format.
+  //Returns a pointer to the data.
+
+  AliHLTTPCDigitRowData *data = 0;
+  nrow=0;
+  
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
+    <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
+    return 0; 
+  }
+
+#ifndef use_newio
+  if(!fInAli->IsOpen()){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
+    <<"No Input avalible: TFile not opened"<<ENDLOG;
+    return 0;
+  }
+#endif
+
+  if(!fDigitsTree)
+    if(!GetDigitsTree(event)) return 0;
+
+  UShort_t dig;
+  Int_t time,pad,sector,row;
+  Int_t lslice,lrow;
+  Int_t nrows=0;
+  Int_t ndigitcount=0;
+  Int_t entries = (Int_t)fDigitsTree->GetEntries();
+  if(entries==0) {
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
+      <<"No TPC digits (entries==0)!"<<ENDLOG;
+    nrow = (UInt_t)(fRowMax-fRowMin+1);
+    Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
+    data=(AliHLTTPCDigitRowData*) Allocate(size);
+    AliHLTTPCDigitRowData *tempPt = data;
+    for(Int_t r=fRowMin;r<=fRowMax;r++){
+      tempPt->fRow = r;
+      tempPt->fNDigit = 0;
+      tempPt++;
+    }
+    return data;
+  }
+
+  Int_t * ndigits = new Int_t[fRowMax+1];
+  Float_t xyz[3];
+
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t n=fIndex[fSlice][r];
+    if(n!=-1){ //data on that row
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+
+      if(lrow!=r){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
+         <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+       continue;
+      }
+
+      ndigits[lrow] = 0;
+      fDigits->First();
+      do {
+       time=fDigits->CurrentRow();
+       pad=fDigits->CurrentColumn();
+       dig = fDigits->GetDigit(time,pad);
+       if(dig <= fParam->GetZeroSup()) continue;
+       if(dig >= AliHLTTPCTransform::GetADCSat())
+         dig = AliHLTTPCTransform::GetADCSat();
+      
+       AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+       //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+       //        continue; // why 230???
+
+       ndigits[lrow]++; //for this row only
+       ndigitcount++;   //total number of digits to be published
+
+      } while (fDigits->Next());
+      //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
+    }
+    nrows++;
+  }
+
+  Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+    + nrows*sizeof(AliHLTTPCDigitRowData);
+
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
+    <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+  
+  data=(AliHLTTPCDigitRowData*) Allocate(size);
+  nrow = (UInt_t)nrows;
+  AliHLTTPCDigitRowData *tempPt = data;
+
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t n=fIndex[fSlice][r];
+    tempPt->fRow = r;
+    tempPt->fNDigit = 0;
+
+    if(n!=-1){//data on that row
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+      if(lrow!=r){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
+         <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+       continue;
+      }
+
+      tempPt->fNDigit = ndigits[lrow];
+
+      Int_t localcount=0;
+      fDigits->First();
+      do {
+       time=fDigits->CurrentRow();
+       pad=fDigits->CurrentColumn();
+       dig = fDigits->GetDigit(time,pad);
+       if (dig <= fParam->GetZeroSup()) continue;
+       if(dig >= AliHLTTPCTransform::GetADCSat())
+         dig = AliHLTTPCTransform::GetADCSat();
+
+       //Exclude data outside cone:
+       AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+       //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+       //        continue; // why 230???
+
+       if(localcount >= ndigits[lrow])
+         LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
+           <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+           <<ndigits[lrow]<<ENDLOG;
+       
+       tempPt->fDigitData[localcount].fCharge=dig;
+       tempPt->fDigitData[localcount].fPad=pad;
+       tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+       tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
+       tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
+       tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
+#endif
+       localcount++;
+      } while (fDigits->Next());
+    }
+    Byte_t *tmp = (Byte_t*)tempPt;
+    Int_t size = sizeof(AliHLTTPCDigitRowData)
+                                      + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
+    tmp += size;
+    tempPt = (AliHLTTPCDigitRowData*)tmp;
+  }
+  delete [] ndigits;
+  return data;
+}
+
+AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
+{
+  //Read data from AliROOT file into memory, and store it in the HLT data format.
+  //Returns a pointer to the data.
+  //This functions filter out single timebins, which is noise. The timebins which
+  //are removed are timebins which have the 4 zero neighbours; 
+  //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
+  
+  AliHLTTPCDigitRowData *data = 0;
+  nrow=0;
+  
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
+    <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
+    return 0; 
+  }
+#ifndef use_newio
+  if(!fInAli->IsOpen()){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
+    <<"No Input avalible: TFile not opened"<<ENDLOG;
+    return 0;
+  }
+#endif
+  if(eventmerge == kTRUE && event >= 1024)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
+       <<"Too many events if you want to merge!"<<ENDLOG;
+      return 0;
+    }
+  delete fDigits;
+  fDigits=0;
+#ifdef use_newio 
+  /* Dont understand why we have to do 
+     reload the tree, but otherwise the code crashes */
+  fDigitsTree=0;
+  if(!GetDigitsTree(event)) return 0;
+#else
+  if(!fDigitsTree){
+    if(!GetDigitsTree(event)) return 0;
+  }
+#endif
+
+  UShort_t dig;
+  Int_t time,pad,sector,row;
+  Int_t nrows=0;
+  Int_t ndigitcount=0;
+  Int_t entries = (Int_t)fDigitsTree->GetEntries();
+  if(entries==0) {
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
+      <<"No TPC digits (entries==0)!"<<ENDLOG;
+    nrow = (UInt_t)(fRowMax-fRowMin+1);
+    Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
+    data=(AliHLTTPCDigitRowData*) Allocate(size);
+    AliHLTTPCDigitRowData *tempPt = data;
+    for(Int_t r=fRowMin;r<=fRowMax;r++){
+      tempPt->fRow = r;
+      tempPt->fNDigit = 0;
+      tempPt++;
+    }
+    return data;
+  }
+  Int_t * ndigits = new Int_t[fRowMax+1];
+  Int_t lslice,lrow;
+  Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
+  Float_t xyz[3];
+
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t n=fIndex[fSlice][r];
+
+    ndigits[r] = 0;
+
+    if(n!=-1){//data on that row
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+      //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
+      if((lslice!=fSlice)||(lrow!=r)){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
+         <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+       continue;
+      }
+
+      fDigits->ExpandBuffer();
+      fDigits->ExpandTrackBuffer();
+      for(Int_t i=0; i<fDigits->GetNCols(); i++){
+       for(Int_t j=0; j<fDigits->GetNRows(); j++){
+         pad=i;
+         time=j;
+         dig = fDigits->GetDigitFast(time,pad);
+         if(dig <= zerosupval) continue;
+         if(dig >= AliHLTTPCTransform::GetADCSat())
+           dig = AliHLTTPCTransform::GetADCSat();
+
+         //Check for single timebins, and remove them because they are noise for sure.
+         if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
+           if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+              fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+              fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+              fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+             continue;
+             
+         //Boundaries:
+         if(i==0) //pad==0
+           {
+             if(j < fDigits->GetNRows()-1 && j > 0) 
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+                   continue;
+               }
+             else if(j > 0)
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+                   continue;
+               }
+           }
+         if(j==0)
+           {
+             if(i < fDigits->GetNCols()-1 && i > 0)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+                   continue;
+               }
+             else if(i > 0)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+                   continue;
+               }
+           }
+
+         if(i==fDigits->GetNCols()-1)
+           {
+             if(j>0 && j<fDigits->GetNRows()-1)
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+             else if(j==0 && j<fDigits->GetNRows()-1)
+               {
+                 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+             else 
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+           }
+       
+         if(j==fDigits->GetNRows()-1)
+           {
+             if(i>0 && i<fDigits->GetNCols()-1)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+             else if(i==0 && fDigits->GetNCols()-1)
+               {
+                 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+             else 
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+           }
+
+         AliHLTTPCTransform::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
+       }
+      }
+    }
+    nrows++;
+  }
+  
+  Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+    + nrows*sizeof(AliHLTTPCDigitRowData);
+
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
+    <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+  
+  data=(AliHLTTPCDigitRowData*) Allocate(size);
+  nrow = (UInt_t)nrows;
+  AliHLTTPCDigitRowData *tempPt = data;
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t n=fIndex[fSlice][r];
+    tempPt->fRow = r;
+    tempPt->fNDigit = 0;
+    if(n!=-1){ //no data on that row
+      fDigitsTree->GetEvent(n);
+      fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+      AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+
+      if(lrow!=r){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
+         <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+       continue;
+      }
+
+      tempPt->fNDigit = ndigits[lrow];
+
+      Int_t localcount=0;
+      fDigits->ExpandBuffer();
+      fDigits->ExpandTrackBuffer();
+      for(Int_t i=0; i<fDigits->GetNCols(); i++){
+       for(Int_t j=0; j<fDigits->GetNRows(); j++){
+         pad=i;
+         time=j;
+         dig = fDigits->GetDigitFast(time,pad);
+         if(dig <= zerosupval) continue;
+         if(dig >= AliHLTTPCTransform::GetADCSat())
+           dig = AliHLTTPCTransform::GetADCSat();
+             
+         //Check for single timebins, and remove them because they are noise for sure.
+         if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
+           if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+              fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+              fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+              fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+             continue;
+         
+         //Boundaries:
+         if(i==0) //pad ==0
+           {
+             if(j < fDigits->GetNRows()-1 && j > 0) 
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+                   continue;
+               }
+             else if(j > 0)
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+                   continue;
+               }
+           }
+         if(j==0)
+           {
+             if(i < fDigits->GetNCols()-1 && i > 0)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+                   continue;
+               }
+             else if(i > 0)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+                   continue;
+               }
+           }
+       
+         if(i == fDigits->GetNCols()-1)
+           {
+             if(j>0 && j<fDigits->GetNRows()-1)
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+             else if(j==0 && j<fDigits->GetNRows()-1)
+               {
+                 if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+             else 
+               {
+                 if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+                   continue;
+               }
+           }
+         if(j==fDigits->GetNRows()-1)
+           {
+             if(i>0 && i<fDigits->GetNCols()-1)
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+             else if(i==0 && fDigits->GetNCols()-1)
+               {
+                 if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+             else 
+               {
+                 if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+                    fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+                   continue;
+               }
+           }
+       
+         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+         //      if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+         //        continue;
+         
+         if(localcount >= ndigits[lrow])
+           LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
+             <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+             <<ndigits[lrow]<<ENDLOG;
+       
+         tempPt->fDigitData[localcount].fCharge=dig;
+         tempPt->fDigitData[localcount].fPad=pad;
+         tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+         tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
+         tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
+         tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
+         if(eventmerge == kTRUE) //careful track mc info will be touched
+           {//Event are going to be merged, so event number is stored in the upper 10 bits.
+             tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
+             tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
+             tempPt->fDigitData[localcount].fTrackID[2] += 128;
+             tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
+             tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
+             tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
+           }
+#endif
+         localcount++;
+       }
+      }
+    }
+    Byte_t *tmp = (Byte_t*)tempPt;
+    Int_t size = sizeof(AliHLTTPCDigitRowData)
+      + ndigits[r]*sizeof(AliHLTTPCDigitData);
+    tmp += size;
+    tempPt = (AliHLTTPCDigitRowData*)tmp;
+  }
+  delete [] ndigits;
+  return data;
+}
+Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
+{
+  //Connects to the TPC digit tree in the AliROOT file.
+#ifdef use_newio
+  AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+  if(!tpcLoader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
+    <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  fInAli->GetEvent(event);
+  tpcLoader->LoadDigits();
+  fDigitsTree = tpcLoader->TreeD();
+#else  
+  fInAli->cd();
+  Char_t dname[100];
+  sprintf(dname,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
+  fDigitsTree = (TTree*)fInAli->Get(dname);
+#endif
+  if(!fDigitsTree) 
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
+       <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
+      return kFALSE;
+    }
+  fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
+
+  if(!fIndexCreated) return CreateIndex();
+  else return kTRUE;
+}
+
+void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *new_digitsfile)
+{
+  //Write the data stored in rowPt, into a new AliROOT file.
+  //The data is stored in the AliROOT format 
+  //This is specially a nice thing if you have modified data, and wants to run it  
+  //through the offline reconstruction chain.
+  //The arguments is a pointer to the data, and the name of the new AliROOT file.
+  //Remember to pass the original AliROOT file (the one that contains the original
+  //simulated data) to this object, in order to retrieve the MC id's of the digits.
+
+  if(!fInAli)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+       <<"No rootfile "<<ENDLOG;
+      return;
+    }
+  if(!fParam)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+       <<"No parameter object. Run on rootfile "<<ENDLOG;
+      return;
+    }
+
+#ifdef use_newio
+  //Get the original digitstree:
+  AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+  if(!tpcLoader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+    <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+    return;
+  }
+  tpcLoader->LoadDigits();
+  TTree *t=tpcLoader->TreeD();
+
+  AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
+  old_array->Setup(fParam);
+  old_array->SetClass("AliSimDigits");
+
+  Bool_t ok = old_array->ConnectTree(t);
+  if(!ok)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+       << "No digits tree object" << ENDLOG;
+      return;
+    }
+
+  tpcLoader->SetDigitsFileName(new_digitsfile);
+  tpcLoader->MakeDigitsContainer();
+    
+  //setup a new one, or connect it to the existing one:
+  AliTPCDigitsArray *arr = new AliTPCDigitsArray(); 
+  arr->SetClass("AliSimDigits");
+  arr->Setup(fParam);
+  arr->MakeTree(tpcLoader->TreeD());
+#else
+  
+  //Get the original digitstree:
+  Char_t dname[100];
+  sprintf(dname,"TreeD_%s_0",AliHLTTPCTransform::GetParamName());
+
+  fInAli->cd();
+  AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
+  old_array->Setup(fParam);
+  old_array->SetClass("AliSimDigits");
+
+  Bool_t ok = old_array->ConnectTree(dname);
+  if(!ok)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+       <<"No digits tree object." <<ENDLOG;
+      return;
+    }
+
+  Bool_t create=kFALSE;
+  TFile *digFile;
+  
+  if(gSystem->AccessPathName(new_digitsfile))
+    {
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+       <<"Creating new file "<<new_digitsfile<<ENDLOG;
+      create = kTRUE;
+      digFile = TFile::Open(new_digitsfile,"RECREATE");
+      fParam->Write(fParam->GetTitle());
+    }
+  else
+    {
+      create = kFALSE;
+      digFile = TFile::Open(new_digitsfile,"UPDATE");
+      
+    }
+  if(!digFile->IsOpen())
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
+       <<"Error opening rootfile "<<new_digitsfile<<ENDLOG;
+      return;
+    }
+  
+  digFile->cd();
+    
+  //setup a new one, or connect it to the existing one:
+  AliTPCDigitsArray *arr = new AliTPCDigitsArray(); 
+  arr->SetClass("AliSimDigits");
+  arr->Setup(fParam);
+  if(create)
+    arr->MakeTree();
+  else
+    {
+      Bool_t ok = arr->ConnectTree(dname);
+      if(!ok)
+       {
+         LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
+           <<"No digits tree object in existing file"<<ENDLOG;
+         return;
+       }
+    }
+#endif
+
+  Int_t digcounter=0,trackID[3];
+
+  for(Int_t i=fRowMin; i<=fRowMax; i++)
+    {
+      
+      if((Int_t)rowPt->fRow != i) 
+       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+         <<"Mismatching row numbering "<<(Int_t)rowPt->fRow<<" "<<i<<ENDLOG;
+            
+      Int_t sector,row;
+      AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
+      
+      AliSimDigits *old_dig = (AliSimDigits*)old_array->LoadRow(sector,row);
+      AliSimDigits * dig = (AliSimDigits*)arr->CreateRow(sector,row);
+      old_dig->ExpandBuffer();
+      old_dig->ExpandTrackBuffer();
+      dig->ExpandBuffer();
+      dig->ExpandTrackBuffer();
+      
+      if(!old_dig)
+       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+         <<"No padrow " << sector << " " << row <<ENDLOG;
+
+      AliHLTTPCDigitData *digPt = rowPt->fDigitData;
+      digcounter=0;
+      for(UInt_t j=0; j<rowPt->fNDigit; j++)
+       {
+         Short_t charge = (Short_t)digPt[j].fCharge;
+         Int_t pad = (Int_t)digPt[j].fPad;
+         Int_t time = (Int_t)digPt[j].fTime;
+         
+         if(charge == 0) //Only write the digits that has not been removed
+           {
+             LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+               <<"Zero charge" <<ENDLOG;
+             continue;
+           }
+
+         digcounter++;
+         
+         //Tricks to get and set the correct track id's. 
+         for(Int_t t=0; t<3; t++)
+           {
+             Int_t label = old_dig->GetTrackIDFast(time,pad,t);
+             if(label > 1)
+               trackID[t] = label - 2;
+             else if(label==0)
+               trackID[t] = -2;
+             else
+               trackID[t] = -1;
+           }
+         
+         dig->SetDigitFast(charge,time,pad);
+         
+         for(Int_t t=0; t<3; t++)
+           ((AliSimDigits*)dig)->SetTrackIDFast(trackID[t],time,pad,t);
+         
+       }
+      //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;
+      UpdateRowPointer(rowPt);
+      arr->StoreRow(sector,row);
+      arr->ClearRow(sector,row);  
+      old_array->ClearRow(sector,row);
+    }
+
+  char treeName[100];
+  sprintf(treeName,"TreeD_%s_0",fParam->GetTitle());
+  
+#ifdef use_newio
+  arr->GetTree()->SetName(treeName);
+  arr->GetTree()->AutoSave();
+  tpcLoader->WriteDigits("OVERWRITE");
+#else
+  digFile->cd();
+  arr->GetTree()->SetName(treeName);
+  arr->GetTree()->AutoSave();
+  digFile->Close();
+#endif
+  delete arr;
+  delete old_array;
+}
+
+///////////////////////////////////////// Point IO  
+Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
+{
+  //points to binary
+  Bool_t out = kTRUE;
+  UInt_t npoint;
+  AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
+  out = Memory2Binary(npoint,data);
+  Free();
+  return out;
+}
+
+AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
+{
+  //points to memory
+  AliHLTTPCSpacePointData *data = 0;
+  npoint=0;
+  if(!fInAli){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+    <<"No Input avalible: no object fInAli"<<ENDLOG;
+    return 0;
+  }
+#ifndef use_newio
+  if(!fInAli->IsOpen()){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+    <<"No Input avalible: TFile not opend"<<ENDLOG;
+    return 0;
+  }
+#endif
+
+  TDirectory *savedir = gDirectory;
+#ifdef use_newio
+  AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+  if(!tpcLoader){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+    <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  fInAli->GetEvent(eventn);
+  tpcLoader->LoadRecPoints();
+
+  AliTPCClustersArray carray;
+  carray.Setup(fParam);
+  carray.SetClusterType("AliTPCcluster");
+  Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
+#else
+  fInAli->cd();
+  
+  Char_t cname[100];
+  sprintf(cname,"TreeC_TPC_%d",eventn);
+  AliTPCClustersArray carray;
+  carray.Setup(fParam);
+  carray.SetClusterType("AliTPCcluster");
+  Bool_t clusterok = carray.ConnectTree(cname);
+#endif
+
+  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;
+    AliHLTTPCTransform::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(AliHLTTPCSpacePointData);
+
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+  <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
+
+  data = (AliHLTTPCSpacePointData *) Allocate(size);
+  npoint = sum;
+  UInt_t n=0; 
+  Int_t pat=fPatch;
+  if(fPatch==-1)
+    pat=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];
+    AliHLTTPCTransform::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].fCharge = (UInt_t)c->GetQ();
+      data[n].fID = n+((fSlice&0x7f)<<25)+((pat&0x7)<<22);//uli
+      data[n].fPadRow = lrow;
+      data[n].fSigmaY2 = c->GetSigmaY2();
+      data[n].fSigmaZ2 = c->GetSigmaZ2();
+#ifdef do_mc
+      data[n].fTrackID[0] = c->GetLabel(0);
+      data[n].fTrackID[1] = c->GetLabel(1);
+      data[n].fTrackID[2] = c->GetLabel(2);
+#endif
+      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/TPCLib/AliHLTTPCFileHandler.h b/HLT/TPCLib/AliHLTTPCFileHandler.h
new file mode 100644 (file)
index 0000000..ecc6745
--- /dev/null
@@ -0,0 +1,89 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCFILEHANDLER_H
+#define ALIHLTTPCFILEHANDLER_H
+
+#include "AliHLTTPCMemHandler.h"
+
+class TClonesArray;
+
+#include <AliSimDigits.h>
+#include <AliTPCParam.h>
+#ifdef use_newio
+#include <AliRunLoader.h>
+#endif
+
+#include <TObject.h>
+#include <TFile.h>
+#include <TTree.h>
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCTrackArray;
+
+class AliHLTTPCFileHandler:public AliHLTTPCMemHandler{
+
+ protected:
+#ifdef use_newio
+  AliRunLoader *fInAli;//!
+  Bool_t fUseRunLoader; //use runloader
+#else
+  TFile *fInAli;//!
+#endif
+
+  AliTPCParam *fParam;//!
+  AliSimDigits *fDigits;//!
+
+  TTree *fDigitsTree;//!
+  FILE *fMC;//!
+  
+  Bool_t fIndexCreated;   //is index created
+  Int_t  fIndex[36][159]; //stores index over digitstree 
+                          //for faster access w/o ASVVERSION
+  Bool_t fUseStaticIndex; //take static index
+  static Bool_t fgStaticIndexCreated;   //global index created
+  static Int_t  fgStaticIndex[36][159]; //global index
+
+  virtual Bool_t SetAliInput();
+  Bool_t GetDigitsTree(Int_t event);
+  Bool_t CreateIndex();  //create the index
+
+ public:
+  AliHLTTPCFileHandler(Bool_t b=kFALSE);
+  ~AliHLTTPCFileHandler();
+
+  void FreeDigitsTree();
+  static void CleanStaticIndex();
+  static Int_t SaveStaticIndex(Char_t *prefix=0,Int_t event=0);
+  static Int_t LoadStaticIndex(Char_t *prefix=0,Int_t event=0);
+
+  Bool_t SetAliInput(Char_t *name);
+  Bool_t SetAliInput(TFile *file);
+#ifdef use_newio
+  Bool_t SetAliInput(AliRunLoader *runLoader);
+#else
+#endif
+  void CloseAliInput(); 
+  Bool_t IsDigit(Int_t event);
+  
+  Bool_t SetMCOutput(Char_t *name);
+  Bool_t SetMCOutput(FILE *file);
+  void CloseMCOutput();
+
+  //Digit IO
+  Bool_t AliDigits2Binary(Int_t event=0,Bool_t altro=kFALSE);
+  AliHLTTPCDigitRowData *AliDigits2Memory(UInt_t & nrow,Int_t event=0); //Allocates Memory
+  AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & nrow,Int_t event=0,Bool_t eventmerge=kFALSE); 
+  //Allocates Memory
+  Bool_t AliDigits2CompBinary(Int_t event=0,Bool_t altro=kFALSE);  
+  void AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *new_digitsfile);
+
+  //Point IO
+  Bool_t AliPoints2Binary(Int_t eventn=0);
+  AliHLTTPCSpacePointData *AliPoints2Memory(UInt_t & npoint,Int_t eventn=0);//Allocates Memory
+
+  ClassDef(AliHLTTPCFileHandler,1)   //Filehandler class
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCFitter.cxx b/HLT/TPCLib/AliHLTTPCFitter.cxx
new file mode 100644 (file)
index 0000000..f153ecc
--- /dev/null
@@ -0,0 +1,640 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group 
+
+/** \class AliHLTTPCFitter
+<pre>
+//_____________________________________________________________
+// AliHLTTPCFitter
+//
+// Fit class HLT for helix
+</pre>
+*/
+
+#include <math.h>
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCFitter.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPC.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCFitter)
+
+
+AliHLTTPCFitter::AliHLTTPCFitter()
+{
+  //constructor
+  fTrack=0;
+  fVertex=0;
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+}
+
+AliHLTTPCFitter::AliHLTTPCFitter(AliHLTTPCVertex *vertex,Bool_t vertexconstraint)
+{
+  //constructor
+  fTrack=0;
+  fVertex = vertex;
+  fVertexConstraint=vertexconstraint;
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+}
+
+AliHLTTPCFitter::~AliHLTTPCFitter()
+{
+  //destructor
+  for(Int_t i=0; i<36; i++)
+    {
+      for(Int_t j=0; j<6; j++)
+       {
+         if(fClusters[i][j])
+           delete [] fClusters[i][j];
+       }
+    }
+}
+
+void AliHLTTPCFitter::LoadClusters(Char_t *path,Int_t event,Bool_t sp)
+{
+  //load clusters
+  Char_t fname[256];
+  AliHLTTPCMemHandler *clusterfile[36][6];
+  for(Int_t s=0; s<=35; s++)
+    {
+      for(Int_t p=0; p<6; p++)
+       {
+         Int_t patch;
+         if(sp==kTRUE)
+           patch=-1;
+         else
+           patch=p;
+         if(fClusters[s][p])
+           delete fClusters[s][p];
+         fClusters[s][p] = 0;
+         clusterfile[s][p] = new AliHLTTPCMemHandler();
+         sprintf(fname,"%s/points_%d_%d_%d.raw",path,event,s,patch);
+         if(!clusterfile[s][p]->SetBinaryInput(fname))
+           {
+             delete clusterfile[s][p];
+              clusterfile[s][p] = 0; 
+             continue;
+           }
+         fClusters[s][p] = (AliHLTTPCSpacePointData*)clusterfile[s][p]->Allocate();
+         clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+         clusterfile[s][p]->CloseBinaryInput();
+         if(sp==kTRUE)
+           break;
+       }
+    }
+}
+
+void AliHLTTPCFitter::SortTrackClusters(AliHLTTPCTrack *track) const
+{
+  //Sort the internal cluster list in each track with respect to row numbering.
+  //This may be necessary when no conventional track follower has been
+  //applied, in which the cluster list has been maintained in a more
+  //arbitrary fashion.
+
+  Int_t nhits = track->GetNHits();
+  Int_t *ids = (Int_t*)track->GetHitNumbers();
+  Int_t *origids = new Int_t[nhits];
+  Int_t *mk = new Int_t[nhits];
+  Int_t k;
+
+  for(k=0; k<nhits; k++) {origids[k] = ids[k]; mk[k] = -1;}
+  
+  Int_t slice,patch,id,padrow,maxrow,maxk;
+  UInt_t pos;
+  for(Int_t j=0; j<nhits; j++)
+    {
+      maxrow=-1;
+      maxk=200;
+      for(k=0; k<nhits; k++)
+       {
+         id=ids[k];
+         if(id < 0) continue;
+         slice = (id>>25) & 0x7f;
+         patch = (id>>22) & 0x7;
+         pos = id&0x3fffff;          
+         AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+         padrow = points[pos].fPadRow;
+         if(padrow > maxrow)
+           {
+             maxrow = padrow;
+             maxk=k;
+           }
+       }
+      mk[j]=maxk;
+      ids[maxk]=-1;
+    }
+    
+  for(k=0; k<nhits; k++)
+    ids[k] = origids[mk[k]];
+  delete [] origids;
+  delete [] mk;
+}
+
+Int_t AliHLTTPCFitter::FitHelix(AliHLTTPCTrack *track)
+{
+  //fit helix parameters
+  fTrack = track;
+  if(FitCircle())
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+       "Problems during circle fit"<<ENDLOG;
+      return 1;
+    }
+  if(FitLine())
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+       "Problems during line fit"<<ENDLOG;
+      return 1;
+    }
+  return 0;
+}
+
+Int_t AliHLTTPCFitter::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 ;
+  
+  //
+  //     Loop over hits calculating average
+  Double_t * fXYWeight = new Double_t[(fTrack->GetNHits())];
+  UInt_t *hitnum = fTrack->GetHitNumbers();
+  for(Int_t i=0; i<fTrack->GetNHits(); i++)
+    {
+      UInt_t id = hitnum[i];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+      fXYWeight[i] = 1./ (Double_t)(points[pos].fSigmaY2 + points[pos].fSigmaY2);
+      wsum += fXYWeight[i];
+      xav += fXYWeight[i]*points[pos].fX;
+      yav += fXYWeight[i]*points[pos].fY;
+    }
+  if (fVertexConstraint == kTRUE)
+    {    
+      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(Int_t i=0; i<fTrack->GetNHits(); i++)
+    { 
+      UInt_t id = hitnum[i];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+
+      xi = points[pos].fX -xav;
+      yi        = points[pos].fY - yav ;
+      xxav     += xi * xi * fXYWeight[i];
+      xyav     += xi * yi * fXYWeight[i];
+      yyav     += yi * yi * fXYWeight[i];
+    }
+  
+  if (fVertexConstraint == kTRUE)
+    {
+      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(Int_t i=0; i<fTrack->GetNHits(); i++)
+    { 
+      UInt_t id = hitnum[i];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+      
+      xold = points[pos].fX - xav ;
+      yold = points[pos].fY - 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 = fXYWeight[i] * riri ;
+      
+      xyav   += fXYWeight[i] * xi * yi ;
+      xxav   += fXYWeight[i] * xixi ;
+      yyav   += fXYWeight[i] * yiyi ;
+      
+      xrrav  += wiriri * xi ;
+      yrrav  += wiriri * yi ;
+      rrrrav += wiriri * riri ;
+    }
+//
+//   Include vertex if required
+//
+  if (fVertexConstraint == kTRUE)
+    {
+      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 kntry = 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 <= kntry ; 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(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitCircle","TrackFit")<<AliHLTTPCLog::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
+//
+  Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
+  fTrack->SetCharge(q);
+  
+  //Set the first point on the track to the space point coordinates of the innermost track
+  //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
+  Double_t x0,y0,psi,pt ;
+  Int_t lastid=fTrack->GetNHits()-1;
+  UInt_t id = hitnum[lastid];
+  Int_t slice = (id>>25) & 0x7f;
+  Int_t patch = (id>>22) & 0x7;
+  UInt_t pos = id&0x3fffff;
+  AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+  x0   =  points[pos].fX;
+  y0   =  points[pos].fY;
+  fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
+  
+  //Set the remaining fit parameters
+  psi  = (Double_t)atan2(bcent-y0,acent-x0) ;
+  psi  = psi + q * 0.5F * AliHLTTPCTransform::Pi() ;
+  if ( psi < 0 ) psi = psi + 2*AliHLTTPCTransform::Pi();
+  
+  pt   = (Double_t)(AliHLTTPCTransform::GetBFact() * AliHLTTPCTransform::GetBField() * radius ) ;
+  fTrack->SetPsi(psi);
+  fTrack->SetPt(pt);
+  fTrack->SetRadius(radius);
+  fTrack->SetCenterX(acent);
+  fTrack->SetCenterY(bcent);
+//
+//    Get errors from fast fit
+//
+  //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+  delete [] fXYWeight;
+  return 0 ;
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//    Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliHLTTPCFitter::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() / ( AliHLTTPCTransform::GetBFact() * AliHLTTPCTransform::GetBField() ) ) ;
+
+  Double_t * fS = new Double_t[(fTrack->GetNHits())];
+  Double_t *fZWeight = new Double_t[fTrack->GetNHits()];
+  UInt_t *hitnum = fTrack->GetHitNumbers();
+  if (0)//fVertexConstraint==kTRUE)
+    {
+      UInt_t id = hitnum[0];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+      
+      dx = points[pos].fX - fVertex->GetX();
+      dy = points[pos].fY - fVertex->GetY();
+    }
+  else 
+    {
+      UInt_t id = hitnum[0];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t posf = id&0x3fffff;
+      AliHLTTPCSpacePointData *pointsf = fClusters[slice][patch];
+      id = hitnum[(fTrack->GetNHits()-1)];
+      slice = (id>>25) & 0x7f;
+      patch = (id>>22) & 0x7;
+      UInt_t posl = id&0x3fffff;
+      AliHLTTPCSpacePointData *pointsl = fClusters[slice][patch];
+      dx = pointsf[posf].fX - pointsl[posl].fX;
+      dy = pointsf[posf].fY - pointsl[posl].fY;
+    }
+
+  Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
+  Double_t totals ;
+  
+  if ( fabs(localPsi) < 1. ) 
+    {
+      totals = 2.0 * radius * asin ( localPsi ) ;
+    } 
+  else 
+    { 
+      totals = 2.0 * radius * AliHLTTPCTransform::Pi() ;
+    } 
+  
+  Double_t dpsi,s;
+  
+  for(Int_t i=0; i<fTrack->GetNHits(); i++)
+    { 
+      UInt_t id = hitnum[i];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+      
+      fZWeight[i] = 1./(Double_t)(points[pos].fSigmaZ2);
+      if(i>0)
+       {
+         id = hitnum[i-1];
+         slice = (id>>25) & 0x7f;
+         patch = (id>>22) & 0x7;
+         UInt_t lastpos = id&0x3fffff;
+         AliHLTTPCSpacePointData *lastpoints = fClusters[slice][patch];
+         dx = points[pos].fX -lastpoints[lastpos].fX;
+         dy = points[pos].fY -lastpoints[lastpos].fY;
+         dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
+         if(fabs(dpsi) > 1)
+           return 1;
+         fTrack->SetPsierr(dpsi);
+         s = fS[i-1] - 2.0 * radius * (Double_t)asin ( dpsi ) ;
+         fS[i]=s;
+       }
+      else
+       fS[i]=totals;
+      
+      sum += fZWeight[i];
+      ss  += fZWeight[i] * fS[i];
+      sz  += fZWeight[i] * points[pos].fZ;
+      sss += fZWeight[i] * fS[i] * fS[i];
+      ssz += fZWeight[i] * fS[i] * points[pos].fZ;
+      
+    }
+  
+  
+  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(Int_t i=0; i<fTrack->GetNHits(); i++)
+    { 
+      UInt_t id = hitnum[i];
+      Int_t slice = (id>>25) & 0x7f;
+      Int_t patch = (id>>22) & 0x7;
+      UInt_t pos = id&0x3fffff;
+      AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+      r1   = points[pos].fZ - tanl * fS[i] - z0 ;
+      chi2 += (Double_t) ( (Double_t)(fZWeight[i]) * (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);
+  delete [] fZWeight;
+  delete [] fS;
+  return 0 ;
+} 
diff --git a/HLT/TPCLib/AliHLTTPCFitter.h b/HLT/TPCLib/AliHLTTPCFitter.h
new file mode 100644 (file)
index 0000000..75ef3f2
--- /dev/null
@@ -0,0 +1,41 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCFITTER_H
+#define ALIHLTTPCFITTER_H
+
+//_____________________________________________________________
+// AliHLTTPCFitter
+//
+// Fit class HLT
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+
+class AliHLTTPCTrack;
+class AliHLTTPCVertex;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCFitter {
+
+  public:
+  AliHLTTPCFitter();
+  AliHLTTPCFitter(AliHLTTPCVertex *vertex,Bool_t vertexconstraint=kTRUE);
+  virtual ~AliHLTTPCFitter();
+  
+  void LoadClusters(Char_t *path,Int_t event=0,Bool_t sp=kFALSE);
+  void SortTrackClusters(AliHLTTPCTrack *track) const;
+  Int_t FitHelix(AliHLTTPCTrack *track);
+  Int_t FitCircle();
+  Int_t FitLine();
+  void NoVertex() {fVertexConstraint=kFALSE;}
+ private:
+  AliHLTTPCTrack *fTrack; //!                    actual track
+  AliHLTTPCVertex *fVertex; //!                  vertex info
+  Bool_t fVertexConstraint; //               include vertex constraint
+  AliHLTTPCSpacePointData *fClusters[36][6]; //! clusters
+  UInt_t fNcl[36][6]; //                     cluster numbers
+  ClassDef(AliHLTTPCFitter,1) //HLT fit class
+};
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCGlobalMerger.cxx b/HLT/TPCLib/AliHLTTPCGlobalMerger.cxx
new file mode 100644 (file)
index 0000000..4a079e7
--- /dev/null
@@ -0,0 +1,342 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group 
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+/** \class AliHLTTPCGlobalMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCGlobalMerger
+//
+// The HLTTPC Slice merger
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCGlobalMerger)
+
+AliHLTTPCGlobalMerger::AliHLTTPCGlobalMerger()
+{
+  //Default constructor. Use Setup to specify and setup the necessary parameters and arrays.
+  Is2Global(kTRUE);
+  SetParameter(0,0,0,0,0);
+  fNSlices=0;
+  fFirst=0;
+  fLast=0;
+}
+
+
+AliHLTTPCGlobalMerger::~AliHLTTPCGlobalMerger()
+{
+  //Destructor
+}
+
+void AliHLTTPCGlobalMerger::Setup(Int_t first,Int_t last)
+{
+  //Used to setup the arrays and everything
+  
+  fNSlices = last-first+1;
+  fFirst = first;
+  fLast = last;
+  InitMerger(last-first+1);
+}
+
+void AliHLTTPCGlobalMerger::InitSlice(Int_t slice)
+{
+  // 
+  // Select Sector The following FillTracks call will 
+  // fill this Sector
+  //
+  fSlice = slice;
+  fCurrentTracks = fSlice - fFirst; 
+}
+
+Double_t AliHLTTPCGlobalMerger::CheckTracks(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack,Int_t slice)
+{
+  //Compare the tracks by propagating the outermost track to the last and first point plane
+  //of the innermost track. This plane is defined by the padrow plane where these points
+  //are.
+  
+  if(innertrack->GetCharge()!=outertrack->GetCharge()) return -1;
+  
+  Float_t angle = 0;//perpendicular to the padrowplane (in local system)
+  AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+  Double_t dx[2],dy[2],dz[2];
+  Double_t diff =-1;
+  AliHLTTPCTrack *tracks[2];
+  tracks[0] = innertrack;
+  tracks[1] = outertrack;
+  SortGlobalTracks(tracks,2);
+  innertrack = tracks[0]; 
+  outertrack = tracks[1];
+  
+  Float_t point[3];
+  
+  point[0]=innertrack->GetLastPointX();
+  point[1]=innertrack->GetLastPointY();
+  point[2]=innertrack->GetLastPointZ();
+  AliHLTTPCTransform::Global2LocHLT(point,slice);
+  
+  outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
+  if(!outertrack->IsPoint()) return diff;
+  dx[0] = fabs(outertrack->GetPointX()-innertrack->GetLastPointX());
+  dy[0] = fabs(outertrack->GetPointY()-innertrack->GetLastPointY());
+  dz[0] = fabs(outertrack->GetPointZ()-innertrack->GetLastPointZ());
+  
+  point[0]=innertrack->GetFirstPointX();
+  point[1]=innertrack->GetFirstPointY();
+  point[2]=innertrack->GetFirstPointZ();
+  AliHLTTPCTransform::Global2LocHLT(point,slice);
+  
+  outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
+  if(!outertrack->IsPoint()) return diff;
+  dx[1] = fabs(outertrack->GetPointX()-innertrack->GetFirstPointX());
+  dy[1] = fabs(outertrack->GetPointY()-innertrack->GetFirstPointY());
+  dz[1] = fabs(outertrack->GetPointZ()-innertrack->GetFirstPointZ());
+  
+  diff=0;//This was a tough bug to find....
+  for(Int_t i=0; i<2; i++)
+    diff += sqrt(dx[i]*dx[i] + dy[i]*dy[i] + dz[i]*dz[i]);
+  return diff;
+}
+
+void AliHLTTPCGlobalMerger::SlowMerge(Char_t *path)
+{
+  //Tuning of parameters. This matches _all_ tracks between two neighbouring
+  //slices, and merges the ones which are closest in space. The difference
+  //is written to a ntuppel, which can be used as a input for the SetParameters
+  //when using normal Merge function.
+  
+  
+  void* ntuple=GetNtuple();
+  AliHLTTPCTrack *track[2];
+  AliHLTTPCTrackArray *tout = GetOutTracks();
+  if(fNSlices<2)
+    {
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCGlobalMerger::SlowMerge","Slice Number")
+       <<"Need more than one Slice!"<<ENDLOG;
+      return;
+    }
+  
+  for(Int_t i=0; i<fNSlices; i++)
+    {
+      //if(fNSlices!=18 && i+1 == fNSlices) continue; 
+      Int_t slice = fFirst + i;
+      AliHLTTPCTrackArray *ttt0=GetInTracks(i);
+      Int_t slice2 = i+1;
+      //if(slice2==fNSlices) slice2 =0; 
+      
+      //Make sure slices are on the same side of the TPC
+      if(slice2 == 18) slice2=0;
+      else if(slice2 == 36) slice2=18;
+      AliHLTTPCTrackArray *ttt1=GetInTracks(slice2);
+      //10 degrees -> the border of the slices in local coordinates
+      Float_t angle = AliHLTTPCTransform::Pi()/18; 
+      AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+      
+      //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
+      //the calculation of crossing points to be correct.
+      if(slice==17 || slice==35) 
+       angle=0;
+      if(i==0)
+       ttt0->QSort();
+      ttt1->QSort();
+      for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
+       {
+         AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+         if(!track0) continue;
+         track0->CalculateHelix();
+         track0->CalculateEdgePoint(angle);
+         //      if(track0->IsPoint()) AddTrack(tout,track0);
+       }
+      for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
+       {
+         AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+         if(!track1) continue;
+         track1->CalculateHelix();
+         track1->CalculateEdgePoint(angle);
+         //      if(track1->IsPoint())  AddTrack(tout,track1); 
+       }
+      Bool_t merge = kTRUE;
+      while(merge)
+       {
+         Int_t min0=-1,min1=-1;
+         Double_t min=5;
+         Int_t n0=ttt0->GetNTracks(),n1=ttt1->GetNTracks();
+         for(Int_t s0=0;s0<n0;s0++)
+           {
+             AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+             if(!track0) continue;
+             if(!track0->IsPoint()) continue;
+             for(Int_t s1=0;s1<n1;s1++)
+               {
+                 AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+                 if(!track1) continue;
+                 if(!track1->IsPoint()) continue;
+                 
+                 //Double_t diff = TrackDiff(track0,track1,angle);
+                 Double_t diff = CheckTracks(track0,track1,slice);
+                 //PrintDiff(track0,track1);
+                 if(diff>=0&&diff<min)
+                   {
+                     min=diff;
+                     min0=s0;
+                     min1=s1;
+                   }
+               }
+           }
+         if(min0>=0&&min1>=0)
+           {
+             AliHLTTPCTrack *track0=ttt0->GetTrack(min0);
+             AliHLTTPCTrack *track1=ttt1->GetTrack(min1);
+             track[0] = track0;
+             track[1] = track1;
+             SortGlobalTracks(track,2);
+             track1->CalculateEdgePoint((angle+AliHLTTPCTransform::Pi()/9));
+             if(track1->IsPoint())//Check if the track will cross the boundary of yet another slice.
+               MultiMerge(ttt1,track,2);
+             else
+               MultiMerge(tout,track,2); 
+             track0->CalculateReferencePoint(angle);
+             track1->CalculateReferencePoint(angle);
+             //PrintDiff(track0,track1);
+             FillNtuple(ntuple,track0,track1);
+             ttt0->Remove(min0);
+             ttt1->Remove(min1);
+             
+           }
+         else merge = kFALSE;
+       }
+      ttt0->Compress();
+      ttt1->Compress();
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPCGlobalMerger::SlowMerge","Result")
+       <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<tout->GetNTracks()<<" at:"
+       <<angle<<ENDLOG;
+    }
+  Char_t fname[1024];
+  sprintf(fname,"%s/merge_parameters.root",path);
+  WriteNtuple(fname,ntuple);
+}
+
+void AliHLTTPCGlobalMerger::Merge()
+{
+  //Normal merging procedure. Matches tracks which are within limits
+  //set by SetParameters. Parameters can be tuned by SlowMerge.
+  
+  AliHLTTPCTrack *track[2];
+  AliHLTTPCTrackArray *tout = GetOutTracks();
+  if(fNSlices<2)
+    {
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCGlobalMerger::Merge","Slice Number")
+       <<"Need more than one Slice!"<<ENDLOG;
+      return;
+    }
+  for(Int_t i=0; i<fNSlices; i++)
+    {
+      //if(fNSlices!=18 && i+1 == fNSlices) continue; 
+      Int_t slice = fFirst + i;
+      AliHLTTPCTrackArray *ttt0=GetInTracks(i);
+      Int_t slice2 = i+1;
+      //if(slice2==fNSlices) slice2 =0;
+      
+      //Make sure slices are on the same side of the TPC
+      if(slice2 == 18) slice2=0;
+      else if(slice2 == 36) slice2=18;
+      AliHLTTPCTrackArray *ttt1=GetInTracks(slice2);
+      //10 degrees -> the border of the slices in local coordinates
+      Float_t angle = AliHLTTPCTransform::Pi()/18; 
+      AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+      
+      //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
+      //the calculation of crossing points to be correct.
+      if(slice==17 || slice==35)
+       angle=0;
+      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;
+         AliHLTTPCTrack *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;
+         AliHLTTPCTrack *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++)
+       {
+         if(ismatched0[s0]) continue;
+         AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+         if(!track0) continue;
+         if(!track0->IsPoint()) continue;
+         for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
+           {
+             if(ismatched1[s1]) continue;
+             AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+             if(!track1) continue;
+             if(!track1->IsPoint()) continue;
+             if(IsRTrack(track0,track1))
+               {
+                 track[0] = track0;
+                 track[1] = track1;
+                 SortGlobalTracks(track,2);
+                 Double_t r0 = pow(track[0]->GetLastPointX(),2)+
+                   pow(track[0]->GetLastPointY(),2);
+                 Double_t r1 = pow(track[1]->GetFirstPointX(),2)+
+                   pow(track[1]->GetFirstPointY(),2);
+                 if(r0<r1)
+                   {
+                     MultiMerge(tout,track,2); 
+                     ismatched0[s0]=kTRUE;
+                     ismatched1[s1]=kTRUE;
+                     ttt0->Remove(s0);
+                     ttt1->Remove(s1);
+                     break;
+                     /*
+                       The track is merged, so we will _not_ look for more matches.
+                       Because there could easily be more matches, if a track is being
+                       split within the sector....
+                     */
+                   }
+               }
+           }
+       }
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPCGlobalMerger::Merge","Result")
+       <<AliHLTTPCLog::kDec<<"slice0: "<<n0<<" slice1: "<<n1
+       <<" Merged Tracks: "<<tout->GetNTracks()<<ENDLOG;
+      delete [] ismatched0;
+      delete [] ismatched1;
+    }
+}
diff --git a/HLT/TPCLib/AliHLTTPCGlobalMerger.h b/HLT/TPCLib/AliHLTTPCGlobalMerger.h
new file mode 100644 (file)
index 0000000..050a42d
--- /dev/null
@@ -0,0 +1,33 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_GLOBALMERGER_H
+#define ALIHLTTPC_GLOBALMERGER_H
+
+#ifndef  __CINT__
+#include "AliHLTTPCMerger.h"
+#endif
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCGlobalMerger : public AliHLTTPCMerger{
+
+ private:
+  Int_t fNSlices;
+  Int_t fFirst;
+  Int_t fLast;
+
+  Double_t CheckTracks(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack,Int_t slice);
+  
+ public:
+  AliHLTTPCGlobalMerger();
+  virtual ~AliHLTTPCGlobalMerger();
+  
+  void Setup(Int_t first,Int_t last);
+  void InitSlice(Int_t slice);
+  void SlowMerge(Char_t *path="./");
+  void Merge();  //Loop over tracks from different sectors
+
+  ClassDef(AliHLTTPCGlobalMerger,1) //Slice merger
+};
+
+#endif
index d25266a..c4b22bd 100644 (file)
@@ -27,14 +27,14 @@ using namespace std;
 #endif
 
 #include "AliHLTTPCGlobalMergerComponent.h"
-#include "AliL3Transform.h"
-#include "AliL3GlobalMerger.h"
-#include "AliL3Vertex.h"
-#include "AliL3VertexData.h"
-#include "AliL3TrackSegmentData.h"
-#include "AliL3TrackArray.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCVertexData.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTrackArray.h"
 #include "AliHLTTPCTrackletDataFormat.h"
-#include "AliL3SpacePointData.h"
+#include "AliHLTTPCSpacePointData.h"
 #include "AliHLTTPCClusterDataFormat.h"
 #include <stdlib.h>
 #include <errno.h>
@@ -95,8 +95,8 @@ int AliHLTTPCGlobalMergerComponent::DoInit( int argc, const char** argv )
     {
     if ( fGlobalMerger || fVertex )
        return EINPROGRESS;
-    fGlobalMerger = new AliL3GlobalMerger();
-    fVertex = new AliL3Vertex();
+    fGlobalMerger = new AliHLTTPCGlobalMerger();
+    fVertex = new AliHLTTPCVertex();
     SetMergerParameters();
     return 0;
     }
@@ -201,7 +201,7 @@ int AliHLTTPCGlobalMergerComponent::DoEvent( const AliHLTComponent_EventData& ev
        fVertex->SetZero();
        }
     else
-       fVertex->Read( (AliL3VertexData*)( lastVertexBlock->fPtr ) );
+       fVertex->Read( (AliHLTTPCVertexData*)( lastVertexBlock->fPtr ) );
 
     // Add all tracks into the merger
     sdIter = slices.begin();
@@ -210,7 +210,7 @@ int AliHLTTPCGlobalMergerComponent::DoEvent( const AliHLTComponent_EventData& ev
        {
        if ( sdIter->fVertexBlock )
            {
-           fVertex->Read( (AliL3VertexData*)( sdIter->fVertexBlock->fPtr ) );
+           fVertex->Read( (AliHLTTPCVertexData*)( sdIter->fVertexBlock->fPtr ) );
            fGlobalMerger->SetVertex( fVertex );
            }
        inPtr = (AliHLTTPCTrackletData*)( sdIter->fTrackletBlock->fPtr );
index 79f13f5..9ce9786 100644 (file)
@@ -12,8 +12,8 @@
 #include "AliHLTProcessor.h"
 #include "AliHLTTPCDefinitions.h"
 
-class AliL3GlobalMerger;
-class AliL3Vertex;
+class AliHLTTPCGlobalMerger;
+class AliHLTTPCVertex;
 
 class AliHLTTPCGlobalMergerComponent : public AliHLTProcessor
     {
@@ -47,8 +47,8 @@ class AliHLTTPCGlobalMergerComponent : public AliHLTProcessor
        
     private:
 
-       AliL3GlobalMerger* fGlobalMerger;
-       AliL3Vertex* fVertex;
+       AliHLTTPCGlobalMerger* fGlobalMerger;
+       AliHLTTPCVertex* fVertex;
 
        struct SliceData
            {
diff --git a/HLT/TPCLib/AliHLTTPCInterMerger.cxx b/HLT/TPCLib/AliHLTTPCInterMerger.cxx
new file mode 100644 (file)
index 0000000..4c16f7c
--- /dev/null
@@ -0,0 +1,155 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCInterMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+/** \class AliHLTTPCInterMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCInterMerger
+//
+// The HLTTPC track segment merger
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCInterMerger)
+
+AliHLTTPCInterMerger::AliHLTTPCInterMerger()
+{
+  //Default constructor
+  InitMerger(1);
+  Is2Global(kFALSE);
+//  SetParameter(2,2,.3,.3,.3);
+  SetParameter(1,0.5,0.0005,0.05,0.1);
+  fRowMax = fRowMin = 0;
+}
+
+
+AliHLTTPCInterMerger::~AliHLTTPCInterMerger(){
+  //Destructor
+  
+}
+
+void AliHLTTPCInterMerger::SlowMerge(){
+  Int_t nrow= fRowMax-fRowMin+1;
+  void *ntuple=GetNtuple();
+  AliHLTTPCTrackArray * tracks = GetInTracks(0);
+  const Int_t  kNIn =tracks->GetNTracks();
+  AliHLTTPCTrack *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++){
+    AliHLTTPCTrack *outertrack=tracks->GetCheckedTrack(out);
+    if(!outertrack) continue;
+      for(Int_t in=0;in<kNIn;in++){
+        if(in==out) continue;
+        AliHLTTPCTrack *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){
+      AliHLTTPCTrack *outertrack=tracks->GetTrack(outmin);
+      AliHLTTPCTrack *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(AliHLTTPCLog::kInformational,"AliHLTTPCInterMerger::SlowMerge","Result")
+  <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<tracks->GetNTracks()-kNIn<<ENDLOG;
+
+  char name[256];
+  sprintf(name,"ntuple_i_%d.root",fPatch);
+  WriteNtuple(name,ntuple);
+}
+
+void AliHLTTPCInterMerger::MMerge(){
+  while(Merge());
+  GetOutTracks()->AddTracks(GetInTracks(0));
+}
+
+Int_t AliHLTTPCInterMerger::Merge(){
+  Int_t nrow= fRowMax-fRowMin+1;
+  Double_t xval =AliHLTTPCTransform::Row2X((fRowMax+fRowMin)/2);
+  AliHLTTPCTrackArray * tracks = GetInTracks(0);
+  const Int_t  kNIn =tracks->GetNTracks();
+  AliHLTTPCTrack *tr[2];
+  for(Int_t in=0;in<kNIn;in++){
+    AliHLTTPCTrack *t = tracks->GetCheckedTrack(in);
+    if(t){
+      t->CalculateHelix();
+      t->CalculatePoint(xval);
+    }
+  }
+  for(Int_t out=0;out<kNIn;out++){
+  AliHLTTPCTrack *outertrack=tracks->GetCheckedTrack(out);
+  if(!outertrack) continue;
+    for(Int_t in=0;in<kNIn;in++){
+      if(in==out) continue;
+      AliHLTTPCTrack *innertrack=tracks->GetCheckedTrack(in);
+      if(!innertrack) continue;
+      if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+      if(IsTrack(innertrack,outertrack)){
+        tr[0]=innertrack;
+        tr[1]=outertrack;
+        SortGlobalTracks(tr,2);
+
+        Double_t r0 = pow(tr[0]->GetLastPointX(),2)+
+                      pow(tr[0]->GetLastPointY(),2);
+        Double_t r1 = pow(tr[1]->GetFirstPointX(),2)+
+                      pow(tr[1]->GetFirstPointY(),2);
+        if(r0<r1){
+          MultiMerge(tracks,tr,2);
+          tracks->Remove(out);
+          tracks->Remove(in);
+          break;
+        }
+      }
+    } 
+  }
+  Int_t nmerged = tracks->GetNTracks()-kNIn; 
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCInterMerger::Merge","Result")
+  <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<nmerged<<ENDLOG;
+  //add in tracks
+//  GetOutTracks()->AddTracks(GetInTracks(0)); 
+
+  return nmerged;
+}
+
+
diff --git a/HLT/TPCLib/AliHLTTPCInterMerger.h b/HLT/TPCLib/AliHLTTPCInterMerger.h
new file mode 100644 (file)
index 0000000..42482ef
--- /dev/null
@@ -0,0 +1,30 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCINTERMERGER_H
+#define ALIHLTTPCINTERMERGER_H
+
+#ifndef __CINT__ 
+#include "AliHLTTPCMerger.h"
+#endif
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCInterMerger : public AliHLTTPCMerger {
+
+ private:
+  Int_t fPatch;
+  Int_t fRowMin;
+  Int_t fRowMax;
+ public:
+  AliHLTTPCInterMerger();
+  virtual ~AliHLTTPCInterMerger();
+
+  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(AliHLTTPCInterMerger,1) //Intermerging class
+};
+
+#endif
index 943d634..9434a26 100644 (file)
@@ -6,6 +6,96 @@
 #pragma link off all classes;
 #pragma link off all functions;
 
+#pragma link C++ class AliHLTTPCBenchmark;
+#pragma link C++ class AliHLTTPCDigitRowData; 
+#pragma link C++ class AliHLTTPCDigitData;
+#pragma link C++ class AliHLTTPCSpacePointData;
+#pragma link C++ class AliHLTTPCConfMapper;
+#pragma link C++ class AliHLTTPCConfMapPoint;
+#pragma link C++ class AliHLTTPCVertex;
+#pragma link C++ class AliHLTTPCVertexFinder;
+#pragma link C++ class AliHLTTPCVertexArray;
+#pragma link C++ class AliHLTTPCTrack;
+#pragma link C++ class AliHLTTPCConfMapTrack;
+#pragma link C++ class AliHLTTPCConfMapFit;
+#pragma link C++ class AliHLTTPCTransform;
+#pragma link C++ class AliHLTTPCMerger;
+#pragma link C++ class AliHLTTPCTrackMerger;
+#pragma link C++ class AliHLTTPCGlobalMerger;
+#pragma link C++ class AliHLTTPCInterMerger;
+#pragma link C++ class AliHLTTPC;
+#pragma link C++ class AliHLTTPCTrackArray;
+/* #pragma link C++ class AliHLTTPCLogger; */
+#pragma link C++ class AliHLTTPCMemHandler;
+#pragma link C++ class AliHLTTPCDataCompressorHelper;
+#pragma link C++ class AliHLTTPCDisplay;
+#pragma link C++ class AliHLTTPCClustFinderNew;
+#pragma link C++ class AliHLTTPCFitter;
+/* #pragma link C++ class AliHLTTPCRawDataFileHandler; */
+/* #pragma link C++ class AliHLTTPCTPCBeamTestMemHandler; */
+#pragma link C++ class AliHLTTPCModelTrack;
+
+#ifdef use_aliroot
+#pragma link C++ class AliHLTTPCFileHandler;
+/* #pragma link C++ class AliHLTTPCEvaluate;  */
+#ifdef use_reconstruction
+#pragma link C++ class AliHLTReconstructor;
+#pragma link C++ class AliHLTTPCTPCtracker;
+#endif
+#endif
+
+#ifndef macosx
+/* #pragma link C++ class AliHLTTPCTransBit;  */
+/* #pragma link C++ class AliHLTTPCTransBitV1;  */
+/* #pragma link C++ class AliHLTTPCTransBitV2;  */
+/* #pragma link C++ class AliHLTTPCDataHandler; */
+#endif
+/* #pragma link C++ class AliHLTTPCAltroMemHandler; */
+/* #pragma link C++ class AliHLTTPCVHDLClusterFinder; */
+/* #pragma link C++ class AliHLTTPCTPCMapping; */
+/* #pragma link C++ class AliHLTTPCDDLRawReader; */
+/* #pragma link C++ class AliHLTTPCDDLRawReaderFile; */
+/* #pragma link C++ class AliHLTTPCDDLTPCRawStream; */
+#ifndef macosx
+#pragma link C++ class AliHLTTPCDDLDataFileHandler;
+#endif
+
+#ifdef USEFFLOAT
+/* #pragma link C++ class AliHLTTPCFFloat; */
+#endif
+
+
+#ifdef INCLUDE_TPC_HOUGH
+/* #pragma link C++ class AliHLTTPCHough;  */
+#pragma link C++ class AliHLTTPCHoughBaseTransformer; 
+/* #pragma link C++ class AliHLTTPCHoughTransformer; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerLUT; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerVhdl; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerNew; */
+#pragma link C++ class AliHLTTPCHoughTransformerRow;
+#ifndef macosx
+#pragma link C++ class AliHLTTPCHoughTrack;
+/* #pragma link C++ class AliHLTTPCHoughKalmanTrack; */
+#endif
+/* #pragma link C++ class AliHLTTPCHoughMaxFinder; */
+/* #pragma link C++ class AliHLTTPCHoughEval; */
+#pragma link C++ class AliHLTTPCHistogram;
+/* #pragma link C++ class AliHLTTPCHistogram1D; */
+/* #pragma link C++ class AliHLTTPCHoughMerger; */
+/* #pragma link C++ class AliHLTTPCHoughIntMerger; */
+/* #pragma link C++ class AliHLTTPCHoughGlobalMerger; */
+/* #pragma link C++ class AliHLTTPCHoughDisplay; */
+/* #pragma link C++ class AliHLTTPCHoughClusterTransformer; */
+#pragma link C++ class AliHLTTPCHistogramAdaptive;
+#ifndef macosx
+/* #pragma link C++ class AliHLTTPCHoughTest; */
+#endif
+
+#ifdef use_aliroot
+/* #pragma link C++ class AliHLTTPCHoughTransformerGlobal; */
+#endif
+#endif // INCLUDE_TPC_HOUGH
+
 #pragma link C++ class AliHLTTPCDefinitions;
 #pragma link C++ class AliHLTTPCRawDataUnpackerComponent;
 #pragma link C++ class AliHLTTPCClusterFinderComponent;
diff --git a/HLT/TPCLib/AliHLTTPCLog.cxx b/HLT/TPCLib/AliHLTTPCLog.cxx
new file mode 100644 (file)
index 0000000..9bf28ca
--- /dev/null
@@ -0,0 +1,10 @@
+// $Id$
+
+#ifndef use_logging
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+
+AliHLTTPCLog::TLogLevel AliHLTTPCLog::fgLevel=AliHLTTPCLog::kNone;
+
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCLog.h b/HLT/TPCLib/AliHLTTPCLog.h
new file mode 100644 (file)
index 0000000..697b728
--- /dev/null
@@ -0,0 +1,22 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCLOG_H
+#define ALIHLTTPCLOG_H
+
+class AliHLTTPCLog {
+  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 };
+  static TLogLevel fgLevel;
+};
+
+#if __GNUC__ == 3
+#define LOG( lvl, origin, keyword ) \
+ if (lvl>=AliHLTTPCLog::fgLevel) std::cerr<<"["<<origin<<": "<<keyword<<"] "
+#define ENDLOG std::endl
+#else
+#define LOG( lvl, origin, keyword ) \
+ if (lvl>=AliHLTTPCLog::fgLevel) cerr<<"["<<origin<<": "<<keyword<<"] "
+#define ENDLOG endl
+#endif /* __GNUC__ */
+#endif /* ALIHLTTPCLOG_H */
diff --git a/HLT/TPCLib/AliHLTTPCLogging.h b/HLT/TPCLib/AliHLTTPCLogging.h
new file mode 100644 (file)
index 0000000..6c04548
--- /dev/null
@@ -0,0 +1,24 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCLOGGING_H
+#define ALIHLTTPCLOGGING_H
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+
+#ifdef use_logging
+#include <MLUCLog.hpp>
+#include <MLUCLogServer.hpp>
+
+typedef MLUCLog AliHLTTPCLog;
+typedef MLUCLogServer AliHLTTPCLogServer;
+typedef MLUCDevNullLogServer AliHLTTPCDevNullLogServer;
+typedef MLUCStdoutLogServer AliHLTTPCStdoutLogServer;
+typedef MLUCStderrLogServer AliHLTTPCStderrLogServer;
+typedef MLUCStreamLogServer AliHLTTPCStreamLogServer;
+
+#else
+
+#include "AliHLTTPCLog.h"
+#endif /* use_logging */ 
+#endif /* ALIHLTTPCLOGGING_H */
diff --git a/HLT/TPCLib/AliHLTTPCMemHandler.cxx b/HLT/TPCLib/AliHLTTPCMemHandler.cxx
new file mode 100644 (file)
index 0000000..74dec2b
--- /dev/null
@@ -0,0 +1,1243 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group 
+
+/** \class AliHLTTPCMemHandler 
+<pre>
+//_____________________________________________________________
+// AliHLTTPCMemHandler
+//
+// The HLT Binary File handler 
+//
+//  This class does all the memory I/O handling of HLT binary files.
+//  
+//  Examples:
+//  ---------
+//
+//  1) Reading a binary file:
+//  
+//  AliHLTTPCMemHandler file;
+//  file.SetBinaryInput(filename);
+//  file.Init(slice,patch);
+//
+//  UInt_t nrowss;
+//  AliHLTTPCDigitRowData *data = file.CompBinary2Memory(nrows);
+//  
+//  for(int i=0; i<nrows; i++) 
+//    {
+//    
+//    AliHLTTPCDigitData *dataPt = (AliHLTTPCDigitData*)data->fDigitData;
+//    for(int j=0; j<data->fNDigit; j++) 
+//      {
+//        pad = dataPt[j].fPad;
+//        time = dataPt[j].fTime;
+//        charge = dataPt[j].fCharge;
+//      }
+//     
+//    file.UpdateRowPointer(data);
+//  
+//    }
+//  file.CloseBinaryInput();
+//  ________________________
+//  
+//  2) Writing a binary file:
+//  
+//  //First of all you need to store the data in memory,
+//  //and have a pointer to it of type AliHLTTPCDigitRowData.
+//  //E.g. if you just want to write the data you read in example 1)
+//  //into a new file, you can do the following:
+//  
+//  AliHLTTPCMemHandler newfile;
+//  newfile.Init(slice,patch);
+//  newfile.SetBinaryOutput(newfilename);
+//  newfile.Memory2CompBinary((UInt_t)NumberOfRowsInPatch,(AliHLTTPCDigitRowData*)data);
+//  newfile.CloseBinaryOutput();
+//
+//
+// Compressed file format:
+// -----------------------
+//
+// The data is RLE encoded and currently using _10_ bit range for the ADC-values.
+</pre>
+*/  
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+  
+ClassImp(AliHLTTPCMemHandler)
+  
+AliHLTTPCMemHandler::AliHLTTPCMemHandler()
+{ 
+  //Constructor
+  fPt = 0;
+  fSize =0;
+  fInBinary = 0;
+  fOutBinary = 0;
+  fNRandom = 0;
+  Init(0,0);
+  fIsRandom = kFALSE;
+  fRandomDigits = 0;
+  fDPt =0;
+  fNGenerate = 0;
+  fNUsed = 0;
+  fNDigits = 0;
+  ResetROI();
+}
+
+
+AliHLTTPCMemHandler::~AliHLTTPCMemHandler()
+{
+  //Destructor
+  if(fPt) delete[] fPt;
+  if(fRandomDigits) delete [] fRandomDigits;
+  if(fDPt) delete [] fDPt;
+}
+
+void AliHLTTPCMemHandler::Init(Int_t s,Int_t p, Int_t *r)
+{
+  //init handler
+  fSlice=s;fPatch=p;
+  if(r) {
+    fRowMin=r[0];
+    fRowMax=r[1];
+  }else{
+     fRowMin=AliHLTTPCTransform::GetFirstRow(p);
+     fRowMax=AliHLTTPCTransform::GetLastRow(p); 
+  }
+  ResetROI();
+}
+
+void AliHLTTPCMemHandler::ResetROI()
+{
+  //Resets the Look-up table for Region of Interest mode.
+  for(Int_t i=fRowMin; i<=fRowMax; i++)
+    {
+      fEtaMinTimeBin[i] = 0;
+      fEtaMaxTimeBin[i] = AliHLTTPCTransform::GetNTimeBins()-1;
+    }
+}
+
+void AliHLTTPCMemHandler::SetROI(Float_t *eta,Int_t */*slice*/)
+{
+  // Init the Look-up table for the Region of Interest mode.
+  //   Here you can specify a certain etaregion, - all data
+  //   outside this region will be discarded:
+  //   eta[0] = mimium eta
+  //   eta[1] = maximum eta
+  //   slice[0] = mimumum slice
+  //   slice[1] = maximum slice
+
+
+  if(eta[1]==0)
+    {
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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] = AliHLTTPCTransform::Row2X(i);
+      xyz[1]=0;
+      xyz[2] = xyz[0]/tan(thetamax);
+      AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
+      AliHLTTPCTransform::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] = AliHLTTPCTransform::Row2X(i);
+         xyz[1] = AliHLTTPCTransform::GetMaxY(i);
+         Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
+         xyz[2] = radii/tan(thetamin);
+         AliHLTTPCTransform::Local2Raw(xyz,sector,row);
+         fEtaMaxTimeBin[i] = (Int_t)xyz[2];
+       }
+    }
+  
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryInput(char *name)
+{
+  //Set the input binary file.
+  fInBinary = fopen(name,"r");
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
+      <<"Error opening file "<<name<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryInput(FILE *file)
+{
+  //Set the input binary file.
+  fInBinary = file;
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
+    <<"Pointer to File = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+void AliHLTTPCMemHandler::CloseBinaryInput()
+{
+  //Close the input file.
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryInput","File Close")
+      <<"Nothing to Close"<<ENDLOG;
+    return;
+  }
+  fclose(fInBinary);
+  fInBinary =0;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryOutput(char *name)
+{
+  //Set the binary output file.
+    fOutBinary = fopen(name,"w");
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
+      <<"Pointer to File = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryOutput(FILE *file)
+{
+  //Set the binary output file.
+    fOutBinary = file;
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
+      <<"Pointer to File = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+void AliHLTTPCMemHandler::CloseBinaryOutput()
+{
+  //close binary  
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryOutPut","File Close")
+      <<"Nothing to Close"<<ENDLOG;
+    return;
+  }
+  fclose(fOutBinary);
+  fOutBinary =0;
+}
+
+UInt_t AliHLTTPCMemHandler::GetFileSize()
+{
+  //Returns the file size in bytes of the input file.
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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 *AliHLTTPCMemHandler::Allocate()
+{
+  //Allocate
+  return Allocate(GetFileSize()); 
+}
+
+Byte_t *AliHLTTPCMemHandler::Allocate(AliHLTTPCTrackArray *array)
+{
+  //Allocate memory for tracks in memory. Used by TrackArray2Binary()
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
+      <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  return Allocate(array->GetOutSize()); 
+}
+
+Byte_t *AliHLTTPCMemHandler::Allocate(UInt_t size)
+{
+  //Allocate memory of size in bytes.
+  if(fPt){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
+      <<"Delete Memory"<<ENDLOG;
+    Free();
+  } 
+  fPt = new Byte_t[size];
+  fSize = size;
+  memset(fPt,0,fSize);
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Allocate","Memory")
+  <<AliHLTTPCLog::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
+  return fPt;
+}
+
+void AliHLTTPCMemHandler::Free()
+{
+  //Clear the memory, if allocated.
+  if(!fPt){
+    //    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMemHandler::Free","Memory")
+    //      <<"No Memory allocated - can't Free"<<ENDLOG;
+    return;
+  }  
+  delete[] fPt;
+  fPt = 0;
+  fSize =0;
+}
+
+///////////////////////////////////////// Random
+void AliHLTTPCMemHandler::SetRandomSeed()
+{
+  //If you are adding random data to the original data.
+  time_t *tp=0;
+  SetRandomSeed(time(tp));
+}
+
+void AliHLTTPCMemHandler::SetRandomCluster(Int_t maxnumber)
+{
+  //If you are adding random data to the original data.
+  
+  fIsRandom = kTRUE;
+  fNRandom = maxnumber;
+  fNDigits = 0;
+  if(fRandomDigits) delete [] fRandomDigits;
+  fRandomDigits = new AliHLTTPCRandomDigitData[fNRandom*9];
+  if(fDPt) delete [] fDPt;
+  fDPt = new AliHLTTPCRandomDigitData *[fNRandom*9];
+}
+
+void AliHLTTPCMemHandler::QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last)
+{
+
+   // Sort array of AliHLTTPCRandomDigitData pointers using a quicksort algorithm.
+   // Uses CompareDigits() to compare objects.
+   // Thanks to Root!
+
+   static AliHLTTPCRandomDigitData *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 AliHLTTPCMemHandler::GetRandomSize() const
+{
+  //get random size
+  Int_t nrandom = 0;
+  for(Int_t r=fRowMin;r<=fRowMax;r++){
+    Int_t npad=AliHLTTPCTransform::GetNPads(r);
+    nrandom  += Int_t (fNGenerate * ((Double_t) npad/141.));
+  }
+  return 9 * nrandom * sizeof(AliHLTTPCDigitData);
+}
+
+void AliHLTTPCMemHandler::Generate(Int_t row)
+{
+  //Generate random data on row, if you didn't 
+  //ask for this, nothing happens here.
+  
+  if(!fIsRandom) return;
+  ResetRandom();
+  fNDigits = 0;
+  Int_t npad=AliHLTTPCTransform::GetNPads(row);
+  Int_t ntime = fEtaMaxTimeBin[row] - fEtaMinTimeBin[row];
+  Int_t nrandom  = Int_t (fNGenerate * ((Double_t) npad/141.) * 
+                         (Double_t) ntime/(Double_t) AliHLTTPCTransform::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*AliHLTTPCTransform::GetADCSat());
+    DigitizePoint(row,pad,time,charge);
+  }
+  QSort(fDPt,0,fNDigits);
+}
+
+
+void AliHLTTPCMemHandler::DigitizePoint(Int_t row, Int_t pad, 
+                                   Int_t time,Int_t charge)
+{
+  //Making one single random cluster.
+  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>=AliHLTTPCTransform::GetNPads(row))  continue;
+      if(dtime<0||dtime>=AliHLTTPCTransform::GetNTimeBins()) continue;
+      
+      fRandomDigits[fNDigits].fCharge = dcharge;
+      fRandomDigits[fNDigits].fRow = row;
+      fRandomDigits[fNDigits].fPad = dpad;
+      fRandomDigits[fNDigits].fTime = dtime;
+      fDPt[fNDigits] = &fRandomDigits[fNDigits];
+      fNDigits++;
+    }
+  }
+}
+
+///////////////////////////////////////// Digit IO  
+Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t nrow,AliHLTTPCDigitRowData *data)
+{
+  //Write data to the outputfile as is. No run-length encoding is done.
+  
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+      <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+      <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  
+  AliHLTTPCDigitRowData *rowPt = data; 
+  Int_t outsize = 0;
+  for(UInt_t i=0;i<nrow;i++){
+    Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit 
+      + sizeof(AliHLTTPCDigitRowData);
+    outsize += size;
+    fwrite(rowPt,size,1,fOutBinary);
+    Byte_t  *bytePt =(Byte_t *) rowPt;
+    bytePt += size;
+    rowPt = (AliHLTTPCDigitRowData *) bytePt;
+  }
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+    <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+    <<nrow<<" Rows)"<<ENDLOG;
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & nrow,AliHLTTPCDigitRowData *data)
+{
+  //Read inputfile into memory as is, and store it in data. 
+  // No run-length encoding is assumed.
+
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+      <<"No Input File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+      <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  rewind(fInBinary);
+  AliHLTTPCDigitRowData *rowPt = data;
+  UInt_t rowcount = 0;
+  Int_t outsize =0;
+  while(!feof(fInBinary)){
+    Byte_t  *bytePt =(Byte_t *) rowPt;
+
+    if(fread(rowPt,sizeof(AliHLTTPCDigitRowData),1,fInBinary)!=1) break;
+
+    bytePt += sizeof(AliHLTTPCDigitRowData);
+    outsize += sizeof(AliHLTTPCDigitRowData);
+
+    Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit;
+
+    //if(fread(bytePt,size,1,fInBinary)!=1) break;
+    fread(bytePt,size,1,fInBinary);
+    bytePt += size;
+    outsize += size;
+    rowPt = (AliHLTTPCDigitRowData *) bytePt;
+    rowcount++;
+  }  
+  nrow= rowcount;
+    LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+    <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+    <<rowcount<<" Rows)"<<ENDLOG;
+  return kTRUE;
+}
+
+void AliHLTTPCMemHandler::AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
+                             UInt_t /*row*/,UShort_t pad,UShort_t time,UShort_t charge) const
+{
+  //add some data
+  data[ndata].fPad = pad;
+  data[ndata].fTime = time;
+  data[ndata].fCharge = charge;
+  ndata++;
+}
+
+void AliHLTTPCMemHandler::AddRandom(AliHLTTPCDigitData *data, UInt_t & ndata)
+{
+  //add some random data
+  data[ndata].fPad = fDPt[fNUsed]->fPad;
+  data[ndata].fTime = fDPt[fNUsed]->fTime;
+  data[ndata].fCharge = fDPt[fNUsed]->fCharge;
+  ndata++;
+  fNUsed++;
+}
+
+void AliHLTTPCMemHandler::MergeDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
+                                     UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
+{
+  //merge random data
+  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>=AliHLTTPCTransform::GetADCSat()) ch = AliHLTTPCTransform::GetADCSat();
+    data[ndata].fCharge = ch;
+    fNUsed++;
+  }
+  ndata++;
+}
+
+void AliHLTTPCMemHandler::AddDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
+                   UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
+{
+  //add data random
+  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 AliHLTTPCMemHandler::Write(UInt_t *comp, UInt_t & index, 
+                           UInt_t & subindex, UShort_t value) const
+{
+  //write compressed data
+  UInt_t shift[3] = {0,10,20};
+  if(subindex==0) comp[index] =0; //clean up memory
+  comp[index] |= (value&0x03ff)<<shift[subindex];
+  if(subindex == 2){
+    subindex = 0;
+    index++;
+  }
+  else subindex++;
+}
+
+UShort_t AliHLTTPCMemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const
+{ 
+  //read compressed data
+  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 AliHLTTPCMemHandler::Test(UInt_t *comp, 
+                              UInt_t index, UInt_t  subindex) const
+{
+  //supi dupi test
+  UInt_t shift[3] = {0,10,20};
+  return (comp[index]>>shift[subindex])&0x03ff;
+}
+
+Int_t AliHLTTPCMemHandler::Memory2CompMemory(UInt_t nrow,
+                                        AliHLTTPCDigitRowData *data,UInt_t *comp)
+{
+  //Performs run-length encoding on data stored in memory pointed to by data.
+  //The compressed data is written to comp.
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
+      <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
+      <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  AliHLTTPCDigitRowData *rowPt = data;
+  UInt_t index=0;
+  UInt_t subindex=0;
+  
+  for(UInt_t i=0;i<nrow;i++){
+    UShort_t value = rowPt->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<rowPt->fNDigit;dig++){
+      if(rowPt->fDigitData[dig].fPad <200){ 
+        ddd[rowPt->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>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
+        continue;
+      Write(comp,index,subindex,pad);
+//    write zero if time != 0
+      if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+        if(rowPt->fDigitData[digit].fTime>0){
+          Write(comp,index,subindex,0);
+          Write(comp,index,subindex,rowPt->fDigitData[digit].fTime);
+        }
+      }
+      while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+        UShort_t charge = rowPt->fDigitData[digit].fCharge;
+        if(charge>=1023){
+          charge=1023;
+        }
+        Write(comp,index,subindex,charge);
+        if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
+          if(rowPt->fDigitData[digit].fTime +1 !=
+                     rowPt->fDigitData[digit+1].fTime){
+            Write(comp,index,subindex,0);
+            UShort_t nzero = rowPt->fDigitData[digit+1].fTime - 
+                             (rowPt->fDigitData[digit].fTime +1);
+            Write(comp,index,subindex,nzero);
+          }  
+        }
+        digit++;
+      }
+      Write(comp,index,subindex,0);
+      Write(comp,index,subindex,0);
+    }
+    
+    Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+                                            sizeof(AliHLTTPCDigitRowData);
+    Byte_t  *bytePt =(Byte_t *) rowPt;
+    bytePt += size;
+    rowPt = (AliHLTTPCDigitRowData *) bytePt;
+  }
+  while(subindex)
+    Write(comp,index,subindex,0);
+  return index * sizeof(UInt_t);
+}
+
+Int_t AliHLTTPCMemHandler::CompMemory2Memory(UInt_t  nrow,
+                                        AliHLTTPCDigitRowData *data,UInt_t *comp)
+{
+  //Uncompress the run-length encoded data in memory pointed to by comp, and
+  //  store it in data.
+
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2Memory","Memory")
+      <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2Memory","Memory")
+      <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  Int_t outsize=0;
+  
+  AliHLTTPCDigitRowData *rowPt = 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);
+    rowPt->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(rowPt->fDigitData,ndigit,row,pad,time,charge);
+           //seems we are using this function... but dont know why
+            AddDataRandom(rowPt->fDigitData,ndigit,row,pad,time,charge);
+          time++;
+        }
+        UShort_t tshift = Read(comp,index,subindex);
+        if(tshift == 0) break;
+        time += tshift;
+      }
+    }
+    rowPt->fNDigit = ndigit;
+    Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+      sizeof(AliHLTTPCDigitRowData);
+    Byte_t  *bytePt =(Byte_t *) rowPt;
+    bytePt += size;
+    outsize += size;
+    rowPt = (AliHLTTPCDigitRowData *) bytePt;
+  }
+  return outsize;
+}
+
+UInt_t AliHLTTPCMemHandler::GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const
+{
+  //Return the size of RLE data, after compressing data.
+  
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetCompMemorySize","Memory")
+      <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+    return 0;
+  }
+  AliHLTTPCDigitRowData *rowPt = 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<rowPt->fNDigit;dig++){
+      if(rowPt->fDigitData[dig].fPad <200){ 
+        ddd[rowPt->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>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
+        continue;
+      index++;
+      //    write zero if time != 0
+      if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+        if(rowPt->fDigitData[digit].fTime>0){
+          index++;
+          index++;
+        }
+      }
+      while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+        index++;
+        if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
+          if(rowPt->fDigitData[digit].fTime +1 !=
+                     rowPt->fDigitData[digit+1].fTime){
+            index++;
+            index++;
+          }  
+        }
+        digit++;
+      }
+      index++;
+      index++;
+    }
+
+    Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+                                            sizeof(AliHLTTPCDigitRowData);
+    Byte_t  *bytePt =(Byte_t *) rowPt;
+    bytePt += size;
+    rowPt = (AliHLTTPCDigitRowData *) bytePt;
+  }
+  while(index%3)
+    index++;
+  return (index/3) * sizeof(UInt_t);
+}
+
+UInt_t AliHLTTPCMemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const
+{
+  //get memory size
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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(AliHLTTPCDigitData) * ndigit+
+                                        sizeof(AliHLTTPCDigitRowData);
+    outsize += size;
+  }
+   
+  return outsize;
+}
+
+UInt_t AliHLTTPCMemHandler::GetNRow(UInt_t *comp,UInt_t size)
+{
+  //get number of rows
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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<size-1){ //don't start with last word
+    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==size-1){  //last word
+    if(subindex<2){
+      if(Read(comp,index,subindex)!=0) nrow++;
+    }
+  }
+  return nrow;
+}
+
+Bool_t AliHLTTPCMemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
+                                             UInt_t size)
+{
+  //Write the RLE data in comp to the output file.
+  
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","File")
+    <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
+    <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  if(size==0)
+    size=GetMemorySize(nrow,comp);
+  if(!size){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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 AliHLTTPCMemHandler::CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp)
+{
+  //Read the RLE data from file, and store it in comp. No unpacking yet.
+
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompBinary2CompMemory","File")
+      <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!comp){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::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;
+}
+
+AliHLTTPCDigitRowData *AliHLTTPCMemHandler::CompBinary2Memory(UInt_t & nrow)
+{
+  // Read the RLE inputfile, unpack it and return the pointer to it.
+  AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
+  handler->SetBinaryInput(fInBinary);
+  UInt_t *comp =(UInt_t *)handler->Allocate();
+  handler->CompBinary2CompMemory(nrow,comp);
+  UInt_t size = GetMemorySize(nrow,comp);
+  AliHLTTPCDigitRowData *data = (AliHLTTPCDigitRowData *)Allocate(size);
+  CompMemory2Memory(nrow,data,comp);
+  handler->Free();
+  delete handler;
+  return data;  
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data)
+{
+  //Perform RLE on the data, and write it to the output file.
+  Bool_t out = kTRUE;
+  AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
+  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 AliHLTTPCMemHandler::Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data)
+{
+  //Writing spacepoints stored in data to the outputfile.
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+      <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+      <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  UInt_t size = npoint*sizeof(AliHLTTPCSpacePointData);
+  fwrite(data,size,1,fOutBinary);
+  
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice)
+{
+  //Transform the space points in data, to global coordinates in slice.
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Transform","Memory")
+    <<"Pointer to AliHLTTPCSpacePointData = 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;
+    AliHLTTPCTransform::Local2Global(xyz,slice);
+    data[i].fX = xyz[0];
+    data[i].fY = xyz[1];
+    data[i].fZ = xyz[2];
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & npoint,AliHLTTPCSpacePointData *data)
+{
+  //Read the space points in inputfile, and store it in data.
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+    <<"No Input File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+    <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+
+  Int_t size = GetFileSize(); 
+  npoint = size/sizeof(AliHLTTPCSpacePointData);
+  if(size==0) {
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+    <<"File Size == 0"<<ENDLOG;
+    return kFALSE;
+  }
+
+  if(fread(data,size,1,fInBinary)!=1){
+    LOG(AliHLTTPCLog::kFatal,"AliHLTTPCMemHandler::Binary2Memory","File")
+    <<"File Read Error "<<ENDLOG;
+    return kFALSE;
+  }
+  if(size%sizeof(AliHLTTPCSpacePointData)){
+    LOG(AliHLTTPCLog::kFatal,"AliHLTTPCMemHandler::Binary2Memory","File Size")
+    <<"File Size wrong "<<ENDLOG;
+    return kFALSE; 
+  }
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","File")
+  <<AliHLTTPCLog::kDec<<"Wrote  "<<size<<" Bytes to Memory"<<ENDLOG;
+  return kTRUE;
+}
+
+///////////////////////////////////////// Track IO  
+Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t ntrack,AliHLTTPCTrackSegmentData *data)
+{
+  //Write the tracks stored in data, to outputfile.
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+    <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+    <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  AliHLTTPCTrackSegmentData *trackPt = data;
+  for(UInt_t i=0;i<ntrack;i++){
+    Int_t size=sizeof(AliHLTTPCTrackSegmentData)+trackPt->fNPoints*sizeof(UInt_t); 
+    fwrite(trackPt,size,1,fOutBinary);
+    Byte_t *bytePt = (Byte_t*) trackPt;
+    bytePt += size; 
+    trackPt = (AliHLTTPCTrackSegmentData*) bytePt;
+  }
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","File")
+  <<AliHLTTPCLog::kDec<<"Wrote  "<<ntrack<<" Tracks to File"<<ENDLOG;
+  
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data)
+{
+  //Read the tracks in inputfile, and store it in data.
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+    <<"No Input File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+    <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+
+  ntrack=0;
+  AliHLTTPCTrackSegmentData *trackPt = data;
+  rewind(fInBinary);
+
+  while(!feof(fInBinary)){
+    if(fread(trackPt,sizeof(AliHLTTPCTrackSegmentData),1,fInBinary)!=1) break;
+    Int_t size=trackPt->fNPoints*sizeof(UInt_t);
+    if(fread(trackPt->fPointIDs,size,1,fInBinary)!=1) break;
+    Byte_t *bytePt = (Byte_t*) trackPt;
+    bytePt += sizeof(AliHLTTPCTrackSegmentData)+size;
+    trackPt = (AliHLTTPCTrackSegmentData*) bytePt;
+    ntrack++; 
+  }
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","File")
+  <<AliHLTTPCLog::kDec<<"Wrote  "<<ntrack<<" Tracks to Memory"<<ENDLOG;
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::TrackArray2Binary(AliHLTTPCTrackArray *array)
+{
+  //Write the trackarray to the outputfile.
+  if(!fOutBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Binary","File")
+    <<"No Output File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Binary","Memory")
+    <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  AliHLTTPCTrackSegmentData *data = (AliHLTTPCTrackSegmentData *)Allocate(array);
+
+  UInt_t ntrack;
+  TrackArray2Memory(ntrack,data,array);
+  Memory2Binary(ntrack,data);
+  Free();
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2TrackArray(AliHLTTPCTrackArray *array)
+{
+  //Read the tracks in inputfile, and fill it in trackarray. 
+  //array should already be constructed.
+  if(!fInBinary){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2TrackArray","File")
+    <<"No Input File"<<ENDLOG;
+    return kFALSE;
+  }
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2TrackArray","Memory")
+    <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  AliHLTTPCTrackSegmentData *data = (AliHLTTPCTrackSegmentData *)Allocate();
+  UInt_t ntrack;
+  Binary2Memory(ntrack,data);
+  Memory2TrackArray(ntrack,data,array);  
+  Free();
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::TrackArray2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const
+{
+  //Fill the trackarray into the AliTrackSegmentData structures before writing to outputfile.
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Memory","Memory")
+    <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Memory","Memory")
+    <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+
+  array->WriteTracks(ntrack,data);
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const
+{
+  //Fill the tracks in data into trackarray.
+  
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+    <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+    <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  array->FillTracks(ntrack,data);
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array,Int_t slice) const
+{
+  //Fill the tracks in data into trackarray, and rotate the tracks to global coordinates.
+    
+  if(!data){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+    <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  if(!array){
+    LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+    <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+    return kFALSE;
+  }
+  array->FillTracks(ntrack,data,slice);
+  return kTRUE;
+}
+
+void AliHLTTPCMemHandler::UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt)
+{
+  //Update the data pointer to the next padrow in memory.
+  
+  Byte_t *tmp = (Byte_t*)tempPt;
+  Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+  tmp += size;
+  tempPt = (AliHLTTPCDigitRowData*)tmp;
+}
+
+Int_t  AliHLTTPCMemHandler::ComparePoints(UInt_t /*row*/,UShort_t pad,UShort_t time) const
+{
+  //compare two points
+  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;
+}
+
+Int_t AliHLTTPCMemHandler::CompareDigits(AliHLTTPCRandomDigitData *a,AliHLTTPCRandomDigitData *b) const
+{
+  //compare two digits
+  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;
+}
diff --git a/HLT/TPCLib/AliHLTTPCMemHandler.h b/HLT/TPCLib/AliHLTTPCMemHandler.h
new file mode 100644 (file)
index 0000000..7e9b183
--- /dev/null
@@ -0,0 +1,219 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_MEMHANDLER_H
+#define ALIHLTTPC_MEMHANDLER_H
+
+//_____________________________________________________________
+// AliHLTTPCMemHandler
+//
+// The HLT Binary File handler 
+//
+//  This class does all the memory I/O handling of HLT binary files.
+//  
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, 
+//         Anders Vestbo <mailto:vestbo$fi.uib.no>, 
+//         Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+// *-- Copyright &copy ALICE HLT Group 
+
+class AliHLTTPCDigitData;
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCTrackArray;
+class AliHLTTPCRandomPointData;
+class AliHLTTPCRandomDigitData;
+
+#ifdef use_newio
+class AliRunLoader;
+class AliRawEvent;
+#endif
+class AliTPCRawStream;
+
+class AliHLTTPCMemHandler { 
+
+ public:
+  AliHLTTPCMemHandler();
+  virtual ~AliHLTTPCMemHandler();
+  AliHLTTPCMemHandler(const AliHLTTPCMemHandler& /*m*/){};
+  AliHLTTPCMemHandler& operator=(const AliHLTTPCMemHandler& /*&m*/)
+    {return (*this);}
+   
+  void Reset(){CloseBinaryInput();CloseBinaryOutput();Free();}  
+  void Init(Int_t s,Int_t p, Int_t *r=0);
+
+  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,AliHLTTPCDigitRowData *data);
+  Bool_t Binary2Memory(UInt_t & nrow,AliHLTTPCDigitRowData *data);
+
+  Int_t Memory2CompMemory(UInt_t nrow,AliHLTTPCDigitRowData *data,UInt_t *comp);
+  Int_t CompMemory2Memory(UInt_t nrow,AliHLTTPCDigitRowData *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);
+
+  virtual AliHLTTPCDigitRowData *CompBinary2Memory(UInt_t & nrow);
+  virtual Bool_t Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data);
+  
+  UInt_t GetNRow(UInt_t *comp,UInt_t size);
+
+  //Point IO
+  Bool_t Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data);
+  Bool_t Binary2Memory(UInt_t & npoint,AliHLTTPCSpacePointData *data);
+  Bool_t Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice);
+  static void UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt);
+  
+  //Track IO
+  Bool_t Memory2Binary(UInt_t ntrack,AliHLTTPCTrackSegmentData *data);
+  Bool_t Binary2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data);
+  Bool_t TrackArray2Binary(AliHLTTPCTrackArray *array);
+  Bool_t Binary2TrackArray(AliHLTTPCTrackArray *array);
+  Bool_t TrackArray2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const;
+  Bool_t Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const;
+  Bool_t Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array,Int_t slice) const;
+    
+  //Memory Allocation
+  UInt_t GetAllocatedSize() const {return fSize;}  
+  UInt_t GetFileSize();
+  UInt_t GetMemorySize(UInt_t nrow,UInt_t *comp) const;
+  UInt_t GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const;
+  UInt_t GetRandomSize() const;
+
+  Byte_t *Allocate(UInt_t size);
+  Byte_t *Allocate();  // allocate size of Binary Input File
+  Byte_t *Allocate(AliHLTTPCTrackArray *array);
+  Byte_t *GetDataPointer(UInt_t &size) {size = fSize; return fPt;}
+  FILE *GetFilePointer() {return fInBinary;}
+  void   Free();
+  
+  //Getters:
+  Int_t GetRowMin() const {return fRowMin;}
+  Int_t GetRowMax() const {return fRowMax;}
+  Int_t GetSlice() const {return fSlice;}
+  Int_t GetPatch() const {return fPatch;}
+  
+  //virtual functions:
+  virtual void FreeDigitsTree() {fDummy=0; return;}
+  virtual Bool_t SetAliInput(char */*name*/){fDummy=0; return 0;}
+#ifdef use_newio
+  virtual Bool_t SetAliInput(AliRunLoader */*runloader*/){fDummy=0; return 0;}
+#endif
+  virtual void CloseAliInput(){fDummy=0; return;} 
+  virtual Bool_t IsDigit(Int_t /*i*/=0){fDummy=0; return 0;}
+  virtual Bool_t SetMCOutput(char */*name*/){fDummy=0; return 0;}
+  virtual Bool_t SetMCOutput(FILE */*file*/){fDummy=0; return 0;}
+  virtual void CloseMCOutput(){fDummy=0; return;}
+  virtual Bool_t AliDigits2Binary(Int_t /*event*/=0,Bool_t /*altro*/=kFALSE){fDummy=0; return 0;}
+  virtual Bool_t AliDigits2CompBinary(Int_t /*event*/=0,Bool_t /*altro*/=kFALSE){fDummy=0; return 0;}  
+  virtual AliHLTTPCDigitRowData *AliDigits2Memory(UInt_t & /*nrow*/,Int_t /*event*/=0){fDummy=0; return 0;}
+  virtual AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & /*nrow*/,Int_t /*event*/=0,Bool_t /*eventmerge*/=kFALSE){fDummy=0; return 0;}
+  virtual void AliDigits2RootFile(AliHLTTPCDigitRowData */*rowPt*/,Char_t */*new_digitsfile*/){fDummy=0; return;}
+  virtual Bool_t AliPoints2Binary(Int_t /*eventn*/=0){fDummy=0; return 0;}
+  virtual AliHLTTPCSpacePointData *AliPoints2Memory(UInt_t & /*npoint*/,Int_t /*eventn*/=0){fDummy=0; return 0;}
+
+  //AliHLTTPCRawDataFileHandler
+  virtual Bool_t SetRawInput(Char_t */*name*/){fDummy=0; return 0;}
+  virtual Bool_t SetRawInput(ifstream */*file*/){fDummy=0; return 0;}
+  virtual void CloseRawInput(){} 
+  virtual Int_t ReadRawInput(){fDummy=0; return 0;}
+  virtual Short_t** GetRawData(Int_t &/*channels*/, Int_t & /*timebins*/){fDummy=0; return 0;}
+
+  virtual Bool_t SetRawOutput(Char_t */*name*/){fDummy=0; return 0;}
+  virtual Bool_t SetRawOutput(ofstream */*file*/){fDummy=0; return 0;}
+  virtual void CloseRawOutput(){} 
+  virtual Bool_t SaveRawOutput(){fDummy=0; return 0;}
+
+  virtual Bool_t SetMappingFile(Char_t */*name*/){fDummy=0; return 0;}
+  virtual Bool_t SetMappingFile(FILE */*file*/){fDummy=0; return 0;}
+  virtual void CloseMappingFile(){} 
+  virtual Int_t ReadMappingFile(){fDummy=0; return 0;}
+  
+  virtual Bool_t SetRawPedestalsInput(Char_t */*name*/){fDummy=0; return 0;}
+  virtual Bool_t SetRawPedestalsInput(ifstream */*file*/){fDummy=0; return 0;}
+  virtual void CloseRawPedestalsInput(){} 
+  virtual Int_t ReadRawPedestalsInput(){fDummy=0; return 0;}
+
+  virtual AliHLTTPCDigitRowData* RawData2Memory(UInt_t &/*nrow*/,Int_t /*event*/=-1){fDummy=0; return 0;}
+  virtual Bool_t RawData2CompMemory(Int_t /*event*/=-1){fDummy=0; return 0;}
+
+  //AliHLTTPCDDLDataFileHandler
+#ifdef use_newio
+  virtual Bool_t SetReaderInput(AliRawEvent */*rawevent*/){fDummy=0; return 0;}
+  virtual Bool_t SetReaderInput(Char_t */*name*/,Int_t /*event*/=0){fDummy=0; return 0;}
+#else
+  virtual Bool_t SetReaderInput(Char_t */*name*/,Bool_t /*add*/=kTRUE){fDummy=0; return 0;}
+#endif
+  virtual void CloseReaderInput(){};
+
+  virtual AliHLTTPCDigitRowData* DDLData2Memory(UInt_t &/*nrow*/,Int_t /*event*/=-1){fDummy=0; return 0;}
+  virtual Bool_t DDLData2CompBinary(Int_t /*event*/=-1){fDummy=0; return 0;}
+
+  virtual AliTPCRawStream* GetTPCRawStream(){fDummy=0; return 0;}
+
+ protected:
+  Int_t fRowMin; //min row
+  Int_t fRowMax; //max row
+  Int_t fSlice;  //slice
+  Int_t fPatch;  //patch
+
+  Int_t fEtaMinTimeBin[159]; //for ROI in eta only
+  Int_t fEtaMaxTimeBin[159]; //for ROI in eta only
+  
+  FILE *fInBinary;//!
+  FILE *fOutBinary;//!
+
+ private:
+  
+  Byte_t *fPt;//!
+  UInt_t fSize; //size of allocated data structure
+
+  Bool_t fIsRandom; //random data generated
+  Int_t fNRandom;   //count random digits 
+  Int_t fNGenerate; //count generated digits
+  Int_t fNUsed;     //count used digits
+  Int_t fNDigits;   //count digits from digitstree
+
+  AliHLTTPCRandomDigitData **fDPt;//!
+  AliHLTTPCRandomDigitData *fRandomDigits;//!
+
+  Int_t fDummy; // to fool the virtual const problem 
+                // of the coding conventions tool
+
+  void Write(UInt_t *comp, UInt_t & index, UInt_t & subindex, UShort_t value) const;
+  UShort_t Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const;
+  UShort_t Test(UInt_t *comp, UInt_t index, UInt_t subindex) const; 
+  
+  void DigitizePoint(Int_t row,Int_t pad, Int_t time,Int_t charge);
+  void QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last);
+  Int_t ComparePoints(UInt_t row,UShort_t pad,UShort_t time) const ;
+  Int_t CompareDigits(AliHLTTPCRandomDigitData *a,AliHLTTPCRandomDigitData *b) const;
+  void AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
+                      UInt_t row,UShort_t pad,UShort_t time,UShort_t charge) const;
+  void AddRandom(AliHLTTPCDigitData *data,UInt_t & ndata);
+  void MergeDataRandom(AliHLTTPCDigitData *data,UInt_t & ndata,
+                      UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+  void AddDataRandom(AliHLTTPCDigitData *data,UInt_t & ndata,
+                      UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+
+
+  ClassDef(AliHLTTPCMemHandler,1) // Memory handler class
+};
+#endif
diff --git a/HLT/TPCLib/AliHLTTPCMerger.cxx b/HLT/TPCLib/AliHLTTPCMerger.cxx
new file mode 100644 (file)
index 0000000..8d4864a
--- /dev/null
@@ -0,0 +1,520 @@
+//$Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy Uli 
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+#ifdef use_root //use root ntuple for slow merge
+#include <TNtuple.h>
+#include <TTree.h>
+#include <TFile.h>
+#endif
+
+/** \class AliHLTTPCMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCMerger
+//
+// The HLTTPC merger base class
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCMerger)
+
+AliHLTTPCMerger::AliHLTTPCMerger()
+{
+  //Default constructor
+  fInTrack=0;
+  fOutTrack=0;
+  fCurrentTracks=0;
+  fNIn=0;
+}
+
+AliHLTTPCMerger::~AliHLTTPCMerger()
+{
+  //Destructor
+  DeleteArray();
+}
+
+void AliHLTTPCMerger::InitMerger(Int_t ntrackarrays,Char_t *tracktype)
+{
+  //Used to setup all arrays
+  
+  if(strcmp(tracktype,"AliHLTTPCTrack")==0) fTrackType='t';
+  else if(strcmp(tracktype,"AliHLTTPCConfMapTrack")==0) fTrackType='c';
+#ifdef INCLUDE_TPC_HOUGH
+  else if(strcmp(tracktype,"AliHLTTPCHoughTrack")==0) fTrackType='h';
+#endif
+  else
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCMerger::AliHLTTPCMerger","Track types")
+      <<"Unknown tracktype"<<ENDLOG;
+  SetArray(ntrackarrays);
+  fCurrentTracks=0;
+
+}
+
+void AliHLTTPCMerger::DeleteArray()
+{
+  //delete arrays
+  for(Int_t i=0; i<fNIn;i++)
+    {
+      if(!fInTrack[i]) continue;
+      delete fInTrack[i];
+      fInTrack[i]=0;
+    }
+  if(fInTrack)
+    delete[] fInTrack;
+  if(fOutTrack)
+    delete fOutTrack;
+  fInTrack=0;
+  fOutTrack=0;
+}
+
+void AliHLTTPCMerger::SetArray(Int_t nin)
+{ 
+  //set arrays
+  DeleteArray();//Make sure arrays are cleaned 
+  
+  fNIn = nin;
+  fInTrack = new AliHLTTPCTrackArray*[fNIn];
+  for(Int_t i=0; i<fNIn;i++)
+    {
+#ifdef INCLUDE_TPC_HOUGH
+      if(fTrackType=='h')
+       fInTrack[i] = new AliHLTTPCTrackArray("AliHLTTPCHoughTrack");
+      else
+#endif
+       fInTrack[i] = new AliHLTTPCTrackArray("AliHLTTPCTrack");
+      
+    }
+#ifdef INCLUDE_TPC_HOUGH
+  if(fTrackType=='h')
+    fOutTrack= new AliHLTTPCTrackArray("AliHLTTPCHoughTrack");
+  else
+#endif
+    fOutTrack= new AliHLTTPCTrackArray("AliHLTTPCTrack");
+}
+
+void AliHLTTPCMerger::Reset()
+{ 
+  //reset
+  for(Int_t i=0; i<fNIn;i++)
+    {
+      fInTrack[i]->Reset();
+    }
+  fOutTrack->Reset();
+}
+
+void AliHLTTPCMerger::FillTracks(Int_t ntracks, AliHLTTPCTrackSegmentData* tr)
+{
+  //Read tracks from shared memory (or memory)
+  AliHLTTPCTrackArray *destination = GetInTracks(fCurrentTracks);
+  if(Is2Global())
+    destination->FillTracks(ntracks, tr, fSlice);
+  else
+    destination->FillTracks(ntracks, tr);
+}
+
+void AliHLTTPCMerger::AddAllTracks()
+{ 
+  //add all tracks
+  for(Int_t i=0; i<GetNIn();i++)
+    {
+      AliHLTTPCTrackArray *in = GetInTracks(i);
+      AliHLTTPCTrackArray *out = GetOutTracks();
+      out->AddTracks(in);
+    }
+}
+
+void AliHLTTPCMerger::SortGlobalTracks(AliHLTTPCTrack **tracks, Int_t ntrack)
+{ 
+  //sort global tracks
+  AliHLTTPCTrack **tmp = new AliHLTTPCTrack*[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 AliHLTTPCMerger::SortTracks(AliHLTTPCTrack **tracks, Int_t ntrack) const
+{ 
+  //sort tracks
+  AliHLTTPCTrack **tmp = new  AliHLTTPCTrack*[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 AliHLTTPCMerger::AddTrack(AliHLTTPCTrackArray *mergedtrack,AliHLTTPCTrack *track)
+{ 
+  // add tracks
+  AliHLTTPCTrack *t[1];
+  t[0] = track;
+  MultiMerge(mergedtrack,t,1);
+}
+
+AliHLTTPCTrack * AliHLTTPCMerger::MergeTracks(AliHLTTPCTrackArray *mergedtrack,AliHLTTPCTrack *t0,AliHLTTPCTrack *t1)
+{ 
+  //merge tracks
+  AliHLTTPCTrack *t[2];
+  t[0] = t0; 
+  t[1] = t1;
+  SortTracks(t,2);
+  return MultiMerge(mergedtrack,t,2);
+}
+
+AliHLTTPCTrack * AliHLTTPCMerger::MultiMerge(AliHLTTPCTrackArray *mergedtracks,AliHLTTPCTrack **tracks, Int_t ntrack)
+{
+  //multi merge the tracks
+  //check npoints
+  Int_t nps = 0;
+  for(Int_t i=0;i<ntrack;i++)
+    {
+      nps+=tracks[i]->GetNHits();
+    }
+  if(nps>AliHLTTPCTransform::GetNRows())
+    {
+      LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMerger::MultiMerge","Adding Points")
+       <<AliHLTTPCLog::kDec<<"Too many Points: "<<nps<<ENDLOG;
+      return 0;
+    }
+  
+  //create new track
+  AliHLTTPCTrack *newtrack = mergedtracks->NextTrack();
+  //copy points
+  UInt_t * nn = new UInt_t[AliHLTTPCTransform::GetNRows()];
+  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();
+    }
+  AliHLTTPCTrack *tpf=tracks[0];
+  AliHLTTPCTrack *tpl=tracks[ntrack-1];
+  AliHLTTPCTrack *best = tpf;
+  if(tpf->GetNHits()<tpl->GetNHits() && Is2Global())
+    best = tpl;//Best means = most points and therefore best fit (in global case)
+  
+  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(best->GetPt());
+  newtrack->SetPsi(best->GetPsi());
+  newtrack->SetTgl(best->GetTgl());
+  newtrack->SetCharge(tpf->GetCharge());
+  delete [] nn;
+  return newtrack;
+}
+
+void* AliHLTTPCMerger::GetNtuple(char *varlist) const
+{ 
+  //get ntuple
+#ifdef use_root
+  TNtuple* nt = new TNtuple("ntuple","ntuple",varlist);
+  return (void*) nt;
+#else
+  return 0;
+#endif
+}
+
+void* AliHLTTPCMerger::GetNtuple() const
+{ 
+  //get ntuple
+#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 AliHLTTPCMerger::WriteNtuple(char *filename, void* nt) const
+{ 
+  //write ntuple
+#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 AliHLTTPCMerger::FillNtuple(void *nt,AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{ 
+  //fill ntuple
+  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>AliHLTTPCTransform::Pi()) psi-=AliHLTTPCTransform::TwoPi();
+      else if(psi<-AliHLTTPCTransform::Pi()) psi+=AliHLTTPCTransform::TwoPi();
+      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));
+      data[14]=0;
+      data[15]=0;
+      data[16]=0;
+#ifdef use_root
+      TNtuple *ntuple = (TNtuple *) nt;
+      ntuple->Fill(data);
+#endif
+    }
+}
+
+void AliHLTTPCMerger::FillNtuple(void *nt,Float_t *data) const
+{ 
+  //fill ntuple
+#ifdef use_root
+  TNtuple *ntuple = (TNtuple *) nt;
+  ntuple->Fill(data);
+#endif
+}
+
+Double_t AliHLTTPCMerger::GetAngle(Double_t a1,Double_t a2)
+{ 
+  //get angle
+  Double_t da = a1 - a2 + 4*AliHLTTPCTransform::Pi();
+  da = fmod(da,AliHLTTPCTransform::TwoPi());
+  if(da>AliHLTTPCTransform::Pi()) da = AliHLTTPCTransform::TwoPi()-da;
+  return da;
+}
+
+void AliHLTTPCMerger::SetParameter(Double_t maxy, Double_t maxz, Double_t maxkappa, Double_t maxpsi, Double_t maxtgl)
+{ 
+  //set parameters for merger
+  fMaxY = maxy;
+  fMaxZ = maxz;
+  fMaxKappa = maxkappa;
+  fMaxPsi = maxpsi;
+  fMaxTgl = maxtgl;
+}
+
+Bool_t AliHLTTPCMerger::IsTrack(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+  //is track to be merged
+  if(innertrack->GetCharge()!=outertrack->GetCharge()) return kFALSE;
+  if( (!innertrack->IsPoint()) || (!outertrack->IsPoint()) )  return kFALSE; 
+  if(innertrack->GetNHits()+outertrack->GetNHits()>AliHLTTPCTransform::GetNRows()) 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 AliHLTTPCMerger::IsRTrack(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{ 
+  //same as IsTrack
+  return IsTrack(innertrack,outertrack);
+}
+
+Double_t AliHLTTPCMerger::TrackDiff(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{ 
+  //return track difference
+  Double_t diff =-1;
+  Double_t x[4],y[4],z[4],dy[4],dz[4];
+  AliHLTTPCTrack *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 AliHLTTPCMerger::PrintDiff(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{ 
+  // print difference
+  if(!innertrack->IsPoint()||!outertrack->IsPoint())
+    {
+      LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMerger::PrintDiff","No Points")<<ENDLOG;
+      //cerr<<"AliHLTTPCMerger::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>AliHLTTPCTransform::Pi()) dpsi-=AliHLTTPCTransform::TwoPi();
+  else if(dpsi<-AliHLTTPCTransform::Pi())dpsi+=AliHLTTPCTransform::TwoPi();
+  //Double_t dpsi = GetAngle(innertrack->GetPointPsi(),outertrack->GetPointPsi());
+  Double_t dtgl= innertrack->GetTgl()-outertrack->GetTgl();
+  Double_t dq =innertrack->GetCharge()-outertrack->GetCharge();
+  
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMerger::PrintDiff","Points") <<"dx: "<<dx<<" dy: "<<dy<<" dz: "<<dz<<" dk: "<<dk<<" dpsi: "<<dpsi<<" dtgl: "<<dtgl<<" dq: "<<dq<<ENDLOG;
+  //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;
+  
+}
+
+void AliHLTTPCMerger::Print()
+{
+  // print some infos
+  for(Int_t i=0; i<fNIn; i++)
+    {
+      AliHLTTPCTrackArray *ttt= GetInTracks(i);
+      for(Int_t j =0;j<ttt->GetNTracks();j++)
+       {
+         AliHLTTPCTrack *track=ttt->GetCheckedTrack(j);
+         if(!track) continue;
+         track->CalculateHelix();
+         //      Double_t angle = atan2(track->GetLastPointY(),track->GetLastPointX());
+         //      if(angle<0) angle+=AliHLTTPCTransform::Pi();
+         if(track->CalculatePoint(135))
+           //      if(!track->CalculateEdgePoint(angle)) cerr<<"**************"<<endl;     
+           //      if(track->CalculatePoint(track->GetLastPointX()))
+           //      if(track->CalculatePoint(0))
+           {
+             //      PrintTrack(track);
+             //      track->CalculateReferencePoint(AliHLTTPCTransform::Pi()/180.);
+             track->CalculateReferencePoint(0.001);
+             Float_t dx=(float)track->GetPointX()-track->GetPointX();
+             Float_t dy=(float)track->GetPointY()-track->GetPointY();
+             Float_t dz=(float)track->GetPointZ()-track->GetPointZ();
+             LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMerger::Print","RefPoint") <<"npt: "<<track->GetNHits()<<" dx: "<<dx<<" dy: "<<dy<<" dz: "<<dz<<ENDLOG;
+             
+             //fprintf(stderr,"npt: %3d dx: %8.5f dy: %8.5f dz: %8.5f\n",track->GetNHits(),dx,dy,dz);
+             //cerr<<"---------------------------"<<endl;
+           }
+       }  
+    }
+}
+
+void AliHLTTPCMerger::PrintTrack(AliHLTTPCTrack *track)
+{ 
+  //print track info
+  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(),
+     &nb