Added files for the reference version based on an old version of Anders'
authortimms <timms@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 7 Sep 2005 12:32:23 +0000 (12:32 +0000)
committertimms <timms@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 7 Sep 2005 12:32:23 +0000 (12:32 +0000)
code, prior to its commit to CVS. This version is intended just as a
reference for the component library version based on the code from the CVS
one direcrory level up. This is because the tracker in this version finds
approx. double as many tracks as the one in the CVS based version.

108 files changed:
HLT/TPCLib/Ref/AliHLTTPC.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPC.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCBenchmark.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCBenchmark.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClusterDataFormat.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClusterFitter.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCClusterFitter.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCCompress.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCCompress.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapFit.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapFit.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapPoint.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapPoint.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapTrack.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapTrack.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapper.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCConfMapper.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLDataFileHandler.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLDataFileHandler.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDataCompressor.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDataCompressor.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDataCompressorHelper.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDataCompressorHelper.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDefinitions.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDefinitions.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDigitData.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDisplay.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCDisplay.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCFileHandler.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCFileHandler.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCFitUtilities.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCFitter.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCFitter.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCGlobalMerger.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCGlobalMerger.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCGlobalMergerComponent.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCGlobalMergerComponent.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHistogram.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHistogram.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHistogramAdaptive.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHistogramAdaptive.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughBaseTransformer.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughBaseTransformer.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughTrack.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughTrack.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughTransformerRow.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCHoughTransformerRow.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCInterMerger.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCInterMerger.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCLog.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCLog.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCLogging.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCMemHandler.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCMemHandler.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCMerger.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCMerger.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCModelTrack.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCModelTrack.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCModeller.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCModeller.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCModels.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRawDataFormat.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRawDataUnpackerComponent.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRawDataUnpackerComponent.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRefLinkDef.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRefStandardIncludes.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCRootTypes.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCSliceTrackerComponent.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCSliceTrackerComponent.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCSpacePointData.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCStandardIncludes.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCStopwatch.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCStopwatch.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrack.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrack.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackArray.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackArray.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackMerger.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackMerger.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackSegmentData.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTrackletDataFormat.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTransform.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCTransform.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertex.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertex.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexArray.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexArray.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexData.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexFinder.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexFinder.h [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexFinderComponent.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/AliHLTTPCVertexFinderComponent.h [new file with mode: 0644]
HLT/TPCLib/Ref/Makefile [new file with mode: 0644]
HLT/TPCLib/Ref/README [new file with mode: 0644]
HLT/TPCLib/Ref/bitio.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/bitio.h [new file with mode: 0644]
HLT/TPCLib/Ref/errhand.cxx [new file with mode: 0644]
HLT/TPCLib/Ref/errhand.h [new file with mode: 0644]

diff --git a/HLT/TPCLib/Ref/AliHLTTPC.cxx b/HLT/TPCLib/Ref/AliHLTTPC.cxx
new file mode 100644 (file)
index 0000000..d5dcb79
--- /dev/null
@@ -0,0 +1,616 @@
+// @(#) $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
+
+#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 Level3 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::fSetTracks2FirstPoint = kTRUE;//Define track parameters at first point
+
+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.
+  
+  fInputFile=0;
+}
+
+AliHLTTPC::AliHLTTPC(Char_t *infile)
+{
+  //Constructor to use for when input is anything else but binary files,
+  //meaning rootfiles or raw files.
+  
+  fInputFile = infile;
+
+}
+
+void AliHLTTPC::Init(Char_t *path,EFileType filetype,Int_t npatches)
+{
+  if((filetype!=kBinary) && (filetype!=kDate) && !fInputFile)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+       <<"You have not supplied the input rootfile; use the appropriate ctor!"<<ENDLOG;
+      return;
+    }
+  
+  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;
+
+  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();
+    fFileHandler->SetAliInput(fInputFile);
+  }else if(filetype==kRaw){
+    fFileHandler = new AliHLTTPCDDLDataFileHandler();
+    fFileHandler->SetReaderInput(fInputFile);
+  }else if(filetype==kDate){
+    fFileHandler = new AliHLTTPCDDLDataFileHandler();
+    fFileHandler->SetReaderInput(fInputFile,-1);
+  }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){
+  fBenchmark->Analyze(name);
+  delete fBenchmark;
+  fBenchmark = new AliHLTTPCBenchmark();
+}
+
+void AliHLTTPC::DoMc(char* file){
+#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)
+{
+  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)
+{
+  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);
+  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){
+  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 maxpoints=120000;
+  const Int_t pointsize = maxpoints * 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(pointsize);
+      fClusterFinder = new AliHLTTPCClustFinderNew();
+      fClusterFinder->InitSlice(slice,patch,fRow[patch][0],fRow[patch][1],maxpoints);
+      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()
+{
+  AliHLTTPCFitter *fitter = new AliHLTTPCFitter(fVertex);
+  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);
+      fitter->UpdateTrack(tr);
+    }
+  fBenchmark->Stop("Global track fitter");
+  delete fitter;
+}
+
+void AliHLTTPC::WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+                                Int_t slice,Int_t patch)
+{
+  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)
+{
+  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();
+  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/Ref/AliHLTTPC.h b/HLT/TPCLib/Ref/AliHLTTPC.h
new file mode 100644 (file)
index 0000000..bb11dd6
--- /dev/null
@@ -0,0 +1,129 @@
+// @(#) $Id$
+
+#ifndef ALILEVEL3_H
+#define ALILEVEL3_H
+
+#ifndef no_root
+#include <TObject.h>
+#include <TFile.h>
+#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;
+  AliHLTTPCTrackSegmentData* fTrackData; //!
+  AliHLTTPCConfMapper *fTracker; //!
+  AliHLTTPCVertex *fVertex; //! 
+  AliHLTTPCVertexFinder *fVertexFinder; //!
+  AliHLTTPCTrackMerger *fTrackMerger; //!
+  AliHLTTPCGlobalMerger *fGlobalMerger; //!
+  AliHLTTPCInterMerger *fInterMerger; //!
+  AliHLTTPCClustFinderNew *fClusterFinder; //! 
+  AliHLTTPCMemHandler *fFileHandler; //!
+  AliHLTTPCBenchmark *fBenchmark;//!
+
+  Int_t fEvent;
+  Int_t fNPatch;
+  Int_t fRow[6][2];
+  Float_t fEta[2];
+  
+  Char_t *fInputFile;//!
+
+  Char_t fPath[256];
+  Char_t fWriteOutPath[256];
+  
+  Bool_t fDoRoi;
+  Bool_t fFindVertex;
+  Bool_t fDoNonVertex;
+  Bool_t fPileUp;
+  Bool_t fNoCF;
+  
+  Bool_t fUseBinary;
+  Bool_t fWriteOut;
+  
+  //Define whether track parameters should be given at first point on track (default)
+  //If not, the parameters will be given at the vertex.
+  static Bool_t fSetTracks2FirstPoint; 
+
+  Bool_t fClusterDeconv;
+  Float_t fXYClusterError;
+  Float_t fZClusterError;
+
+
+  void WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+                                          Int_t slice,Int_t patch);
+  Int_t WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt='o');  
+  void WriteResults();
+  void FitGlobalTracks();
+  void SetPath(char *p){sprintf(fPath,"%s",p);}
+
+ public:
+  AliHLTTPC ();
+  AliHLTTPC(Char_t *infile);
+  virtual ~AliHLTTPC();
+  enum EFileType {kBinary, kBinary8, kRoot, kRaw, kDate};
+  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 SetTracks2FirstPoint()   {fSetTracks2FirstPoint = kTRUE;}
+  static void SetTracks2Vertex()       {fSetTracks2FirstPoint = kFALSE;}
+  static Bool_t IsTracksAtFirstPoint() {return fSetTracks2FirstPoint;}
+  
+  ClassDef(AliHLTTPC,1) //Interface class for Level3-tracking
+};
+
+#endif
+
+
+
+
+
diff --git a/HLT/TPCLib/Ref/AliHLTTPCBenchmark.cxx b/HLT/TPCLib/Ref/AliHLTTPCBenchmark.cxx
new file mode 100644 (file)
index 0000000..38b606f
--- /dev/null
@@ -0,0 +1,197 @@
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#ifndef no_root
+#include <TFile.h>
+#include <TGraphAsymmErrors.h>
+#include <TString.h>
+#include <TStopwatch.h>
+#include <TMath.h>
+#endif
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCBenchmark.h"
+
+/** \class AliHLTTPCBenchmark
+</pre>
+//_____________________________________________________________
+//
+// AliHLTTPCBenchmark
+//
+//   Benchmark class for level3 code
+//  
+//
+</pre>
+*/
+
+ClassImp(AliHLTTPCBenchmark)
+AliHLTTPCBenchmark::AliHLTTPCBenchmark()
+{
+  //Constructor
+
+  fNbench = 0;
+  fNmax   = 20;
+  fNames  = 0;
+  fTimer  = 0;
+  fSum    = 0;
+  fMin    = 0;
+  fMax    = 0;
+  fCount  = 0;
+  //fStopwatch = 0;
+}
+
+AliHLTTPCBenchmark::~AliHLTTPCBenchmark()
+{
+   fNbench   = 0;
+   if (fNames)  {delete [] fNames; fNames  = 0;}
+   if (fTimer)  {delete [] fTimer; fTimer  = 0;}
+   if (fSum)    {delete [] fSum;   fSum   = 0;}
+   if (fMin)    {delete [] fMin;   fMin   = 0;}
+   if (fMax)    {delete [] fMax;   fMax   = 0;}
+   if (fCount)  {delete [] fCount; fCount =0;}
+   //if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+}
+
+Int_t AliHLTTPCBenchmark::GetBench(const char *name)
+{
+   for (Int_t i=0;i<fNbench;i++) {
+      if (!strcmp(name,(const char*)fNames[i])) return i;
+   }
+   return -1;
+}
+
+
+void AliHLTTPCBenchmark::Start(const char *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();
+      //if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+      //fStopwatch = new TStopwatch();
+      //fStopwatch->Reset();
+      //fStopwatch->Start();
+   } else if (bench >=0) {
+   // Resume the existent benchmark
+      fTimer[bench].Reset();
+      fTimer[bench].Start();
+      //if(fStopwatch) {delete fStopwatch; fStopwatch =0;}
+      //fStopwatch = new TStopwatch();
+      //fStopwatch->Reset();
+      //fStopwatch->Start();
+   }
+   else
+     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCBenchmark::Start","Start")
+     <<"too many benches"<<ENDLOG;
+}
+
+void AliHLTTPCBenchmark::Stop(const char *name)
+{
+   Int_t bench = GetBench(name);
+   if (bench < 0) return;
+
+   fTimer[bench].Stop();
+   Float_t val = fTimer[bench].CpuTime();
+   //fStopwatch->Stop();
+   //Float_t val = fStopwatch->CpuTime();
+   
+   fSum[bench] += val; 
+   fCount[bench]++;
+   if(fCount[bench]==1){
+     fMin[bench] = val;
+     fMax[bench] = val;
+   }
+   else{
+     if(val<fMin[bench])fMin[bench]=val;
+     if(val>fMax[bench])fMax[bench]=val;
+   }
+}
+
+void AliHLTTPCBenchmark::Analyze(const Char_t* name){
+  Float_t *x = new Float_t[fNbench]; 
+  Float_t *y = new Float_t[fNbench];
+  Float_t *eyl = new Float_t[fNbench]; 
+  Float_t *eyh = new Float_t[fNbench];
+  char filename[256];
+  sprintf(filename,"%s.dat",name);
+  FILE *f= fopen(filename,"w");
+  for (Int_t i=0;i<fNbench;i++) {
+    Float_t av =0;
+    if(fCount[i]) av = fSum[i]/fCount[i]; 
+    x[i]=i+1;
+    y[i]=av*1000;
+    eyl[i]=(av-fMin[i])*1000;
+    eyh[i]=(fMax[i]-av)*1000;
+#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()
+{
+  {return (Double_t)(clock()) / CLOCKS_PER_SEC;}
+}
diff --git a/HLT/TPCLib/Ref/AliHLTTPCBenchmark.h b/HLT/TPCLib/Ref/AliHLTTPCBenchmark.h
new file mode 100644 (file)
index 0000000..c258ff2
--- /dev/null
@@ -0,0 +1,47 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_Benchmark
+#define AliHLTTPC_Benchmark
+
+#ifndef no_root
+#include <Rtypes.h>
+class TStopwatch;
+class TString;
+#else
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStopwatch.h"
+#endif
+
+class AliHLTTPCBenchmark {
+
+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;
+   AliHLTTPCStopwatch *fTimer;
+#endif
+   Float_t    *fSum;
+   Float_t    *fMin;
+   Float_t    *fMax;
+   Int_t      *fCount;
+   //TStopwatch *fStopwatch;    //Stopwatch
+
+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();
+   
+   ClassDef(AliHLTTPCBenchmark,0)  //L3 benchmark
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.cxx b/HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.cxx
new file mode 100644 (file)
index 0000000..6c708ed
--- /dev/null
@@ -0,0 +1,517 @@
+// @(#) $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 "AliHLTTPCLogging.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if GCCVERSION == 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()
+{
+  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()
+{
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
+{
+  fNClusters = 0;
+  fMaxNClusters = nmaxpoints;
+  fCurrentSlice = slice;
+  fCurrentPatch = patch;
+  fFirstRow = firstrow;
+  fLastRow = lastrow;
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
+{
+  fNClusters = 0;
+  fMaxNClusters = nmaxpoints;
+  fCurrentSlice = slice;
+  fCurrentPatch = patch;
+  fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
+  fLastRow=AliHLTTPCTransform::GetLastRow(patch);
+}
+
+void AliHLTTPCClustFinderNew::SetOutputArray(AliHLTTPCSpacePointData *pt)
+{
+  fSpacePointData = pt;
+}
+
+void AliHLTTPCClustFinderNew::Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr)
+{
+  fNDigitRowData = ndigits;
+  fDigitRowData = ptr;
+}
+
+void AliHLTTPCClustFinderNew::ProcessDigits()
+{
+  //Loop over rows, and call processrow
+  
+  AliHLTTPCDigitRowData *tempPt = (AliHLTTPCDigitRowData*)fDigitRowData;
+  
+  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;
+      }
+#if 0
+      LOG(AliHLTTPCLog::kDebug,"AliHLTTPCClustFinderNew::ProcessDigits","Digits")
+         << "Row " << AliHLTTPCLog::kDec << tempPt->fRow << " digits: "
+         << tempPt->fNDigit << " (Offset: " << ((unsigned long)tempPt) - ((unsigned long)fDigitRowData)
+         << ")." << ENDLOG;
+#endif
+      ProcessRow(tempPt);
+      Byte_t *tmp = (Byte_t*)tempPt;
+      Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+      tmp += size;
+      tempPt = (AliHLTTPCDigitRowData*)tmp;
+    }
+  LOG(AliHLTTPCLog::kDebug,"AliHLTTPCClustFinderNew::ProcessDigits","Space points")
+    <<"Cluster finder found "<<fNClusters<<" clusters in slice "<<fCurrentSlice
+    <<" patch "<<fCurrentPatch<<ENDLOG;
+}
+
+void AliHLTTPCClustFinderNew::ProcessRow(AliHLTTPCDigitRowData *tempPt)
+{
+
+  UInt_t last_pad = 123456789;
+
+  ClusterData *pad1[5000]; //2 lists for internal memory=2pads
+  ClusterData *pad2[5000]; //2 lists for internal memory=2pads
+  ClusterData clusterlist[10000]; //Clusterlist
+
+  ClusterData **currentPt;  //List of pointers to the current pad
+  ClusterData **previousPt; //List of pointers to the previous pad
+  currentPt = pad2;
+  previousPt = pad1;
+  UInt_t n_previous=0,n_current=0,n_total=0;
+
+  //Loop over sequences of this row:
+  for(UInt_t bin=0; bin<tempPt->fNDigit; bin++)
+    {
+      AliHLTTPCDigitData *data = tempPt->fDigitData;
+#if 0
+      LOG( AliHLTTPCLog::kDebug, "AliHLTTPCClustFinderNew::ProcessRow", "Signal" )
+         << "Pad " << AliHLTTPCLog::kDec << data[bin].fPad 
+         << " (" << bin << ")"
+         << " time " << data[bin].fTime << ": " << data[bin].fCharge
+         << " (Offset: " << ((unsigned long)(data+bin)) - ((unsigned long)fDigitRowData)
+         << ")." << ENDLOG;
+#ifdef do_mc
+      LOG( AliHLTTPCLog::kWarning, "AliHLTTPCClustFinderNew::ProcessRow", "Signal" )
+         << "Compiled with do_mc" << ENDLOG;
+#endif
+#endif
+      if(data[bin].fPad != last_pad)
+       {
+         //This is a new pad
+         
+         //Switch the lists:
+         if(currentPt == pad2)
+           {
+             currentPt = pad1;
+             previousPt = pad2;
+           }
+         else 
+           {
+             currentPt = pad2;
+             previousPt = pad1;
+           }
+         n_previous = n_current;
+         n_current = 0;
+         if(bin[data].fPad != last_pad+1)
+           {
+             //this happens if there is a pad with no signal.
+             n_previous = n_current = 0;
+           }
+         last_pad = data[bin].fPad;
+       }
+
+      Bool_t new_cluster = kTRUE;
+      UInt_t seq_charge=0,seq_average=0,seq_error=0;
+      UInt_t last_charge=0,last_was_falling=0;
+      Int_t new_bin=-1;
+
+      if(fDeconvTime)
+       {
+       redo: //This is a goto.
+         if(new_bin > -1)
+           {
+             bin = new_bin;
+             new_bin = -1;
+           }
+         
+         last_charge=0;
+         last_was_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 > last_charge)
+               {
+                 if(last_was_falling)
+                   {
+                     new_bin = bin;
+                     break;
+                   }
+               }
+             else last_was_falling = 1; //last pixel was larger than this
+             last_charge = charge;
+           }
+         
+         //Sum the total charge of this sequence
+         seq_charge += charge;
+         seq_average += data[bin].fTime*charge;
+         seq_error += 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 seq_mean=0;
+      if(seq_charge)
+       seq_mean = seq_average/seq_charge;
+      else
+       {
+         LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Data")
+           <<"Error in data given to the cluster finder"<<ENDLOG;
+         seq_mean = 1;
+         seq_charge = 1;
+       }
+      
+      //Calculate mean in pad direction:
+      Int_t pad_mean = seq_charge*data[bin].fPad;
+      Int_t pad_error = data[bin].fPad*pad_mean;
+
+      //Compare with results on previous pad:
+      for(UInt_t p=0; p<n_previous; p++)
+       {
+         //dont merge sequences on the same pad twice
+         if(previousPt[p]->fLastMergedPad==data[bin].fPad) continue;
+
+         Int_t difference = seq_mean - previousPt[p]->fMean;
+         if(difference < -fMatch) break;
+
+         if(difference <= fMatch) //There is a match here!!
+           {
+             ClusterData *local = previousPt[p];
+
+             if(fDeconvPad)
+               {
+                 if(seq_charge > local->fLastCharge)
+                   {
+                     if(local->fChargeFalling) //The previous pad was falling
+                       {                       
+                         break; //create a new cluster
+                       }                   
+                   }
+                 else
+                   local->fChargeFalling = 1;
+                 local->fLastCharge = seq_charge;
+               }
+             
+             //Don't create a new cluster, because we found a match
+             new_cluster = kFALSE;
+             
+             //Update cluster on current pad with the matching one:
+             local->fTotalCharge += seq_charge;
+             local->fPad += pad_mean;
+             local->fPad2 += pad_error;
+             local->fTime += seq_average;
+             local->fTime2 += seq_error;
+             local->fMean = seq_mean;
+             local->fFlags++; //means we have more than one pad 
+             local->fLastMergedPad = data[bin].fPad;
+
+             currentPt[n_current] = local;
+             n_current++;
+             
+             break;
+           } //Checking for match at previous pad
+       } //Loop over results on previous pad.
+      
+      if(new_cluster)
+       {
+         //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:
+         ClusterData *tmp = &clusterlist[n_total];
+         tmp->fTotalCharge = seq_charge;
+         tmp->fPad = pad_mean;
+         tmp->fPad2 = pad_error;
+         tmp->fTime = seq_average;
+         tmp->fTime2 = seq_error;
+         tmp->fMean = seq_mean;
+         tmp->fFlags = 0;  //flags for single pad clusters
+         tmp->fLastMergedPad = data[bin].fPad;
+
+         if(fDeconvPad)
+           {
+             tmp->fChargeFalling = 0;
+             tmp->fLastCharge = seq_charge;
+           }
+
+         //Update list of pointers to previous pad:
+         currentPt[n_current] = &clusterlist[n_total];
+         n_total++;
+         n_current++;
+       }
+
+      if(fDeconvTime)
+       if(new_bin >= 0) goto redo;
+    }//Loop over digits on this padrow
+  
+  WriteClusters(n_total,clusterlist);
+}
+
+void AliHLTTPCClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list)
+{
+  Int_t thisrow,thissector;
+  UInt_t counter = fNClusters;
+  
+  for(int j=0; j<n_clusters; 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 /(Float_t)list[j].fTotalCharge;
+      Float_t fpad2=fXYErr*fXYErr; //fixed given error
+      Float_t ftime =(Float_t)list[j].fTime /(Float_t)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);
+
+       Float_t sy2=(Float_t)list[j].fPad2/(Float_t)list[j].fTotalCharge - fpad*fpad;
+       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=(Float_t)list[j].fTime2/(Float_t)list[j].fTotalCharge - ftime*ftime;
+       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)
+         {
+#if 0
+       cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
+#endif
+         }
+      
+      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)
+{
+  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/Ref/AliHLTTPCClustFinderNew.h b/HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.h
new file mode 100644 (file)
index 0000000..b7f2db5
--- /dev/null
@@ -0,0 +1,84 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_ClustFinderNew
+#define AliHLTTPC_ClustFinderNew
+
+#include "AliHLTTPCRootTypes.h"
+
+
+struct ClusterData
+{
+  UInt_t fTotalCharge;
+  UInt_t fPad;
+  UInt_t fTime;
+  UInt_t fPad2;     //for error in XY direction
+  ULong64_t fTime2; //for error in Z  direction
+  UInt_t fMean;
+  UInt_t fFlags;
+  UInt_t fChargeFalling; //for deconvolution
+  UInt_t fLastCharge;    //for deconvolution
+  UInt_t fLastMergedPad; //dont merge twice per pad
+};
+typedef struct ClusterData ClusterData;
+
+class AliHLTTPCDigitRowData;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCClustFinderNew {
+ 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;
+  Int_t fFirstRow;
+  Int_t fLastRow;
+  Int_t fCurrentRow;
+  Int_t fCurrentSlice;
+  Int_t fCurrentPatch;
+  Int_t fMatch;
+  UInt_t fThreshold;
+  Int_t fNClusters;
+  Int_t fMaxNClusters;
+  Float_t fXYErr;
+  Float_t fZErr;
+
+#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,ClusterData *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() {return fNClusters;}
+  
+  ClassDef(AliHLTTPCClustFinderNew,1) //Fast cluster finder
+
+};
+
+#endif
+
+
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClusterDataFormat.h b/HLT/TPCLib/Ref/AliHLTTPCClusterDataFormat.h
new file mode 100644 (file)
index 0000000..d32f0c1
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _ALIHLTTPCCLUSTERFORMAT_H_
+#define _ALIHLTTPCCLUSTERFORMAT_H_
+
+
+/*
+***************************************************************************
+**
+** $Author$ - Initial Version by Timm Morten Steinbeck
+**
+** $Id$ 
+**
+***************************************************************************
+*/
+
+#include "AliHLTDataTypes.h"
+// #include "AliHLTTPCMemHandler.h"
+// #include "AliHLTTPCTransform.h"
+#include "AliHLTTPCSpacePointData.h"
+
+struct AliHLTTPCClusterData
+    {
+       AliHLTUInt32_t fSpacePointCnt;
+       AliHLTTPCSpacePointData fSpacePoints[];
+    };
+
+
+/*
+***************************************************************************
+**
+** $Author$ - Initial Version by Timm Morten Steinbeck
+**
+** $Id$ 
+**
+***************************************************************************
+*/
+
+#endif // _ALIHLTTPCCLUSTERFORMAT_H_
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.cxx b/HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.cxx
new file mode 100644 (file)
index 0000000..b19cd6b
--- /dev/null
@@ -0,0 +1,209 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
+ *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
+ *          for The ALICE Off-line Project.                               *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// a TPC cluster finder processing component for the HLT                     //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#if __GNUC__== 3
+using namespace std;
+#endif
+
+#include "AliHLTTPCClusterFinderComponent.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCRawDataFormat.h"
+#include "AliHLTTPCClusterDataFormat.h"
+#include "AliHLTTPCTransform.h"
+#include <stdlib.h>
+#include <errno.h>
+
+// this is a global object used for automatic component registration, do not use this
+AliHLTTPCClusterFinderComponent gAliHLTTPCClusterFinderComponent;
+
+ClassImp(AliHLTTPCClusterFinderComponent)
+
+AliHLTTPCClusterFinderComponent::AliHLTTPCClusterFinderComponent()
+    {
+    fClusterFinder = NULL;
+    fClusterDeconv = true;
+    fXYClusterError = -1;
+    fZClusterError = -1;
+    }
+
+AliHLTTPCClusterFinderComponent::~AliHLTTPCClusterFinderComponent()
+    {
+    }
+
+// Public functions to implement AliHLTComponent's interface.
+// These functions are required for the registration process
+
+const char* AliHLTTPCClusterFinderComponent::GetComponentID()
+    {
+    return "TPCClusterFinder";
+    }
+
+void AliHLTTPCClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponent_DataType>& list)
+    {
+    list.clear();
+    list.push_back( AliHLTTPCDefinitions::gkUnpackedRawDataType );
+    }
+
+AliHLTComponent_DataType AliHLTTPCClusterFinderComponent::GetOutputDataType()
+    {
+    return AliHLTTPCDefinitions::gkClustersDataType;
+    }
+
+void AliHLTTPCClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
+    {
+    // XXX TODO: Find more realistic values.
+    constBase = 0;
+    inputMultiplier = 0.4;
+    }
+
+AliHLTComponent* AliHLTTPCClusterFinderComponent::Spawn()
+    {
+    return new AliHLTTPCClusterFinderComponent;
+    }
+       
+int AliHLTTPCClusterFinderComponent::DoInit( int argc, const char** argv )
+    {
+    if ( fClusterFinder )
+       return EINPROGRESS;
+    fClusterFinder = new AliHLTTPCClustFinderNew();
+    fClusterDeconv = true;
+    fXYClusterError = -1;
+    fZClusterError = -1;
+    int i = 0;
+    while ( i < argc )
+       {
+       if ( !strcmp( argv[i], "pp-run" ) )
+           {
+           fClusterDeconv = false;
+           i++;
+           continue;
+           }
+       Logging(kHLTLogError, "HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
+       return EINVAL;
+       }
+    return 0;
+    }
+
+int AliHLTTPCClusterFinderComponent::DoDeinit()
+    {
+    if ( !fClusterFinder )
+       return ECANCELED;
+    if ( fClusterFinder )
+       delete fClusterFinder;
+    fClusterFinder = NULL;
+    return 0;
+    }
+
+int AliHLTTPCClusterFinderComponent::DoEvent( const AliHLTComponent_EventData& evtData, const AliHLTComponent_BlockData* blocks, 
+                                             AliHLTComponent_TriggerData& trigData, AliHLTUInt8_t* outputPtr, 
+                                             AliHLTUInt32_t& size, vector<AliHLTComponent_BlockData>& outputBlocks )
+    {
+    const AliHLTComponent_BlockData* iter = NULL;
+    unsigned long ndx;
+    AliHLTTPCUnpackedRawData* inPtr;
+    AliHLTTPCClusterData* outPtr;
+    AliHLTUInt8_t* outBPtr;
+    UInt_t offset, mysize, nSize, tSize = 0;
+    outBPtr = outputPtr;
+    outPtr = (AliHLTTPCClusterData*)outBPtr;
+    Int_t slice, patch, row[2];
+    unsigned long maxPoints, realPoints = 0;
+    for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
+       {
+       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] = 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.",
+                realPoints, slice, patch, row[0], row[1] );
+       
+       outPtr = (AliHLTTPCClusterData*)outBPtr;
+       
+       inPtr = (AliHLTTPCUnpackedRawData*)iter->fPtr;
+       maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
+       
+       fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
+       fClusterFinder->SetDeconv( fClusterDeconv );
+       fClusterFinder->SetXYError( fXYClusterError );
+       fClusterFinder->SetZError( fZClusterError );
+       if ( (fXYClusterError>0) && (fZClusterError>0) )
+           fClusterFinder->SetCalcErr( false );
+       fClusterFinder->SetOutputArray( outPtr->fSpacePoints );
+       fClusterFinder->Read( maxPoints, inPtr->fDigits );
+       fClusterFinder->ProcessDigits();
+       realPoints = fClusterFinder->GetNumberOfClusters();
+       
+       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Spacepoints", 
+                "Number of spacepoints found: %lu.", realPoints );
+       
+       outPtr->fSpacePointCnt = realPoints;
+       nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
+       mysize += nSize+sizeof(AliHLTTPCClusterData);
+       
+       Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints", 
+                "Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
+                realPoints, slice, patch, row[0], row[1] );
+       
+       
+       AliHLTComponent_BlockData bd;
+       FillBlockData( bd );
+       bd.fOffset = offset;
+       bd.fSize = mysize;
+       bd.fSpecification = iter->fSpecification;
+       //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
+       outputBlocks.push_back( bd );
+       
+       tSize += mysize;
+       outBPtr += mysize;
+       outPtr = (AliHLTTPCClusterData*)outBPtr;
+       
+       if ( tSize > size )
+           {
+           Logging( kHLTLogFatal, "HLT::TPCClusterFinder::DoEvent", "Too much data", 
+                    "Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
+                    tSize, size );
+           return EMSGSIZE;
+           }
+       }
+    
+    size = tSize;
+    return 0;
+    }
+
+       
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.h b/HLT/TPCLib/Ref/AliHLTTPCClusterFinderComponent.h
new file mode 100644 (file)
index 0000000..fd41c02
--- /dev/null
@@ -0,0 +1,55 @@
+// XEmacs -*-C++-*-
+// @(#) $Id$
+
+#ifndef ALIHLTTPCCLUSTERFINDERCOMPONENT_H
+#define ALIHLTTPCCLUSTERFINDERCOMPONENT_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* AliHLTTPCClusterFinderComponent
+ */
+
+#include "AliHLTProcessor.h"
+#include "AliHLTTPCDefinitions.h"
+
+class AliHLTTPCClustFinderNew;
+
+class AliHLTTPCClusterFinderComponent : public AliHLTProcessor
+    {
+    public:
+       AliHLTTPCClusterFinderComponent();
+       virtual ~AliHLTTPCClusterFinderComponent();
+
+       // Public functions to implement AliHLTComponent's interface.
+       // These functions are required for the registration process
+
+       const char* GetComponentID();
+       void GetInputDataTypes( vector<AliHLTComponent_DataType>& list);
+       AliHLTComponent_DataType GetOutputDataType();
+       virtual void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
+       AliHLTComponent* Spawn();
+       
+    protected:
+       
+       // Protected functions to implement AliHLTComponent's interface.
+       // These functions provide initialization as well as the actual processing
+       // capabilities of the component. 
+
+       int DoInit( int argc, const char** argv );
+       int DoDeinit();
+       int DoEvent( const AliHLTComponent_EventData& evtData, const AliHLTComponent_BlockData* blocks, 
+                    AliHLTComponent_TriggerData& trigData, AliHLTUInt8_t* outputPtr, 
+                    AliHLTUInt32_t& size, vector<AliHLTComponent_BlockData>& outputBlocks );
+       
+    private:
+
+       AliHLTTPCClustFinderNew* fClusterFinder;
+
+       bool fClusterDeconv;
+       float fXYClusterError;
+       float fZClusterError;
+       
+       ClassDef(AliHLTTPCClusterFinderComponent, 0)
+
+    };
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClusterFitter.cxx b/HLT/TPCLib/Ref/AliHLTTPCClusterFitter.cxx
new file mode 100644 (file)
index 0000000..8302a75
--- /dev/null
@@ -0,0 +1,1230 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCClusterFitter.h"
+#include "AliHLTTPCFitUtilities.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCModelTrack.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCHoughTrack.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCCompress.h"
+
+#if GCCVERSION == 3
+using namespace std;
+#endif
+
+//_____________________________________________________________
+//
+//  AliHLTTPCClusterFitter
+//
+
+
+ClassImp(AliHLTTPCClusterFitter)
+
+Int_t AliHLTTPCClusterFitter::fBadFitError=0;
+Int_t AliHLTTPCClusterFitter::fFitError=0;
+Int_t AliHLTTPCClusterFitter::fResultError=0;
+Int_t AliHLTTPCClusterFitter::fFitRangeError=0;
+
+AliHLTTPCClusterFitter::AliHLTTPCClusterFitter()
+{
+  plane=0;
+  fNmaxOverlaps = 3;
+  fChiSqMax[0]=fChiSqMax[1]=12;
+  fRowMin=-1;
+  fRowMax=-1;
+  fFitted=0;
+  fFailed=0;
+  fYInnerWidthFactor=1;
+  fZInnerWidthFactor=1;
+  fYOuterWidthFactor=1;
+  fZOuterWidthFactor=1;
+  fSeeds=0;
+  fProcessTracks=0;
+  fClusters=0;
+  fNMaxClusters=0;
+  fNClusters=0;
+  fEvent=0;
+}
+
+AliHLTTPCClusterFitter::AliHLTTPCClusterFitter(Char_t *path)
+{
+  strcpy(fPath,path);
+  plane=0;
+  fNmaxOverlaps = 3;
+  fChiSqMax[0]=fChiSqMax[1]=12;
+  fRowMin=-1;
+  fRowMax=-1;
+  fFitted=0;
+  fFailed=0;
+  fYInnerWidthFactor=1;
+  fZInnerWidthFactor=1;
+  fYOuterWidthFactor=1;
+  fZOuterWidthFactor=1;
+  fSeeds=0;
+  fProcessTracks=0;
+  fNMaxClusters=100000;
+  fClusters=0;
+  fNClusters=0;
+  fEvent=0;
+}
+
+AliHLTTPCClusterFitter::~AliHLTTPCClusterFitter()
+{
+  if(fSeeds)
+    delete fSeeds;
+  if(fClusters)
+    delete [] fClusters;
+}
+
+void AliHLTTPCClusterFitter::Init(Int_t slice,Int_t patch,Int_t *rowrange,AliHLTTPCTrackArray *tracks)
+{
+  //Assuming tracklets found by the line transform
+
+  fSlice=slice;
+  fPatch=patch;
+  
+  if(rowrange[0] > AliHLTTPCTransform::GetLastRow(patch) || rowrange[1] < AliHLTTPCTransform::GetFirstRow(patch))
+    cerr<<"AliHLTTPCClusterFitter::Init : Wrong rows "<<rowrange[0]<<" "<<rowrange[1]<<endl;
+  fRowMin=rowrange[0];
+  fRowMax=rowrange[1];
+
+  if(fRowMin < 0)
+    fRowMin = 0;
+  if(fRowMax > AliHLTTPCTransform::GetLastRow(fPatch))
+    fRowMax = AliHLTTPCTransform::GetLastRow(fPatch);
+  
+  fFitted=fFailed=0;
+  
+  Int_t ntimes = AliHLTTPCTransform::GetNTimeBins()+1;
+  Int_t npads = AliHLTTPCTransform::GetNPads(AliHLTTPCTransform::GetLastRow(fPatch))+1;//Max num of pads.
+  Int_t bounds = ntimes*npads;
+  if(fRow)
+    delete [] fRow;
+  fRow = new Digit[bounds];
+  if(fTracks)
+    delete fTracks;
+  
+  fTracks = new AliHLTTPCTrackArray("AliHLTTPCModelTrack");
+  
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliHLTTPCHoughTrack *track = (AliHLTTPCHoughTrack*)tracks->GetCheckedTrack(i);
+      if(!track) continue;
+      AliHLTTPCModelTrack *mtrack = (AliHLTTPCModelTrack*)fTracks->NextTrack();
+      mtrack->Init(slice,patch);
+      mtrack->SetTgl(track->GetTgl());
+      mtrack->SetRowRange(rowrange[0],rowrange[1]);
+      for(Int_t j=fRowMin; j<=fRowMax; j++)
+       {
+         Float_t hit[3];
+         track->GetLineCrossingPoint(j,hit);
+         hit[0] += AliHLTTPCTransform::Row2X(track->GetFirstRow());
+         Float_t R = sqrt(hit[0]*hit[0] + hit[1]*hit[1]);
+         hit[2] = R*track->GetTgl();
+         Int_t se,ro;
+         AliHLTTPCTransform::Slice2Sector(slice,j,se,ro);
+         AliHLTTPCTransform::Local2Raw(hit,se,ro);
+         if(hit[1]<0 || hit[1]>=AliHLTTPCTransform::GetNPads(j) || hit[2]<0 || hit[2]>=AliHLTTPCTransform::GetNTimeBins())
+           {
+             mtrack->SetPadHit(j,-1);
+             mtrack->SetTimeHit(j,-1);
+             continue;
+           }
+         mtrack->SetPadHit(j,hit[1]);
+         mtrack->SetTimeHit(j,hit[2]);
+         mtrack->SetCrossingAngleLUT(j,fabs(track->GetPsiLine() - AliHLTTPCTransform::Pi()/2));
+         //if(mtrack->GetCrossingAngleLUT(j) > AliHLTTPCTransform::Deg2Rad(20))
+         //  cout<<"Angle "<<mtrack->GetCrossingAngleLUT(j)<<" psiline "<<track->GetPsiLine()*180/3.1415<<endl;
+         mtrack->CalculateClusterWidths(j);
+       }
+    }
+  //  cout<<"Copied "<<fTracks->GetNTracks()<<" tracks "<<endl;
+}
+
+void AliHLTTPCClusterFitter::Init(Int_t slice,Int_t patch)
+{
+  fSlice=slice;
+  fPatch=patch;
+  
+  fRowMin=AliHLTTPCTransform::GetFirstRow(patch);
+  fRowMax=AliHLTTPCTransform::GetLastRow(patch);
+  
+  fFitted=fFailed=0;
+  
+  Int_t ntimes = AliHLTTPCTransform::GetNTimeBins()+1;
+  Int_t npads = AliHLTTPCTransform::GetNPads(AliHLTTPCTransform::GetLastRow(fPatch))+1;//Max num of pads.
+  Int_t bounds = ntimes*npads;
+  if(fRow)
+    delete [] fRow;
+  fRow = new Digit[bounds];
+  if(fTracks)
+    delete fTracks;
+  fTracks = new AliHLTTPCTrackArray("AliHLTTPCModelTrack");  
+
+}
+
+void AliHLTTPCClusterFitter::LoadLocalSegments()
+{
+  Char_t filename[1024];
+  sprintf(filename,"%s/hough/tracks_ho_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  AliHLTTPCMemHandler mem;
+  mem.SetBinaryInput(filename);
+  mem.Binary2TrackArray(fTracks);
+  mem.CloseBinaryInput();
+  
+  for(Int_t i=0; i<fTracks->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fTracks->GetCheckedTrack(i);
+      if(!track) continue;
+
+      track->CalculateHelix();
+      
+      track->Init(fSlice,fPatch);
+
+      for(Int_t j=fRowMin; j<=fRowMax; j++)
+       {
+         //Calculate the crossing point between track and padrow
+         
+         Float_t xyz_cross[3];
+         if(!track->GetCrossingPoint(j,xyz_cross))
+           continue;
+         
+         Int_t sector,row;
+         AliHLTTPCTransform::Slice2Sector(fSlice,j,sector,row);
+         AliHLTTPCTransform::Local2Raw(xyz_cross,sector,row);
+         
+         if(xyz_cross[1] < 0 || xyz_cross[1] >= AliHLTTPCTransform::GetNPads(j) ||
+            xyz_cross[2] < 0 || xyz_cross[2] >= AliHLTTPCTransform::GetNTimeBins()) //track goes out of range
+           continue;
+         
+         track->SetPadHit(j,xyz_cross[1]);
+         track->SetTimeHit(j,xyz_cross[2]);
+
+         Float_t crossingangle = track->GetCrossingAngle(j);
+         track->SetCrossingAngleLUT(j,crossingangle);
+         track->CalculateClusterWidths(j);
+         track->GetClusterModel(j)->fSlice = fSlice;
+         
+       }
+    }
+}
+
+void AliHLTTPCClusterFitter::LoadSeeds(Int_t *rowrange,Bool_t offline,Int_t eventnr)
+{
+  //Function assumes _global_ tracks written to a single file.
+  
+#if 0
+  cout<<"Loading the seeds"<<endl;
+#endif
+  Char_t fname[1024];
+  fEvent = eventnr;
+  
+  if(offline)
+    sprintf(fname,"%s/offline/tracks_%d.raw",fPath,fEvent);
+  else
+    sprintf(fname,"%s/hough/tracks_%d.raw",fPath,fEvent);
+  
+#if 0
+  cout<<"AliHLTTPCClusterFitter::LoadSeeds : Loading input tracks from "<<fname<<endl;
+#endif
+  
+  AliHLTTPCMemHandler tfile;
+  tfile.SetBinaryInput(fname);
+  
+  if(fSeeds)
+    delete fSeeds;
+  fSeeds = new AliHLTTPCTrackArray("AliHLTTPCModelTrack");
+  tfile.Binary2TrackArray(fSeeds);
+  tfile.CloseBinaryInput();
+
+  //if(!offline)
+  //fSeeds->QSort();
+  
+  Int_t clustercount=0;
+  for(Int_t i=0; i<fSeeds->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fSeeds->GetCheckedTrack(i);
+      if(!track) continue;
+
+      if(!offline)
+       {
+         if(i==0) cerr<<"AliHLTTPCClusterFitter::LoadSeeds : Cutting on pt of 4GeV!!"<<endl;
+         if(track->GetPt() > 4.) 
+           {
+             fSeeds->Remove(i);
+             continue;
+           }
+       }
+      clustercount += track->GetNHits();
+      track->CalculateHelix();
+      
+      Int_t nhits = track->GetNHits();
+      UInt_t *hitids = track->GetHitNumbers();
+
+      Int_t origslice = (hitids[nhits-1]>>25)&0x7f;//Slice of innermost point
+
+      track->Init(origslice,-1);
+      Int_t slice = origslice;
+      
+      //for(Int_t j=rowrange[1]; j>=rowrange[0]; j--)
+      for(Int_t j=rowrange[0]; j<=rowrange[1]; j++)
+       {
+         
+         //Calculate the crossing point between track and padrow
+         Float_t angle = 0; //Perpendicular to padrow in local coordinates
+         AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+         if(!track->CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(j)))
+           {
+             //cerr<<"No crossing in slice "<<slice<<" padrow "<<j<<endl;
+             continue;
+             //track->Print();
+             //exit(5);
+           }
+         Float_t xyz_cross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
+         
+         Int_t sector,row;
+         AliHLTTPCTransform::Slice2Sector(slice,j,sector,row);
+         AliHLTTPCTransform::Global2Raw(xyz_cross,sector,row);
+         //cout<<"Examining slice "<<slice<<" row "<<j<<" pad "<<xyz_cross[1]<<" time "<<xyz_cross[2]<<endl;
+         if(xyz_cross[1] < 0 || xyz_cross[1] >= AliHLTTPCTransform::GetNPads(j)) //Track leaves the slice
+           {
+           newslice:
+             
+             Int_t tslice=slice;
+             Float_t lastcross=xyz_cross[1];
+             if(xyz_cross[1] > 0)
+               {
+                 if(slice == 17)
+                   slice=0;
+                 else if(slice == 35)
+                   slice = 18;
+                 else
+                   slice += 1;
+               }
+             else
+               {
+                 if(slice == 0)
+                   slice = 17;
+                 else if(slice==18)
+                   slice = 35;
+                 else
+                   slice -= 1;
+               }
+             if(slice < 0 || slice>35)
+               {
+                 cerr<<"Wrong slice "<<slice<<" on row "<<j<<endl;
+                 exit(5);
+               }
+             //cout<<"Track leaving, trying slice "<<slice<<endl;
+             angle=0;
+             AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+             if(!track->CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(j)))
+               {
+                 cerr<<"No crossing in slice "<<slice<<" padrow "<<j<<endl;
+                 continue;
+                 //track->Print();
+                 //exit(5);
+               }
+             xyz_cross[0] = track->GetPointX();
+             xyz_cross[1] = track->GetPointY();
+             xyz_cross[2] = track->GetPointZ();
+             Int_t sector,row;
+             AliHLTTPCTransform::Slice2Sector(slice,j,sector,row);
+             AliHLTTPCTransform::Global2Raw(xyz_cross,sector,row);
+             if(xyz_cross[1] < 0 || xyz_cross[1] >= AliHLTTPCTransform::GetNPads(j)) //track is in the borderline
+               {
+                 if(xyz_cross[1] > 0 && lastcross > 0 || xyz_cross[1] < 0 && lastcross < 0)
+                   goto newslice;
+                 else
+                   {
+                     slice = tslice;//Track is on the border of two slices
+                     continue;
+                   }
+               }
+           }
+         
+         if(xyz_cross[2] < 0 || xyz_cross[2] >= AliHLTTPCTransform::GetNTimeBins())//track goes out of range
+           continue;
+         
+         if(xyz_cross[1] < 0 || xyz_cross[1] >= AliHLTTPCTransform::GetNPads(j))
+           {
+             cerr<<"Slice "<<slice<<" padrow "<<j<<" pad "<<xyz_cross[1]<<" time "<<xyz_cross[2]<<endl;
+             track->Print();
+             exit(5);
+           }
+         
+         track->SetPadHit(j,xyz_cross[1]);
+         track->SetTimeHit(j,xyz_cross[2]);
+         angle=0;
+         AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+         Float_t crossingangle = track->GetCrossingAngle(j,slice);
+         track->SetCrossingAngleLUT(j,crossingangle);
+         
+         track->CalculateClusterWidths(j);
+         
+         track->GetClusterModel(j)->fSlice = slice;
+         
+       }
+      memset(track->GetHitNumbers(),0,159*sizeof(UInt_t));//Reset the hitnumbers
+      track->SetNHits(0);
+    }
+  fSeeds->Compress();
+  
+#if 0
+  cout<<"Loaded "<<fSeeds->GetNTracks()<<" seeds and "<<clustercount<<" clusters"<<endl;
+#endif
+}
+
+void AliHLTTPCClusterFitter::FindClusters()
+{
+  if(!fTracks)
+    {
+      cerr<<"AliHLTTPCClusterFitter::Process : No tracks"<<endl;
+      return;
+    }
+  if(!fRowData)
+    {
+      cerr<<"AliHLTTPCClusterFitter::Process : No data "<<endl;
+      return;
+    }
+  
+  AliHLTTPCDigitRowData *rowPt = fRowData;
+  AliHLTTPCDigitData *digPt=0;
+
+  Int_t pad,time;
+  Short_t charge;
+  
+  if(fRowMin < 0)
+    {
+      fRowMin = AliHLTTPCTransform::GetFirstRow(fPatch);
+      fRowMax = AliHLTTPCTransform::GetLastRow(fPatch);
+    }
+  for(Int_t i=AliHLTTPCTransform::GetFirstRow(fPatch); i<=AliHLTTPCTransform::GetLastRow(fPatch); i++)
+    {
+      if((Int_t)rowPt->fRow < fRowMin)
+       {
+         AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
+         continue;
+       }
+      else if((Int_t)rowPt->fRow > fRowMax)
+       break;
+      else if((Int_t)rowPt->fRow != i)
+       {
+         cerr<<"AliHLTTPCClusterFitter::FindClusters : Mismatching row numbering "<<i<<" "<<rowPt->fRow<<endl;
+         exit(5);
+       }
+      fCurrentPadRow = i;
+      memset((void*)fRow,0,(AliHLTTPCTransform::GetNTimeBins()+1)*(AliHLTTPCTransform::GetNPads(i)+1)*sizeof(Digit));
+      digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
+
+      for(UInt_t j=0; j<rowPt->fNDigit; j++)
+       {
+         pad = digPt[j].fPad;
+         time = digPt[j].fTime;
+         charge = digPt[j].fCharge;
+         fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*pad+time].fCharge = charge;
+         fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*pad+time].fUsed = kFALSE;
+         //cout<<"Row "<<i<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
+       }
+      
+      for(Int_t it=0; it<2; it++)
+       {
+         if(it==0)
+           {
+             fProcessTracks = fSeeds;
+             fSeeding = kTRUE;
+           }
+         else
+           {
+             fProcessTracks = fTracks;
+             fSeeding = kFALSE;
+           }
+         if(!fProcessTracks)
+           continue;
+         
+         for(Int_t k=0; k<fProcessTracks->GetNTracks(); k++)
+           {
+             AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(k);
+             if(!track) continue;
+             
+             if(fSeeding)
+               if(track->GetClusterModel(i)->fSlice != fSlice) continue;
+             
+             if(track->GetPadHit(i) < 0 || track->GetPadHit(i) > AliHLTTPCTransform::GetNPads(i)-1 ||
+                track->GetTimeHit(i) < 0 || track->GetTimeHit(i) > AliHLTTPCTransform::GetNTimeBins()-1)
+               {
+                 track->SetCluster(i,0,0,0,0,0,0);
+                 continue;
+               }
+             
+             if(CheckCluster(k) == kFALSE)
+               fFailed++;
+           }
+       }
+      AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
+    }
+  
+  fSeeding = kTRUE;
+  AddClusters();
+  fSeeding = kFALSE;
+  AddClusters();
+    
+#if 0
+  cout<<"Fitted "<<fFitted<<" clusters, failed "<<fFailed<<endl;
+  cout<<"Distribution:"<<endl;
+  cout<<"Bad fit "<<fBadFitError<<endl;
+  cout<<"Fit error "<<fFitError<<endl;
+  cout<<"Result error "<<fResultError<<endl;
+  cout<<"Fit range error "<<fFitRangeError<<endl;
+#endif
+
+}
+
+Bool_t AliHLTTPCClusterFitter::CheckCluster(Int_t trackindex)
+{
+  //Check if this is a single or overlapping cluster
+  
+  AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(trackindex);
+  
+  Int_t row = fCurrentPadRow;
+  
+  if(track->IsSet(row)) //A fit has already be performed on this one
+    return kTRUE;
+  
+  //Define the cluster region of this hit:
+  Int_t padr[2]={999,-1};
+  Int_t timer[2]={999,-1};
+  
+  if(!SetFitRange(track,padr,timer))
+    {
+      track->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
+      
+      if(fDebug)
+         {
+#if 0
+       cout<<"Failed to fit cluster at row "<<row<<" pad "<<(Int_t)rint(track->GetPadHit(row))<<" time "
+           <<(Int_t)rint(track->GetTimeHit(row))<<" hitcharge "
+           <<fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*(Int_t)rint(track->GetPadHit(row))+(Int_t)rint(track->GetTimeHit(row))].fCharge<<endl;
+#endif
+         }
+      fFitRangeError++;
+      return kFALSE;
+    }
+
+  //Check if any other track contributes to this cluster:
+  //This is done by checking if the tracks are overlapping within
+  //the range defined by the track parameters
+  
+  for(Int_t t=trackindex+1; t<fProcessTracks->GetNTracks(); t++)
+    {
+      AliHLTTPCModelTrack *tr = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(t);
+      if(!tr) continue;
+      if(fSeeding)
+       if(tr->GetClusterModel(row)->fSlice != fSlice) continue;
+
+      Int_t xyw = (Int_t)ceil(sqrt(tr->GetParSigmaY2(row))*GetYWidthFactor()); 
+      Int_t zw = (Int_t)ceil(sqrt(tr->GetParSigmaZ2(row))*GetZWidthFactor()); 
+      
+      if( 
+        (tr->GetPadHit(row) - xyw > padr[0] && tr->GetPadHit(row) - xyw < padr[1] &&
+         tr->GetTimeHit(row) - zw > timer[0] && tr->GetTimeHit(row) - zw < timer[1]) ||
+        
+        (tr->GetPadHit(row) + xyw > padr[0] && tr->GetPadHit(row) + xyw < padr[1] &&
+         tr->GetTimeHit(row) - zw > timer[0] && tr->GetTimeHit(row) - zw < timer[1]) ||
+        
+        (tr->GetPadHit(row) - xyw > padr[0] && tr->GetPadHit(row) - xyw < padr[1] &&
+         tr->GetTimeHit(row) + zw > timer[0] && tr->GetTimeHit(row) + zw < timer[1]) ||
+        
+        (tr->GetPadHit(row) + xyw > padr[0] && tr->GetPadHit(row) + xyw < padr[1] &&
+         tr->GetTimeHit(row) + zw > timer[0] && tr->GetTimeHit(row) + zw < timer[1]) 
+        )
+       {
+         if(SetFitRange(tr,padr,timer)) //Expand the cluster fit range
+           track->SetOverlap(row,t);    //Set overlap
+       }
+    }
+
+  if(fDebug)
+      {
+#if 0
+    cout<<"Fitting cluster with "<<track->GetNOverlaps(fCurrentPadRow)<<" overlaps"<<endl;
+#endif
+      }
+  FitClusters(track,padr,timer);
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCClusterFitter::SetFitRange(AliHLTTPCModelTrack *track,Int_t *padrange,Int_t *timerange)
+{
+  Int_t row = fCurrentPadRow;
+  Int_t nt = AliHLTTPCTransform::GetNTimeBins()+1;
+  
+  Int_t nsearchbins=0;
+  if(row < AliHLTTPCTransform::GetNRowLow())
+    nsearchbins=25;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1())
+    nsearchbins=49;
+  else
+    nsearchbins=49;
+  
+  /*
+  Int_t padloop[49] = {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
+                      ,0,1,2,3,3,3,3,3,3,3
+                      ,2,1,0,-1,-2,-3
+                      ,-3,-3,-3,-3,-3,-3,-1,-1};
+  Int_t timeloop[49] = {0,1,-1,0,0,1,1,-1,-1,2,-2,2,2,-2,-2 ,0,0,1,1,-1,-1,2,2,-2,-2
+                        ,-3,-3,-3,-3,-2,-1,0,1,2,3
+                       ,3,3,3,3,3,3,2,1,0,-1,-2,-3,-3,-3};
+  */
+  
+  Int_t padloop[49] = {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
+                      ,-3,3,-3,3,-3,3,-3,3,-3,3
+                      ,0,0,-1,-1,1,1,-2,-2,2,2,-3,-3,3,3};
+  Int_t timeloop[49] = {0,1,-1,0,0,1,1,-1,-1,2,-2,2,2,-2,-2 ,0,0,1,1,-1,-1,2,2,-2,-2
+                       ,0,0,-1,-1,1,1,-2,-2,2,2
+                       ,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3};
+  
+  Int_t padhit = (Int_t)rint(track->GetPadHit(row));
+  Int_t timehit = (Int_t)rint(track->GetTimeHit(row));
+  Int_t padmax=-1;
+  Int_t timemax=-1;
+
+  for(Int_t index=0; index<nsearchbins; index++)
+    {
+      if(IsMaximum(padhit + padloop[index],timehit + timeloop[index])) 
+       {
+         padmax = padhit + padloop[index];
+         timemax = timehit + timeloop[index];
+         break;
+       }
+    }
+
+
+  //Define the cluster region of this hit:
+  //The region we look for, is centered at the local maxima
+  //and expanded around using the parametrized cluster width
+  //according to track parameters.
+  
+  Int_t xyw = (Int_t)ceil(sqrt(track->GetParSigmaY2(row))*GetYWidthFactor());
+  Int_t zw = (Int_t)ceil(sqrt(track->GetParSigmaZ2(row))*GetZWidthFactor());
+  
+  if(padmax>=0 && timemax>=0)
+    {
+      if(fDebug)
+       {
+#if 0
+         cout<<"Expanding cluster range using expected cluster widths: "<<xyw<<" "<<zw
+             <<" and setting local maxima pad "<<padmax<<" time "<<timemax<<endl;
+         if(xyw > 10 || zw > 10)
+           track->Print();
+#endif
+       }
+      
+      //Set the hit to the local maxima of the cluster.
+      //Store the maxima in the cluster model structure,
+      //-only temporary, it will be overwritten when calling SetCluster.
+      
+      track->GetClusterModel(row)->fDPad = padmax;
+      track->GetClusterModel(row)->fDTime = timemax;
+
+      for(Int_t i=padmax-xyw; i<=padmax+xyw; i++)
+       {
+         for(Int_t j=timemax-zw; j<=timemax+zw; j++)
+           {
+             if(i<0 || i>=AliHLTTPCTransform::GetNPads(row) || j<0 || j>=AliHLTTPCTransform::GetNTimeBins()) continue;
+             if(fRow[nt*i+j].fCharge)
+               {
+                 if(i < padrange[0]) padrange[0]=i;
+                 if(i > padrange[1]) padrange[1]=i;
+                 if(j < timerange[0]) timerange[0]=j;
+                 if(j > timerange[1]) timerange[1]=j;
+               }
+           }
+       }
+      if(fDebug)
+         {
+#if 0
+       cout<<"New padrange "<<padrange[0]<<" "<<padrange[1]<<" "<<" time "<<timerange[0]<<" "<<timerange[1]<<endl;
+#endif
+         }
+      return kTRUE;
+    }
+  return kFALSE;
+}
+
+Bool_t AliHLTTPCClusterFitter::IsMaximum(Int_t pad,Int_t time)
+{
+  if(pad<0 || pad >= AliHLTTPCTransform::GetNPads(fCurrentPadRow) ||
+     time<0 || time >= AliHLTTPCTransform::GetNTimeBins())
+    return kFALSE;
+  Int_t nt = AliHLTTPCTransform::GetNTimeBins()+1;
+  if(fRow[nt*pad+time].fUsed == kTRUE) return kFALSE; //Peak has been assigned before
+  Int_t charge = fRow[nt*pad+time].fCharge;
+  if(charge == 1023 || charge==0) return kFALSE;
+  
+  //fRow[nt*pad+time].fUsed = kTRUE;
+  //return kTRUE;
+
+  if(charge < fRow[nt*(pad-1)+(time-1)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad)+(time-1)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad+1)+(time-1)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad-1)+(time)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad+1)+(time)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad-1)+(time+1)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad)+(time+1)].fCharge) return kFALSE;
+  if(charge < fRow[nt*(pad+1)+(time+1)].fCharge) return kFALSE;
+  fRow[nt*pad+time].fUsed = kTRUE;
+  return kTRUE;
+}
+
+void AliHLTTPCClusterFitter::FitClusters(AliHLTTPCModelTrack *track,Int_t *padrange,Int_t *timerange)
+{
+  //Handle single and overlapping clusters
+    
+  //Check whether this cluster has been set before:
+  
+  Int_t size = FIT_PTS;
+  Int_t max_tracks = FIT_MAXPAR/NUM_PARS;
+  if(track->GetNOverlaps(fCurrentPadRow) > max_tracks)
+    {
+      cerr<<"AliHLTTPCClusterFitter::FitOverlappingClusters : Too many overlapping tracks"<<endl;
+      return;
+    }
+  Int_t *overlaps = track->GetOverlaps(fCurrentPadRow);
+  
+  //Check if at least one cluster is not already fitted
+  Bool_t all_fitted=kTRUE;
+  
+  Int_t k=-1;
+  while(k < track->GetNOverlaps(fCurrentPadRow))
+    {
+      AliHLTTPCModelTrack *tr=0;
+      if(k==-1)
+       tr = track;
+      else
+       tr = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
+      k++;
+      if(!tr) continue;
+      if(!tr->IsSet(fCurrentPadRow) && !tr->IsPresent(fCurrentPadRow))//cluster has not been set and is not present
+       {
+         all_fitted = kFALSE;
+         break;
+       }
+    }
+  if(all_fitted)
+    {
+      if(fDebug)
+         {
+#if 0
+       cout<<"But all the clusters were already fitted on row "<<fCurrentPadRow<<endl;
+#endif
+         }
+      return;
+    }
+  
+  //Allocate fit parameters array; this is interface to the C code
+  plane = new DPOINT[FIT_PTS];
+  memset(plane,0,FIT_PTS*sizeof(DPOINT));
+
+  Double_t x[FIT_PTS],y[FIT_PTS],s[FIT_PTS];
+  
+  //Fill the fit parameters:
+  Double_t a[FIT_MAXPAR];
+  Int_t lista[FIT_MAXPAR];
+  Double_t dev[FIT_MAXPAR],chisq_f;
+  
+  Int_t fit_pars=0;
+  
+  Int_t n_overlaps=0;
+  k=-1;
+  
+  //Fill the overlapping tracks:
+  while(k < track->GetNOverlaps(fCurrentPadRow))
+    {
+      AliHLTTPCModelTrack *tr=0;
+      if(k==-1)
+       tr = track;
+      else
+       tr = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
+      k++;
+      if(!tr) continue;
+      
+      if(tr->IsSet(fCurrentPadRow) && !tr->IsPresent(fCurrentPadRow)) continue;//Cluster fit failed before
+      
+      //Use the local maxima as the input to the fitting routine.
+      //The local maxima is temporary stored in the cluster model:
+      Int_t hitpad = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDPad);  
+      Int_t hittime = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDTime);
+      Int_t charge = fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*hitpad + hittime].fCharge;
+      
+      if(fDebug)
+         {
+#if 0
+       cout<<"Fitting track cluster, pad "<<tr->GetPadHit(fCurrentPadRow)<<" time "
+           <<tr->GetTimeHit(fCurrentPadRow)<<" charge "<<charge<<" at local maxima in pad "<<hitpad
+           <<" time "<<hittime<<" xywidth "<<sqrt(tr->GetParSigmaY2(fCurrentPadRow))
+           <<" zwidth "<<sqrt(tr->GetParSigmaZ2(fCurrentPadRow))<<endl;
+#endif
+         }
+      
+      if(charge==0)
+       {
+         cerr<<"Charge still zero!"<<endl;
+         exit(5);
+       }
+            
+      a[n_overlaps*NUM_PARS+2] = hitpad;
+      a[n_overlaps*NUM_PARS+4] = hittime;
+      
+      if(!tr->IsSet(fCurrentPadRow)) //Cluster is not fitted before
+       {
+         a[n_overlaps*NUM_PARS+1] = charge;
+         a[n_overlaps*NUM_PARS+3] = sqrt(tr->GetParSigmaY2(fCurrentPadRow)) * GetYWidthFactor();
+         a[n_overlaps*NUM_PARS+5] = sqrt(tr->GetParSigmaZ2(fCurrentPadRow)) * GetZWidthFactor();
+         a[n_overlaps*NUM_PARS+6] = sqrt(tr->GetParSigmaZ2(fCurrentPadRow)) * GetZWidthFactor();
+         lista[n_overlaps*NUM_PARS + 1] = 1;
+         lista[n_overlaps*NUM_PARS + 2] = 1;
+         lista[n_overlaps*NUM_PARS + 3] = 0;
+         lista[n_overlaps*NUM_PARS + 4] = 1;
+         lista[n_overlaps*NUM_PARS + 5] = 0;
+         lista[n_overlaps*NUM_PARS + 6] = 0;
+         fit_pars             += 3;
+       }
+      else  //Cluster was fitted before
+       {
+         if(!tr->IsPresent(fCurrentPadRow))
+           {
+             cerr<<"AliHLTTPCClusterFitter::FindClusters : Cluster not present; there is a bug here"<<endl;
+             exit(5);
+           }
+         Int_t charge;
+         Float_t xywidth,zwidth,pad,time;
+         tr->GetPad(fCurrentPadRow,pad);
+         tr->GetTime(fCurrentPadRow,time);
+         tr->GetClusterCharge(fCurrentPadRow,charge);
+         xywidth = sqrt(tr->GetParSigmaY2(fCurrentPadRow));
+         zwidth = sqrt(tr->GetParSigmaZ2(fCurrentPadRow));
+         if(fDebug)
+             {
+#if 0
+           cout<<"Cluster had been fitted before, pad "<<pad<<" time "<<time<<" charge "<<charge<<" width "<<xywidth<<" "<<zwidth<<endl;
+#endif
+             }
+         
+         a[n_overlaps*NUM_PARS+2] = pad;
+         a[n_overlaps*NUM_PARS+4] = time;
+         a[n_overlaps*NUM_PARS+1] = charge;
+         a[n_overlaps*NUM_PARS+3] = sqrt(xywidth) * GetYWidthFactor();
+         a[n_overlaps*NUM_PARS+5] = sqrt(zwidth) * GetZWidthFactor();
+         a[n_overlaps*NUM_PARS+6] = sqrt(zwidth) * GetZWidthFactor();
+
+         lista[n_overlaps*NUM_PARS + 1] = 1;
+         lista[n_overlaps*NUM_PARS + 2] = 0;
+         lista[n_overlaps*NUM_PARS + 3] = 0;
+         lista[n_overlaps*NUM_PARS + 4] = 0;
+         lista[n_overlaps*NUM_PARS + 5] = 0;
+         lista[n_overlaps*NUM_PARS + 6] = 0;
+         fit_pars             += 1;
+       }
+      n_overlaps++;
+    }
+  
+  if(n_overlaps==0) //No clusters here
+    {
+      delete [] plane;
+      return;
+    }
+
+  Int_t pad_num=0;
+  Int_t time_num_max=0;
+  Int_t ndata=0;
+  Int_t tot_charge=0;
+  if(fDebug)
+      {
+#if 0
+    cout<<"Padrange "<<padrange[0]<<" "<<padrange[1]<<" timerange "<<timerange[0]<<" "<<timerange[1]<<endl;
+#endif
+      }
+  for(Int_t i=padrange[0]; i<=padrange[1]; i++)
+    {
+      Int_t max_charge = 0;
+      Int_t time_num=0;
+      for(Int_t j=timerange[0]; j<=timerange[1]; j++)
+       {
+         Int_t charge = fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*i + j].fCharge;
+         
+         if(charge <= 0) continue;
+
+         time_num++;
+         if(charge > max_charge)
+           {
+             max_charge = charge;
+             //time_num++;
+           }
+         if(fDebug)
+             {
+#if 0
+           cout<<"Filling padrow "<<fCurrentPadRow<<" pad "<<i<<" time "<<j<<" charge "<<charge<<endl;
+#endif
+             }
+         tot_charge += charge;
+         ndata++;
+         if(ndata >= size)
+           {
+             cerr<<"Too many points; row "<<fCurrentPadRow<<" padrange "<<padrange[0]<<" "<<padrange[1]<<" timerange "
+                 <<timerange[0]<<" "<<timerange[1]<<endl;
+             exit(5);
+           }
+
+         plane[ndata].u = (Double_t)i;
+         plane[ndata].v = (Double_t)j;
+         x[ndata]=ndata;
+         y[ndata]=charge;
+         s[ndata]= 1 + sqrt((Double_t)charge);
+       }
+      if(max_charge) //there was charge on this pad
+       pad_num++;
+      if(time_num_max < time_num)
+       time_num_max = time_num;
+    }
+  
+  if(pad_num <= 1 || time_num_max <=1 || n_overlaps > fNmaxOverlaps || ndata <= fit_pars) //too few to do fit
+    {
+      SetClusterfitFalse(track);
+      if(fDebug)
+         {
+#if 0
+       cout<<"Too few digits or too many overlaps: "<<pad_num<<" "<<time_num_max<<" "<<n_overlaps<<" ndata "<<ndata<<" fit_pars "<<fit_pars<<endl;
+#endif
+         }
+      delete [] plane;
+      return;
+    }
+
+  
+  Int_t npars = n_overlaps * NUM_PARS;
+  if(fDebug)
+      {
+#if 0
+    cout<<"Number of overlapping clusters "<<n_overlaps<<endl;
+#endif
+      }
+  Int_t ret = lev_marq_fit( x, y, s, ndata, a, lista, dev, npars, &chisq_f, f2gauss5 );
+  
+  if(ret<0)
+    {
+      SetClusterfitFalse(track);
+      fFailed++;
+      fFitError++;
+      delete [] plane;
+      return;
+      //exit(5);
+    }
+
+  chisq_f /= (ndata-fit_pars);
+  if(fDebug)
+      {
+#if 0
+    cout<<"Chisq "<<chisq_f<<endl;
+#endif
+      }
+  
+  Bool_t overlapping=kFALSE;
+  if(track->GetNOverlaps(fCurrentPadRow) > 0)//There is a overlap
+    overlapping=kTRUE;
+  
+  k=-1;
+  n_overlaps=0;
+  while(k < track->GetNOverlaps(fCurrentPadRow))
+    {
+      AliHLTTPCModelTrack *tr=0;
+      if(k==-1)
+       tr = track;
+      else
+       tr = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[k]);
+      k++;
+      if(!tr) continue;
+      if(!tr->IsPresent(fCurrentPadRow))
+       {
+         if(tr->IsSet(fCurrentPadRow)) continue;//This cluster has been set before
+         
+         if(chisq_f < fChiSqMax[(Int_t)overlapping])//cluster fit is good enough
+           {
+             tot_charge = (Int_t)(a[n_overlaps*NUM_PARS+1] * a[n_overlaps*NUM_PARS+3] * a[n_overlaps*NUM_PARS+5]);
+             Float_t fpad = a[n_overlaps*NUM_PARS+2];
+             Float_t ftime = a[n_overlaps*NUM_PARS+4];
+             if(tot_charge < 0 || fpad < -1 || fpad > AliHLTTPCTransform::GetNPads(fCurrentPadRow) || 
+                ftime < -1 || ftime > AliHLTTPCTransform::GetNTimeBins())
+               {
+                 if(fDebug)
+                     {
+#if 0
+                   cout<<"AliHLTTPCClusterFitter::Fatal result(s) in fit; in slice "<<fSlice<<" row "<<fCurrentPadRow
+                       <<"; pad "<<fpad<<" time "<<ftime<<" charge "<<tot_charge<<" xywidth "<<a[n_overlaps*NUM_PARS+3]
+                       <<" zwidth "<<a[n_overlaps*NUM_PARS+5]<<" peakcharge "<<a[n_overlaps*NUM_PARS+1]<<endl;
+#endif
+                     }
+                 tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
+                 fFailed++;
+                 fResultError++;
+                 continue;
+               }
+             
+             tr->SetCluster(fCurrentPadRow,fpad,ftime,tot_charge,0,0,pad_num);
+             if(fDebug)
+                 {
+#if 0
+               cout<<"Setting cluster in pad "<<a[n_overlaps*NUM_PARS+2]<<" time "<<a[n_overlaps*NUM_PARS+4]<<" charge "<<tot_charge<<endl;
+#endif
+                 }
+             /*
+             //Set the digits to used:
+             for(Int_t i=padrange[0]; i<=padrange[1]; i++)
+             for(Int_t j=timerange[0]; j<=timerange[1]; j++)
+             fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*i + j].fUsed = kTRUE;
+             */
+             fFitted++;
+           }
+         else //fit was too bad
+           {
+             if(fDebug)
+                 {
+#if 0
+               cout<<"Cluster fit was too bad"<<endl;
+#endif
+                 }
+             tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
+             fBadFitError++;
+             fFailed++;
+           }
+       }
+      n_overlaps++;
+    }
+  
+  delete [] plane;
+}
+
+void AliHLTTPCClusterFitter::SetClusterfitFalse(AliHLTTPCModelTrack *track)
+{
+  //Cluster fit failed, so set the clusters to all the participating
+  //tracks to zero.
+  
+  Int_t i=-1;
+  Int_t *overlaps = track->GetOverlaps(fCurrentPadRow);
+  while(i < track->GetNOverlaps(fCurrentPadRow))
+    {
+      AliHLTTPCModelTrack *tr=0;
+      if(i==-1)
+       tr = track;
+      else
+       tr = (AliHLTTPCModelTrack*)fProcessTracks->GetCheckedTrack(overlaps[i]);
+      i++;
+      if(!tr) continue;
+      
+      //Set the digit data to unused, so it can be fitted to another bastard:
+      Int_t hitpad = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDPad);  
+      Int_t hittime = (Int_t)rint(tr->GetClusterModel(fCurrentPadRow)->fDTime);
+      fRow[(AliHLTTPCTransform::GetNTimeBins()+1)*hitpad + hittime].fUsed = kFALSE;
+      
+      tr->SetCluster(fCurrentPadRow,0,0,0,0,0,0);
+    }
+
+}
+
+
+void AliHLTTPCClusterFitter::AddClusters()
+{
+  if(!fClusters)
+    {
+      fClusters = new AliHLTTPCSpacePointData[fNMaxClusters];
+      fNClusters=0;
+    }
+  
+  if(fDebug)
+      {
+#if 0
+    cout<<"Writing cluster in slice "<<fSlice<<" patch "<<fPatch<<endl;
+#endif
+      }
+  
+  AliHLTTPCTrackArray *tracks=0;
+  if(fSeeding==kTRUE)
+    tracks = fSeeds;
+  else
+    tracks = fTracks;
+  
+  if(!tracks)
+    return;
+  
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *tr = (AliHLTTPCModelTrack*)tracks->GetCheckedTrack(i);
+      if(!tr) continue;
+      
+      UInt_t *hitids = tr->GetHitNumbers();
+      Int_t nhits = tr->GetNHits();
+      for(Int_t i=fRowMax; i>=fRowMin; i--)
+       {
+         if(fSeeding)
+           if(tr->GetClusterModel(i)->fSlice != fSlice) continue;
+         if(!tr->IsPresent(i)) continue;
+         fCurrentPadRow = i;
+         Float_t pad,time,xywidth,zwidth;
+         Int_t charge;
+         tr->GetPad(i,pad);
+         tr->GetTime(i,time);
+         tr->GetClusterCharge(i,charge);
+
+         if(pad < -1 || pad >= AliHLTTPCTransform::GetNPads(i) || 
+            time < -1 || time >= AliHLTTPCTransform::GetNTimeBins())
+           {
+             continue;
+#if 0
+             cout<<"slice "<<fSlice<<" row "<<i<<" pad "<<pad<<" time "<<time<<endl;
+#endif
+             tr->Print();
+             exit(5);
+           }
+
+         tr->CalculateClusterWidths(i,kTRUE); //Parametrize errors
+         
+         tr->GetXYWidth(i,xywidth);
+         tr->GetZWidth(i,zwidth);
+         Float_t xyz[3];
+         Int_t sector,row;
+         AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
+         
+         AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+         
+         if(fNClusters >= fNMaxClusters)
+           {
+             cerr<<"AliHLTTPCClusterFitter::AddClusters : Too many clusters "<<fNClusters<<endl;
+             exit(5);
+           }
+         
+         fClusters[fNClusters].fX = xyz[0];
+         fClusters[fNClusters].fY = xyz[1];
+         fClusters[fNClusters].fZ = xyz[2];
+         fClusters[fNClusters].fCharge = charge;
+         fClusters[fNClusters].fPadRow = i;
+         Int_t pa = AliHLTTPCTransform::GetPatch(i);
+         if(xywidth==0 || zwidth==0)
+           cerr<<"AliHLTTPCClusterFitter::AddClusters : Cluster with zero width"<<endl;
+         if(xywidth>0)
+           fClusters[fNClusters].fSigmaY2 = xywidth*pow(AliHLTTPCTransform::GetPadPitchWidth(pa),2);
+         else
+           fClusters[fNClusters].fSigmaY2 = 1;
+         if(zwidth>0)
+           fClusters[fNClusters].fSigmaZ2 = zwidth*pow(AliHLTTPCTransform::GetZWidth(),2);
+         else
+           fClusters[fNClusters].fSigmaZ2 = 1;
+         Int_t pat=fPatch;
+         if(fPatch==-1)
+           pat=0;
+         fClusters[fNClusters].fID = fNClusters + ((fSlice&0x7f)<<25)+((pat&0x7)<<22);
+         
+         if(nhits >= AliHLTTPCTransform::GetNRows())
+           {
+             cerr<<"AliHLTTPCClusterFitter::AddClusters : Cluster counter of out range "<<nhits<<endl;
+             exit(5);
+           }
+         hitids[nhits++] = fClusters[fNClusters].fID;
+         
+#ifdef do_mc
+         Int_t trackID[3];
+         Int_t fpad = (Int_t)rint(pad);
+         Int_t ftime = (Int_t)rint(time);
+         if(fpad < 0)
+           fpad=0;
+         if(fpad >= AliHLTTPCTransform::GetNPads(i))
+           fpad = AliHLTTPCTransform::GetNPads(i)-1;
+         if(ftime<0)
+           ftime=0;
+         if(ftime >= AliHLTTPCTransform::GetNTimeBins())
+           ftime = AliHLTTPCTransform::GetNTimeBins()-1;
+         GetTrackID(fpad,ftime,trackID);
+         fClusters[fNClusters].fTrackID[0] = trackID[0];
+         fClusters[fNClusters].fTrackID[1] = trackID[1];
+         fClusters[fNClusters].fTrackID[2] = trackID[2];
+#endif  
+         //cout<<"Setting id "<<trackID[0]<<" on pad "<<pad<<" time "<<time<<" row "<<i<<endl;
+         fNClusters++;
+       }
+      
+      //Copy back the number of assigned clusters
+      tr->SetNHits(nhits);
+      
+    }
+}
+
+void AliHLTTPCClusterFitter::WriteTracks(Int_t min_hits)
+{
+  if(!fSeeds)
+    return;
+  
+  AliHLTTPCTrackArray *fakes = new AliHLTTPCTrackArray();
+  
+  Int_t clustercount=0;
+  for(Int_t i=0; i<fSeeds->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *tr = (AliHLTTPCModelTrack*)fSeeds->GetCheckedTrack(i);
+      if(!tr) continue;
+      if(tr->GetNHits() < min_hits)
+       {
+         fakes->AddLast(tr);
+         fSeeds->Remove(i);
+       }
+      clustercount += tr->GetNHits();
+    }
+  
+#if 0
+  cout<<"Writing "<<clustercount<<" clusters"<<endl;
+#endif
+  fSeeds->Compress();
+  AliHLTTPCMemHandler mem;
+  Char_t filename[1024];
+  sprintf(filename,"%s/fitter/tracks_%d.raw",fPath,fEvent);
+  mem.SetBinaryOutput(filename);
+  mem.TrackArray2Binary(fSeeds);
+  mem.CloseBinaryOutput();
+  
+  //Write the fake tracks to its own file
+  mem.Free();
+  sprintf(filename,"%s/fitter/tracks_fakes_%d.raw",fPath,fEvent);
+  mem.SetBinaryOutput(filename);
+  mem.TrackArray2Binary(fakes);
+  mem.CloseBinaryOutput();
+  delete fakes;
+}
+
+void AliHLTTPCClusterFitter::WriteClusters(Bool_t global)
+{
+  AliHLTTPCMemHandler mem;
+  if(fDebug)
+      {
+#if 0
+    cout<<"Write "<<fNClusters<<" clusters to file"<<endl;
+#endif
+      }
+  Char_t filename[1024];
+  sprintf(filename,"%s/fitter/points_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  mem.SetBinaryOutput(filename);
+  if(global == kTRUE)
+    mem.Transform(fNClusters,fClusters,fSlice);
+  mem.Memory2Binary(fNClusters,fClusters);
+  mem.CloseBinaryOutput();
+  mem.Free();
+  
+  delete [] fClusters;
+  fClusters=0;
+  fNClusters=0;
+}
+
diff --git a/HLT/TPCLib/Ref/AliHLTTPCClusterFitter.h b/HLT/TPCLib/Ref/AliHLTTPCClusterFitter.h
new file mode 100644 (file)
index 0000000..f93c29e
--- /dev/null
@@ -0,0 +1,72 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_ClusterFitter
+#define AliHLTTPC_ClusterFitter
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCModeller.h"
+#include "AliHLTTPCTransform.h"
+
+class AliHLTTPCModelTrack;
+class AliHLTTPCTrackArray;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCClusterFitter : public AliHLTTPCModeller {
+  
+ private:
+  Int_t fNmaxOverlaps;
+  Int_t fRowMin;
+  Int_t fRowMax;
+  Float_t fChiSqMax[2];
+  Float_t fYInnerWidthFactor;
+  Float_t fZInnerWidthFactor;
+  Float_t fYOuterWidthFactor;
+  Float_t fZOuterWidthFactor;
+  Int_t fFitted;
+  Int_t fFailed;
+  static Int_t fBadFitError;
+  static Int_t fFitError;
+  static Int_t fResultError;
+  static Int_t fFitRangeError;
+  Bool_t fSeeding;
+  Int_t fNMaxClusters;
+  Int_t fNClusters;
+  Int_t fEvent;
+  AliHLTTPCTrackArray *fSeeds; //!
+  AliHLTTPCTrackArray *fProcessTracks; //!
+  AliHLTTPCSpacePointData *fClusters; //!
+  
+  void FitClusters(AliHLTTPCModelTrack *track,Int_t *padrange,Int_t *timerange);
+  Bool_t CheckCluster(Int_t trackindex);
+  Bool_t IsMaximum(Int_t pad,Int_t time);
+  Bool_t SetFitRange(AliHLTTPCModelTrack *track,Int_t *padrange,Int_t *timerange);
+  void SetClusterfitFalse(AliHLTTPCModelTrack *track);
+  
+ public:
+  AliHLTTPCClusterFitter();
+  AliHLTTPCClusterFitter(Char_t *path);
+  virtual ~AliHLTTPCClusterFitter();
+  
+  void Init(Int_t slice,Int_t patch,Int_t *rowrange,AliHLTTPCTrackArray *tracks);
+  void Init(Int_t slice,Int_t patch);
+  void LoadSeeds(Int_t *rowrange,Bool_t offline=kTRUE,Int_t eventnr=0);
+  void LoadLocalSegments();
+  void FindClusters();
+  void AddClusters();
+  void WriteClusters(Bool_t global=kTRUE);
+  void WriteTracks(Int_t min_hits);
+  void SetNmaxOverlaps(Int_t i) {fNmaxOverlaps=i;}
+  void SetChiSqMax(Float_t f,Bool_t overlapping) {fChiSqMax[(Int_t)overlapping] = f;}
+  void SetInnerWidthFactor(Float_t y,Float_t z) {fYInnerWidthFactor=y; fZInnerWidthFactor=z;}
+  void SetOuterWidthFactor(Float_t y,Float_t z) {fYOuterWidthFactor=y; fZOuterWidthFactor=z;}
+  
+  Float_t GetYWidthFactor() {return fCurrentPadRow < AliHLTTPCTransform::GetLastRow(1) ? fYInnerWidthFactor : fYOuterWidthFactor;}
+  Float_t GetZWidthFactor() {return fCurrentPadRow < AliHLTTPCTransform::GetLastRow(1) ? fZInnerWidthFactor : fZOuterWidthFactor;}
+  AliHLTTPCTrackArray *GetSeeds() {return fSeeds;}
+  
+  
+  ClassDef(AliHLTTPCClusterFitter,1) 
+
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCCompress.cxx b/HLT/TPCLib/Ref/AliHLTTPCCompress.cxx
new file mode 100644 (file)
index 0000000..2b22ebf
--- /dev/null
@@ -0,0 +1,504 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "bitio.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCModels.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCModelTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCDataCompressor.h"
+
+#if 0
+#ifdef use_root
+#include <TH1.h>
+#include <TH2.h>
+#include <TRandom.h>
+#endif
+#ifdef use_aliroot
+#include "AliHLTTPCFileHandler.h"
+#endif
+#endif
+
+#include "AliHLTTPCCompress.h"
+
+#if GCCVERSION == 3
+using namespace std;
+#endif
+
+//_____________________________________________________________
+//
+//  AliHLTTPCCompress
+//
+// Class for compressing and uncompressing data.
+
+ClassImp(AliHLTTPCCompress)
+
+AliHLTTPCCompress::AliHLTTPCCompress()
+{
+  fTracks=0;
+  fSlice =0;
+  fPatch=0;
+  fWriteShape=kFALSE;
+  fEvent=-1;
+}
+
+AliHLTTPCCompress::AliHLTTPCCompress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event)
+{
+  fEvent=event;
+  fSlice=slice;
+  fPatch=patch;
+  fTracks=0;
+  sprintf(fPath,"%s",path);
+  fWriteShape=writeshape;
+}
+
+AliHLTTPCCompress::~AliHLTTPCCompress()
+{
+  if(fTracks)
+    delete fTracks;
+}
+
+Bool_t AliHLTTPCCompress::WriteFile(AliHLTTPCTrackArray *tracks,Char_t *filename)
+{
+  Char_t fname[1024];
+  if(filename)
+    sprintf(fname,"%s/comp/%s",fPath,filename);
+  else if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+
+  FILE *file = fopen(fname,"w");
+  if(!file)
+    {
+      cerr<<"AliHLTTPCCompress::WriteFile : Error opening file "<<fname<<endl;
+      return kFALSE;
+    }
+  Short_t ntracks = tracks->GetNTracks();
+    
+  Int_t count=0;
+  AliHLTTPCClusterModel *clusters=0;
+  AliHLTTPCTrackModel *model=0;
+  for(Int_t i=0; i<ntracks; i++)
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)tracks->GetCheckedTrack(i);
+      if(!track) continue;
+
+      //Do not save useless tracks or clusters:
+      //if(track->GetNPresentClusters() == 0)
+      //continue;
+      
+      track->FillModel();
+      model = track->GetModel();
+      //if(model->fNClusters==0) continue;
+      clusters = track->GetClusters();
+      if(fwrite(model,sizeof(AliHLTTPCTrackModel),1,file)!=1) break;
+      //if(fwrite(clusters,model->fNClusters*sizeof(AliHLTTPCClusterModel),1,file)!=1) break;
+      if(fwrite(clusters,AliHLTTPCTransform::GetNRows(fPatch)*sizeof(AliHLTTPCClusterModel),1,file)!=1) break;
+      count++;
+      
+    }
+  fclose(file);
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCCompress::ReadFile(Char_t which,Char_t *filename)
+{
+  //Read the trackfile.
+
+  Char_t fname[1024];
+  if(filename)
+    sprintf(fname,"%s/comp/%s",fPath,filename);
+  else
+    {
+      if(which == 'm')
+       {
+         if(fEvent<0)
+           sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
+         else
+           sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+       }
+      else if(which == 'u')
+       {
+         if(fEvent<0)
+           sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
+         else
+           sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+       }
+      else
+       {
+         cerr<<"AliHLTTPCCompress::ReadFile() : Wrong option"<<endl;
+         return kFALSE;
+       }
+    }
+
+  FILE *file = fopen(fname,"r");
+  if(!file)
+    {
+      cerr<<"AliHLTTPCCompress::ReadFile : Cannot open file "<<fname<<endl;
+      return kFALSE;
+    }
+
+  if(fTracks)
+    delete fTracks;
+  fTracks = new AliHLTTPCTrackArray("AliHLTTPCModelTrack");
+  
+  while(!feof(file))
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fTracks->NextTrack();
+      track->Init(fSlice,fPatch);
+      AliHLTTPCTrackModel *model = track->GetModel();
+      AliHLTTPCClusterModel *clusters = track->GetClusters();
+      if(fread(model,sizeof(AliHLTTPCTrackModel),1,file)!=1) break;
+      //if(fread(clusters,model->fNClusters*sizeof(AliHLTTPCClusterModel),1,file)!=1) break;
+      if(fread(clusters,AliHLTTPCTransform::GetNRows(fPatch)*sizeof(AliHLTTPCClusterModel),1,file)!=1) break;
+      track->FillTrack();
+    }
+
+  fTracks->RemoveLast();
+  fclose(file);
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCCompress::CompressFile()
+{
+  Char_t fname[100];
+  if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  BIT_FILE *output = OpenOutputBitFile(fname);
+  
+  if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  
+  FILE *input = fopen(fname,"r");
+  if(!input)
+    {
+      cerr<<"AliHLTTPCCompress::CompressFile() : Error opening file: "<<fname<<endl;
+      return kFALSE;
+    }
+
+  AliHLTTPCTrackModel track;
+  AliHLTTPCClusterModel cluster;
+  Int_t temp;
+  Int_t power;
+  
+  Int_t timeo,pado,chargeo,shapeo;
+  timeo=pado=chargeo=shapeo=0;
+  while(!feof(input))
+    {
+      if(fread(&track,sizeof(AliHLTTPCTrackModel),1,input)!=1) break;
+      
+      if(output->mask != 0x80) //Write the current byte to file.
+       {
+         //cerr<<"\nAliHLTTPCCompress::CompressFile() : Writing overhead bits!!!"<<endl;
+         if(putc(output->rack,output->file )!=output->rack)
+           cerr<<"AliHLTTPCCompress::ComressFile : Error writing to bitfile"<<endl;
+         output->mask=0x80;
+         output->rack=0;
+       }
+      
+      //Write track parameters:
+      fwrite(&track,sizeof(AliHLTTPCTrackModel),1,output->file);
+      
+      Int_t origslice=-1,slice,clustercount=0;
+      for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(fPatch); i++)
+       {
+         if(fread(&cluster,sizeof(AliHLTTPCClusterModel),1,input)!=1) break;
+         
+         //Write empty flag:
+         temp = (Int_t)cluster.fPresent;
+         OutputBit(output,temp);
+         if(!temp) continue;
+         
+         if(cluster.fSlice<0 || cluster.fSlice>35)
+           {
+             cerr<<"AliHLTTPCDataCompress::CompressFile : Fucked up slice number :"<<cluster.fSlice<<endl;
+             exit(5);
+           }
+         
+         //Write slice number of first point
+         if(clustercount==0)
+           {
+             origslice = cluster.fSlice;
+             OutputBits(output,origslice,6); //Need 6 bits to encode slice number
+           }
+         else
+           {
+             slice = cluster.fSlice;
+             if(slice == origslice)
+               OutputBit(output,0);
+             else
+               {
+                 OutputBit(output,1);
+                 OutputBits(output,slice,6);
+                 origslice=slice;
+               }
+           }
+         
+         //Write time information:
+         temp = (Int_t)rint(cluster.fDTime);
+         if(temp<0)
+           OutputBit(output,0);
+         else
+           OutputBit(output,1);
+         power = 1<<(AliHLTTPCDataCompressor::GetNTimeBits()-1);
+         if(abs(temp)>=power)
+           {
+             timeo++;
+             temp=power - 1;
+           }
+         OutputBits(output,abs(temp),(AliHLTTPCDataCompressor::GetNTimeBits()-1));
+         
+         //Write pad information:
+         temp = (Int_t)rint(cluster.fDPad);
+         if(temp<0)
+           OutputBit(output,0);
+         else
+           OutputBit(output,1);
+         power = 1<<(AliHLTTPCDataCompressor::GetNPadBits()-1);
+         if(abs(temp)>=power)
+           {
+             pado++;
+             temp=power - 1;
+           }
+         OutputBits(output,abs(temp),(AliHLTTPCDataCompressor::GetNPadBits()-1));
+         
+         //Write charge information:
+         temp = (Int_t)cluster.fDCharge;
+         power = 1<<(AliHLTTPCDataCompressor::GetNChargeBits());
+         if(abs(temp)>=power)
+           {
+             chargeo++;
+             temp=power - 1;
+           }
+         OutputBits(output,abs(temp),(AliHLTTPCDataCompressor::GetNChargeBits()));
+         
+         if(fWriteShape)
+           {
+             //Write shape information:
+             temp = (Int_t)cluster.fDSigmaY2;
+             if(temp<0)
+               OutputBit(output,0);
+             else
+               OutputBit(output,1);
+             power = 1<<(AliHLTTPCDataCompressor::GetNShapeBits()-1);
+             if(abs(temp) >= power)
+               {
+                 shapeo++;
+                 temp = power - 1;
+               }
+             OutputBits(output,abs(temp),(AliHLTTPCDataCompressor::GetNShapeBits()-1));
+             
+             temp = (Int_t)cluster.fDSigmaZ2;
+             if(temp<0)
+               OutputBit(output,0);
+             else
+               OutputBit(output,1);
+             power = 1<<(AliHLTTPCDataCompressor::GetNShapeBits()-1);
+             if(abs(temp) >= power)
+               {
+                 shapeo++;
+                 temp=power - 1;
+               }
+             OutputBits(output,abs(temp),(AliHLTTPCDataCompressor::GetNShapeBits()-1));
+           }
+         
+         clustercount++;
+       }
+    }
+  
+  fclose(input);
+  CloseOutputBitFile(output);
+  if(pado || timeo || chargeo || shapeo)
+    {
+#if 0
+      cout<<endl<<"Saturations: "<<endl
+         <<"Pad "<<pado<<endl
+         <<"Time "<<timeo<<endl
+         <<"Charge "<<chargeo<<endl
+         <<"Shape "<<shapeo<<endl<<endl;
+#endif
+    }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCCompress::ExpandFile()
+{
+  Char_t fname[100];
+  if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  BIT_FILE *input = OpenInputBitFile(fname);
+  
+  if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+  FILE *output = fopen(fname,"w");
+  if(!output)
+    {
+      cerr<<"AliHLTTPCCompress::ExpandFile() : Error opening file: "<<fname<<endl;
+      return kFALSE;
+    }
+
+  AliHLTTPCTrackModel trackmodel;
+  AliHLTTPCClusterModel *clusters=0;
+  Int_t count=0;
+  
+  clusters = new AliHLTTPCClusterModel[(AliHLTTPCTransform::GetNRows(fPatch))];
+  while(!feof(input->file))
+    {
+      input->mask=0x80;//make sure we read a new byte from file.
+      
+      //Read and write track:
+      if(fread(&trackmodel,sizeof(AliHLTTPCTrackModel),1,input->file)!=1) break;
+      fwrite(&trackmodel,sizeof(AliHLTTPCTrackModel),1,output);
+
+      memset(clusters,0,AliHLTTPCTransform::GetNRows(fPatch)*sizeof(AliHLTTPCClusterModel));
+      Int_t origslice=-1,clustercount=0;
+      for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(fPatch); i++)
+       {
+         Int_t temp,sign;
+         
+         //Read empty flag:
+         temp = InputBit(input);
+         if(!temp) 
+           {
+             clusters[i].fPresent=kFALSE;
+             continue;
+           }
+         clusters[i].fPresent=kTRUE;
+         
+         //Read slice information
+         if(clustercount==0)
+           {
+             temp = InputBits(input,6);
+             clusters[i].fSlice = temp;
+             origslice = temp;
+           }
+         else
+           {
+             temp = InputBit(input);
+             if(!temp)//no change
+               clusters[i].fSlice = origslice;
+             else
+               {
+                 temp = InputBits(input,6);//read new slice
+                 clusters[i].fSlice = temp;
+                 origslice = temp;//store new slice
+               }
+           }
+         
+         //Read time information:
+         sign=InputBit(input);
+         temp = InputBits(input,(AliHLTTPCDataCompressor::GetNTimeBits()-1));
+         if(!sign)
+           temp*=-1;
+         clusters[i].fDTime = temp;
+         
+         //Read pad information:
+         sign=InputBit(input);
+         temp = InputBits(input,(AliHLTTPCDataCompressor::GetNPadBits()-1));
+         if(!sign)
+           temp*=-1;
+         clusters[i].fDPad = temp;
+         
+         //Read charge information:
+         temp=InputBits(input,(AliHLTTPCDataCompressor::GetNChargeBits()));
+         clusters[i].fDCharge = temp;
+         
+         if(fWriteShape)
+           {
+             //Read shape information:
+             sign = InputBit(input);
+             temp = InputBits(input,(AliHLTTPCDataCompressor::GetNShapeBits()-1));
+             if(!sign)
+               temp*=-1;
+             clusters[i].fDSigmaY2 = temp;
+             
+             sign = InputBit(input);
+             temp = InputBits(input,(AliHLTTPCDataCompressor::GetNShapeBits()-1));
+             if(!sign)
+               temp*=-1;
+             clusters[i].fDSigmaZ2 = temp;
+           }
+         clustercount++;
+       }
+      count++;
+      //fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliHLTTPCClusterModel),1,output);
+      fwrite(clusters,AliHLTTPCTransform::GetNRows(fPatch)*sizeof(AliHLTTPCClusterModel),1,output);
+    }
+  
+  delete [] clusters;
+  fclose(output);
+  CloseInputBitFile(input);
+  return kTRUE;
+}
+
+void AliHLTTPCCompress::PrintCompRatio(ofstream *outfile)
+{
+  AliHLTTPCMemHandler *mem = new AliHLTTPCMemHandler();
+  Char_t fname[1024];
+  UInt_t remain_size=0,digit_size=0;
+  for(Int_t i=0; i<36; i++)
+    {
+      if(fEvent<0)
+       sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,i,-1);
+      else
+       sprintf(fname,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
+      mem->SetBinaryInput(fname);
+      remain_size += mem->GetFileSize();
+      mem->CloseBinaryInput();
+
+      sprintf(fname,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,fEvent,i,-1);
+      mem->SetBinaryInput(fname);
+      digit_size += mem->GetFileSize();
+      mem->CloseBinaryInput();
+    }
+  
+  
+  if(fEvent<0)
+    sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
+  else
+    sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
+
+  mem->SetBinaryInput(fname);
+  UInt_t compress_size = mem->GetFileSize();
+  mem->CloseBinaryInput();
+  
+  if(digit_size==0)
+    {
+      cerr<<"AliHLTTPCCompress::PrintCompRatio : Zero digit size, not able to obtain comp. ratios!"<<endl;
+      return;
+    }
+  
+  if(outfile)
+    {
+      ofstream &out = *outfile;
+      out<<compress_size<<' '<<remain_size<<' '<<digit_size<<endl;
+    }
+
+#if 0
+  Float_t compratio = (Float_t)(compress_size + remain_size)/(Float_t)digit_size;
+  cout<<"=========================================="<<endl;
+  cout<<"Original digits size : "<<digit_size/1000<<" kByte ( 100 % )"<<endl;
+  cout<<"Compressed file size : "<<compress_size/1000<<" kByte ( "<<(Float_t)compress_size*100/(Float_t)digit_size<<" % )"<<endl;
+  cout<<"Remainig file size   : "<<remain_size/1000<<" kByte ( "<<(Float_t)remain_size*100/(Float_t)digit_size<<" % )"<<endl;
+  cout<<"---------------------- "<<endl;
+  cout<<"Compression ratio    : "<<compratio*100<<" %"<<endl;
+  cout<<"=========================================="<<endl;
+#endif
+}
diff --git a/HLT/TPCLib/Ref/AliHLTTPCCompress.h b/HLT/TPCLib/Ref/AliHLTTPCCompress.h
new file mode 100644 (file)
index 0000000..0ac127b
--- /dev/null
@@ -0,0 +1,36 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_Compress
+#define AliHLTTPC_Compress
+
+class AliHLTTPCTrackArray;
+
+class AliHLTTPCCompress {
+  
+ private:
+  AliHLTTPCTrackArray *fTracks; //!
+
+  Int_t fSlice;
+  Int_t fPatch;
+  Char_t fPath[100];
+  Bool_t fWriteShape;
+  Int_t fEvent;
+
+ public:
+  AliHLTTPCCompress();
+  AliHLTTPCCompress(Int_t slice,Int_t patch,Char_t *path="./",Bool_t writeshape=kFALSE,Int_t event=-1);
+  virtual ~AliHLTTPCCompress();
+  
+  Bool_t WriteFile(AliHLTTPCTrackArray *tracks,Char_t *filename=0);
+  Bool_t ReadFile(Char_t which,Char_t *filename=0);
+  Bool_t CompressFile();
+  Bool_t ExpandFile();
+  void PrintCompRatio(ofstream *outfile=0);
+  
+  AliHLTTPCTrackArray *GetTracks() {return fTracks;}
+  
+  ClassDef(AliHLTTPCCompress,1) 
+
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCConfMapFit.cxx b/HLT/TPCLib/Ref/AliHLTTPCConfMapFit.cxx
new file mode 100644 (file)
index 0000000..90c4263
--- /dev/null
@@ -0,0 +1,519 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCConfMapFit.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTransform.h"
+
+/** \class AliHLTTPCConfMapFit
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapFit
+//
+// Fit class for conformal mapping tracking
+</pre>
+*/
+
+ClassImp(AliHLTTPCConfMapFit)
+
+Double_t AliHLTTPCConfMapFit::pi=3.14159265358979323846;
+
+AliHLTTPCConfMapFit::AliHLTTPCConfMapFit(AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex)
+{
+  //constructor
+  fTrack = track;
+  fVertex = vertex;
+  BFACT = 0.0029980;
+  
+}
+
+Int_t AliHLTTPCConfMapFit::FitHelix()
+{
+  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->currentHit;
+      cHit->SetXYWeight( 1./ (Double_t)(cHit->GetXerr()*cHit->GetXerr() + cHit->GetYerr()*cHit->GetYerr()) );
+      wsum      += cHit->GetXYWeight() ;
+      xav       += cHit->GetXYWeight() * cHit->GetX() ;
+      yav       += cHit->GetXYWeight() * cHit->GetY() ;
+    }
+  if(co!=num_of_hits) 
+    LOG(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->currentHit;
+      xi        = cHit->GetX() - xav ;
+      yi        = cHit->GetY() - yav ;
+      xxav     += xi * xi * cHit->GetXYWeight() ;
+      xyav     += xi * yi * cHit->GetXYWeight() ;
+      yyav     += yi * yi * cHit->GetXYWeight() ;
+    }
+  
+  if (fTrack->ComesFromMainVertex() == true)
+    {
+      xi        = fVertex->GetX() - xav ;
+      yi        = fVertex->GetY() - yav ;
+      xxav     += xi * xi * fVertex->GetXYWeight() ;
+      xyav     += xi * yi * fVertex->GetXYWeight() ;
+      yyav     += yi * yi * fVertex->GetXYWeight() ; 
+    }
+  xxav = xxav / wsum ;
+  xyav = xyav / wsum ;
+  yyav = yyav / wsum ;
+//
+//-->  ROTATE COORDINATES SO THAT <XY> = 0
+//
+//-->  SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
+//-->  &                                     > ==> NEW : (XXAV-YYAV) > 0
+//-->  SIGN(S) = SIGN(XYAV)                  >
+
+  Double_t a = fabs( xxav - yyav ) ;
+  Double_t b = 4.0 * xyav * xyav ;
+
+  Double_t asqpb  = a * a + b  ;
+  Double_t rasqpb = sqrt ( asqpb) ;
+
+  Double_t splus  = 1.0 + a / rasqpb ;
+  Double_t sminus = b / (asqpb * splus) ;
+
+  splus  = sqrt (0.5 * splus ) ;
+  sminus = sqrt (0.5 * sminus) ;
+//
+//->  FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
+//
+  Double_t sinrot, cosrot ;
+  if ( xxav <= yyav ) {
+        cosrot = sminus ;
+        sinrot = splus  ;
+  }
+  else {
+         cosrot = splus ;
+         sinrot = sminus ;
+  }
+//
+//->  REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
+//
+  if ( xyav < 0.0 ) sinrot = - sinrot ;
+//
+//-->  WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
+//-->  TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
+//-->  OUTWARD FROM THE ORGIN.  WE ARE FREE TO CHANGE SIGNS OF BOTH
+//-->  COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
+//
+//-->  CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
+//
+  if ( cosrot*xav+sinrot*yav < 0.0 ) {
+         cosrot = -cosrot ;
+         sinrot = -sinrot ;
+  }
+//
+//->  NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
+//
+  Double_t rrav   = xxav + yyav ;
+  Double_t rscale = sqrt(rrav) ;
+
+  xxav   = 0.0 ;
+  yyav   = 0.0 ;
+  xyav   = 0.0 ;
+  Double_t xrrav = 0.0 ;
+  Double_t yrrav = 0.0 ;
+  Double_t rrrrav  = 0.0 ;
+
+  Double_t xixi, yiyi, riri, wiriri, xold, yold ;
+  
+  //for (hit_counter=0; hit_counter<num_of_hits; hit_counter++) 
+  for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
+    { 
+      //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);  
+      AliHLTTPCConfMapPoint* cHit = (AliHLTTPCConfMapPoint*)fTrack->currentHit;
+
+      xold = cHit->GetX() - xav ;
+      yold = cHit->GetY() - yav ;
+      //
+      //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+      //
+      xi = (  cosrot * xold + sinrot * yold ) / rscale ;
+      yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+      
+      xixi   = xi * xi ;
+      yiyi   = yi * yi ;
+      riri   = xixi + yiyi ;
+      wiriri = cHit->GetXYWeight() * riri ;
+      
+      xyav   += cHit->GetXYWeight() * xi * yi ;
+      xxav   += cHit->GetXYWeight() * xixi ;
+      yyav   += cHit->GetXYWeight() * yiyi ;
+      
+      xrrav  += wiriri * xi ;
+      yrrav  += wiriri * yi ;
+      rrrrav += wiriri * riri ;
+    }
+  //
+//   Include vertex if required
+//
+  if (fTrack->ComesFromMainVertex() == true)
+    {
+       xold = fVertex->GetX() - xav ;
+       yold = fVertex->GetY() - yav ;
+       //
+       //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+       //
+       xi = (  cosrot * xold + sinrot * yold ) / rscale ;
+       yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+       
+       xixi   = xi * xi ;
+       yiyi   = yi * yi ;
+       riri   = xixi + yiyi ;
+       wiriri = fVertex->GetXYWeight() * riri ;
+
+       xyav   += fVertex->GetXYWeight() * xi * yi ;
+       xxav   += fVertex->GetXYWeight() * xixi ;
+       yyav   += fVertex->GetXYWeight() * yiyi ;
+
+       xrrav  += wiriri * xi ;
+       yrrav  += wiriri * yi ;
+       rrrrav += wiriri * riri ;
+  }
+  //
+  //    
+  //
+  //-->  DIVIDE BY WSUM TO MAKE AVERAGES
+  //
+  xxav    = xxav   / wsum ;
+  yyav    = yyav   / wsum ;
+  xrrav   = xrrav  / wsum ;
+  yrrav   = yrrav  / wsum ;
+  rrrrav  = rrrrav / wsum ;
+  xyav    = xyav   / wsum ;
+
+  Int_t const ntry = 5 ;
+//
+//-->  USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
+//-->  DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
+//
+  Double_t xrrxrr = xrrav * xrrav ;
+  Double_t yrryrr = yrrav * yrrav ;
+  Double_t rrrrm1 = rrrrav - 1.0  ;
+  Double_t xxyy   = xxav  * yyav  ;        
+
+  Double_t c0  =          rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
+  Double_t c1  =        - rrrrm1      + xrrxrr      + yrryrr   - 4.0*xxyy ;        
+  Double_t c2  =   4.0  + rrrrm1                               - 4.0*xxyy ;           
+  Double_t c4  = - 4.0  ;                
+//
+//-->  COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
+//
+  Double_t c2d =   2.0 * c2 ;
+  Double_t c4d =   4.0 * c4 ;
+//
+//-->  0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
+//
+//   LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
+  Double_t lamda  = 0.0 ;
+  Double_t dlamda = 0.0 ;
+//
+  Double_t chiscl = wsum * rscale * rscale ;
+  Double_t dlamax = 0.001 / chiscl ;   
+   
+  Double_t p, pd ;
+  for ( int itry = 1 ; itry <= ntry ; itry++ ) {
+     p      = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
+     pd     = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
+     dlamda = -p / pd ;
+     lamda  = lamda + dlamda ;
+     if (fabs(dlamda)<   dlamax) break ;
+  }
+
+  Double_t chi2 = (Double_t)(chiscl * lamda) ;
+  fTrack->SetChiSq1(chi2);
+  // Double_t dchisq = chiscl * dlamda ;            
+//
+//-->  NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
+//
+  Double_t h11   = xxav  -     lamda ;
+  Double_t h14   = xrrav ;
+  Double_t h22   = yyav  -     lamda ; 
+  Double_t h24   = yrrav ;
+  Double_t h34   = 1.0   + 2.0*lamda ;
+  if ( h11 == 0.0 || h22 == 0.0 ){
+    LOG(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);
+  
+//
+//    Get other track parameters
+//
+  Double_t x0, y0,phi0,r0,psi,pt ;
+  if ( fTrack->ComesFromMainVertex() == true ) 
+    {
+      //flag = 1 ; // primary track flag
+      x0   = fVertex->GetX() ;
+      y0   = fVertex->GetY() ;
+      phi0 = fVertex->GetPhi() ;
+      r0   = fVertex->GetR() ;
+      fTrack->SetPhi0(phi0);
+      fTrack->SetR0(r0);
+    } 
+  else 
+    {
+      //AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)hits->Last();
+      AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fTrack->lastHit;
+      //flag =  0 ; // primary track flag
+      x0   =  lHit->GetX()  ;
+      y0   =  lHit->GetY()  ;
+      phi0 =  atan2(lHit->GetY(),lHit->GetX());
+      if ( phi0 < 0 ) phi0 += 2*pi;
+      r0   =  sqrt ( lHit->GetX() * lHit->GetX() + lHit->GetY() * lHit->GetY() )  ;
+      fTrack->SetPhi0(phi0);
+      fTrack->SetR0(r0);
+    }
+  //
+  psi  = (Double_t)atan2(bcent-y0,acent-x0) ;
+  psi  = psi + q * 0.5F * pi ;
+  if ( psi < 0 ) psi = psi + 2*pi;
+  
+  pt   = (Double_t)(BFACT * AliHLTTPCTransform::GetBField() * radius ) ;
+  fTrack->SetPsi(psi);
+  fTrack->SetPt(pt);
+
+  //
+//    Get errors from fast fit
+//
+  //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+  return 0 ;
+  
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//    Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t 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() / ( BFACT * AliHLTTPCTransform::GetBField() ) ) ;
+
+  //TObjArray *hits = fTrack->GetHits();
+  //Int_t num_of_hits = fTrack->GetNumberOfPoints();
+
+  if ( fTrack->ComesFromMainVertex() == true ) 
+    {
+      dx = ((AliHLTTPCConfMapPoint*)fTrack->firstHit)->GetX() - fVertex->GetX();
+      dy = ((AliHLTTPCConfMapPoint*)fTrack->firstHit)->GetY() - fVertex->GetY() ;
+    }
+  else 
+    {
+      dx = ((AliHLTTPCConfMapPoint *)fTrack->firstHit)->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->lastHit)->GetX() ;
+      dy = ((AliHLTTPCConfMapPoint *)fTrack->firstHit)->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->lastHit)->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 * 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->currentHit;
+      // if ( currentHit != firstHit ) 
+      if(cHit != fTrack->firstHit)//  hits->First())
+       {
+         dx   = cHit->GetX() - previousHit->GetX() ;
+         dy   = cHit->GetY() - previousHit->GetY() ;
+         dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
+         fTrack->SetPsierr(dpsi);
+         s = previousHit->GetS() - 2.0 * radius * (Double_t)asin ( dpsi ) ;
+         cHit->SetS(s);
+       }
+      else
+       cHit->SetS(total_s);
+      //       cHit->s = total_s ;
+    
+      sum += cHit->GetZWeight() ;
+      ss  += cHit->GetZWeight() * cHit->GetS() ;
+      sz  += cHit->GetZWeight() * cHit->GetZ() ;
+      sss += cHit->GetZWeight() * cHit->GetS() * cHit->GetS() ;
+      ssz += cHit->GetZWeight() * cHit->GetS() * cHit->GetZ() ;
+      previousHit = cHit ;
+    }
+  
+  Double_t chi2,det = sum * sss - ss * ss;
+  if ( fabs(det) < 1e-20)
+    { 
+      chi2 = 99999.F ;
+      fTrack->SetChiSq2(chi2);
+      return 0 ;
+    }
+  
+  //Compute the best fitted parameters A,B
+  Double_t tanl,z0,dtanl,dz0;
+
+  tanl = (Double_t)((sum * ssz - ss * sz ) / det );
+  z0   = (Double_t)((sz * sss - ssz * ss ) / det );
+
+  fTrack->SetTgl(tanl);
+  fTrack->SetZ0(z0);
+  
+  //     calculate chi-square 
+  
+  chi2 = 0.;
+  Double_t r1 ;
+  
+  //for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+  for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
+    {
+      //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+      AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->currentHit;
+      r1   = cHit->GetZ() - tanl * cHit->GetS() - z0 ;
+      chi2 += (Double_t) ( (Double_t)cHit->GetZWeight() * (r1 * r1) );
+    }
+  fTrack->SetChiSq2(chi2);
+  //
+  //     calculate estimated variance
+  //      varsq=chi/(double(n)-2.) 
+  //     calculate covariance matrix 
+  //      siga=sqrt(varsq*sxx/det) 
+  //      sigb=sqrt(varsq*sum/det) 
+  //
+  dtanl = (Double_t) ( sum / det );
+  dz0   = (Double_t) ( sss / det );
+  
+  fTrack->SetTglerr(dtanl);
+  fTrack->SetZ0err(dz0);
+  
+  return 0 ;
+} 
diff --git a/HLT/TPCLib/Ref/AliHLTTPCConfMapFit.h b/HLT/TPCLib/Ref/AliHLTTPCConfMapFit.h
new file mode 100644 (file)
index 0000000..a5d86bf
--- /dev/null
@@ -0,0 +1,31 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapFit
+#define ALIHLTTPC_ConfMapFit
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapFit {
+
+ private:
+  AliHLTTPCConfMapTrack *fTrack; //!
+  AliHLTTPCVertex *fVertex; //!
+  Double_t BFACT;
+  
+  static Double_t pi;
+
+ 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/Ref/AliHLTTPCConfMapPoint.cxx b/HLT/TPCLib/Ref/AliHLTTPCConfMapPoint.cxx
new file mode 100644 (file)
index 0000000..41dfc1d
--- /dev/null
@@ -0,0 +1,242 @@
+// @(#) $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::fDontMap=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.
+  // Does nothing except destruct. 
+}
+
+Bool_t AliHLTTPCConfMapPoint::ReadHits(AliHLTTPCSpacePointData* 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);
+  nextRowHit = 0;
+  nextVolumeHit=0;
+  nextTrackHit=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(const Double_t in_x,const Double_t in_y,const Double_t in_z,
+                                   const Double_t in_x_err,const Double_t in_y_err,const Double_t in_z_err)
+{
+  // Defines a new interaction point. This point is needed to calculate
+  // the conformal coordinates.
+
+  SetXt(in_x);
+  SetYt(in_y);
+  SetZt(in_z);
+  SetXterr(in_x_err);
+  SetYterr(in_y_err);
+  SetZterr(in_z_err);
+
+  return;
+}
+
+void AliHLTTPCConfMapPoint::SetAllCoord(const AliHLTTPCConfMapPoint *preceding_hit)
+{
+  // Sets the interaction point, the shifted coordinates, and the conformal mapping coordinates.
+  // These values are calculated from the interaction point of the given cluster which should be a
+  // already found cluster on the same track.
+
+  if (this == preceding_hit) {
+    SetIntPoint(preceding_hit->GetX(),    preceding_hit->GetY(),    preceding_hit->GetZ(),
+                preceding_hit->GetXerr(), preceding_hit->GetYerr(), preceding_hit->GetZerr());
+  }
+
+  else {
+    SetIntPoint(preceding_hit->GetXt(),    preceding_hit->GetYt(),    preceding_hit->GetZt(),
+                preceding_hit->GetXterr(), preceding_hit->GetYterr(), preceding_hit->GetZterr());
+  }
+
+  SetShiftedCoord();
+  SetConfCoord();
+
+  return;
+}
+
+void 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(fDontMap){
+    fXprime = x;
+    fYprime = y;
+    fWxy = 0;
+    s = 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)*((xerr*xerr)+(yerr*yerr)));
+      s = 0; //track trajectory
+      fWz = (Double_t)(1./(szErrorScale*zerr*zerr));
+    } else {
+    fXprime    = 0.;
+    fYprime    = 0.;
+    fXprimeerr = 0.;
+    fYprimeerr = 0.;
+    fWxy = 0;
+    fWz = 0;
+    s = 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(y,x);
+  //if(fPhi<0) fPhi = fPhi + 2*TMath::Pi();
+  
+  //fEta = 0.5 * TMath::Log((r3dim + fZv)/(r3dim - fZv));
+  fEta = 0.5 * log((r3dim + fZv)/(r3dim - fZv));
+  return;
+}
+/*
+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/Ref/AliHLTTPCConfMapPoint.h b/HLT/TPCLib/Ref/AliHLTTPCConfMapPoint.h
new file mode 100644 (file)
index 0000000..a5663ee
--- /dev/null
@@ -0,0 +1,189 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapPoint
+#define ALIHLTTPC_ConfMapPoint
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapPoint {
+
+ private:
+
+  Int_t fHitNumber;
+  Int_t fTrackNumber;
+  Int_t fNextHitNumber;
+  Bool_t fUsed;
+  Int_t fPadrow;
+  Int_t fSector;
+
+  //global coordinates and their errors
+  Double_t x;
+  Double_t y;
+  Double_t z;
+  Double_t xerr;
+  Double_t yerr;
+  Double_t zerr;
+
+  Double_t fWxy;  // x-y weight on x-y
+  Double_t fWz;   // z weight on z
+  Float_t s;     //track trajectory
+  
+   // Interaction point
+  Double_t   fXt;          // x-value of the interaction point
+  Double_t   fYt;          // y-value of the interaction point
+  Double_t   fZt;          // z-value of the interaction point
+  
+  Double_t   fXterr;       // error of mXt
+  Double_t   fYterr;       // error of mYt
+  Double_t   fZterr;       // error of mZt
+  
+  // conformal mapping coordinates
+  Double_t   fXprime;      // transformed x
+  Double_t   fYprime;      // transformed y  
+  
+  Double_t   fXprimeerr;   // error of mXprime
+  Double_t   fYprimeerr;   // error of mYprime
+  
+  // coordinates with respect to the vertex
+  
+  // cartesian coordinates
+  Double_t   fXv;          // x with respect to vertex
+  Double_t   fYv;          // y with respect to vertex
+  Double_t   fZv;          // z with respect to vertex
+  
+  Double_t   fXverr;       // error of mXv
+  Double_t   fYverr;       // error of mYv
+  Double_t   fZverr;       // error of mZv
+  
+  // spherical coordinates
+  Double_t   fPhi;         // angle phi
+  Double_t   fEta;         // pseudorapidity
+  
+  static Bool_t fDontMap; //flag to switch off mapping  
+
+ public:
+
+  AliHLTTPCConfMapPoint();
+  virtual ~AliHLTTPCConfMapPoint();
+  
+  void Reset();
+  Bool_t ReadHits(AliHLTTPCSpacePointData* hits ); //!
+  
+  AliHLTTPCConfMapPoint *nextVolumeHit; //!
+  AliHLTTPCConfMapPoint *nextRowHit;  //!
+  
+  AliHLTTPCConfMapPoint *nextTrackHit; //! Linked chain of points in a track
+  Short_t phiIndex;
+  Short_t etaIndex;
+  Double_t xyChi2;
+  Double_t szChi2;
+  Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+   // getter
+  Double_t GetX() const {return x;}
+  Double_t GetY() const {return y;}
+  Double_t GetZ() const {return z;}
+  Double_t GetXerr() const {return xerr;}
+  Double_t GetYerr() const {return yerr;}
+  Double_t GetZerr() const {return zerr;}
+  Int_t GetPadRow() const {return fPadrow;}
+  Int_t GetSector() const {return fSector;}
+  
+  Double_t GetXYWeight() const {return fWxy;}
+  Double_t GetZWeight() const {return fWz;}
+  Float_t GetS()        const {return s;}
+
+  //AliHLTTPCConfMapTrack *GetTrack(TClonesArray *tracks) const;
+  
+  Bool_t GetUsage() const {return fUsed;}
+  Double_t GetPhi() const {return fPhi;}
+  Double_t GetEta() const {return fEta;}
+  
+  Double_t GetXprime() const    {return fXprime;}
+  Double_t GetYprime() const    {return fYprime;}
+  Double_t GetXprimeerr() const {return fXprimeerr;}
+  Double_t GetYprimeerr() const {return fYprimeerr;}
+  
+  Double_t GetXt() const           { return fXt;         }
+  Double_t GetYt() const           { return fYt;         }
+  Double_t GetZt() const           { return fZt;         }
+  Double_t GetXterr() const        { return fXterr;      }
+  Double_t GetYterr() const        { return fYterr;      }
+  Double_t GetZterr() const        { return fZterr;      }
+  
+  Double_t GetXv() const           { return fXv;         }
+  Double_t GetYv() const           { return fYv;         }
+  Double_t GetZv() const           { return fZv;         }
+  Double_t GetXverr() const        { return fXverr;      }
+  Double_t GetYverr() const        { return fYverr;      }
+  Double_t GetZverr() const        { return fZverr;      }
+
+  Int_t GetHitNumber() const {return fHitNumber;}
+  Int_t GetNextHitNumber() const {return fNextHitNumber;}
+  Int_t GetTrackNumber() const {return fTrackNumber;}
+  //  Int_t const *GetMCTrackID()     const {return fMCTrackID;}
+  
+  // setter
+  static void SetDontMap(Bool_t b){fDontMap=b;}
+
+  void SetX(Double_t f) {x=f;}
+  void SetY(Double_t f) {y=f;}
+  void SetZ(Double_t f) {z=f;}
+  void SetXerr(Double_t f) {xerr=f;}
+  void SetYerr(Double_t f) {yerr=f;}
+  void SetZerr(Double_t f) {zerr=f;}
+  void SetPadRow(Int_t f) {fPadrow=f;}
+  void SetSector(Int_t f) {fSector=f;}
+  void SetMCTrackID(Int_t f,Int_t g,Int_t h) {fMCTrackID[0] = f; fMCTrackID[1]=g; fMCTrackID[2]=h;}
+
+  void SetXYWeight(Float_t f) {fWxy = f;}
+  void SetZWeight(Float_t f) {fWz = f;}
+  void SetS(Float_t f) {s = f;}
+
+  void SetUsage(Bool_t f) {fUsed=f;}
+    
+  void SetPhi(Double_t f)         {           fPhi = f; }
+  void SetEta(Double_t f)         {           fEta = f; }
+  
+  void SetXprime(Double_t f)      {        fXprime = f; }
+  void SetYprime(Double_t f)      {        fYprime = f; }
+  void SetXprimeerr(Double_t f)   {     fXprimeerr = f; }
+  void SetYprimeerr(Double_t f)   {     fYprimeerr = f; }
+  
+  void SetXt(Double_t f)          {            fXt = f; }
+  void SetYt(Double_t f)          {            fYt = f; }
+  void SetZt(Double_t f)          {            fZt = f; }
+  void SetXterr(Double_t f)       {         fXterr = f; }
+  void SetYterr(Double_t f)       {         fYterr = f; }
+  void SetZterr(Double_t f)       {         fZterr = f; }
+  
+  void SetXv(Double_t f)          {            fXv = f; }
+  void SetYv(Double_t f)          {            fYv = f; }
+  void SetZv(Double_t f)          {            fZv = f; }
+  void SetXverr(Double_t f)       {         fXverr = f; }
+  void SetYverr(Double_t f)       {         fYverr = f; }
+  void SetZverr(Double_t f)       {         fZverr = f; }
+  
+  void SetHitNumber(Int_t f) {fHitNumber=f;}
+  void SetTrackNumber(Int_t f) {fTrackNumber=f;}
+  void SetNextHitNumber(Int_t f) {fNextHitNumber=f;}
+
+  void Setup(AliHLTTPCVertex *vertex);// does the usual setup in the right order
+  void SetAngles();// calculate spherical angles and set values
+  void SetIntPoint(const Double_t in_x = 0.,const Double_t in_y = 0.,
+                  const Double_t in_z = 0.,const Double_t in_x_err = 0., 
+                  const Double_t in_y_err = 0., const Double_t in_z_err = 0.);  
+  //-> set interaction point
+  void SetShiftedCoord();// set shifted coordinates  
+  void SetAllCoord(const 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/Ref/AliHLTTPCConfMapTrack.cxx b/HLT/TPCLib/Ref/AliHLTTPCConfMapTrack.cxx
new file mode 100644 (file)
index 0000000..9b6844e
--- /dev/null
@@ -0,0 +1,337 @@
+// @(#) $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>
+*/
+
+ClassImp(AliHLTTPCConfMapTrack)
+
+
+AliHLTTPCConfMapTrack::AliHLTTPCConfMapTrack()
+{
+  //Constructor
+
+  fChiSq[0] = 0.;
+  fChiSq[1] = 0.;
+}
+
+AliHLTTPCConfMapTrack::~AliHLTTPCConfMapTrack()
+{
+
+}
+
+void AliHLTTPCConfMapTrack::DeleteCandidate()
+{
+  //Deletes this track by resetting all its parameters. Does not delete
+  //the object itself.
+
+  AliHLTTPCConfMapPoint *curHit = (AliHLTTPCConfMapPoint*)firstHit;
+  AliHLTTPCConfMapPoint *nextHit;
+  
+  while(curHit != 0)
+    {
+      nextHit = (AliHLTTPCConfMapPoint*)curHit->nextTrackHit;
+      curHit->nextTrackHit = 0;
+      curHit = nextHit;
+    }
+  
+  UInt_t *hit_numbers = GetHitNumbers();
+  for(Int_t i=0; i<GetNHits(); i++)
+    {
+      //fHitNumbers[i] = 0;
+      hit_numbers[i]=0;
+    }
+    
+  SetRadius(0.);
+  SetCenterX(0.);
+  SetCenterY(0.);
+  
+  ComesFromMainVertex(false);
+
+  SetNHits(0);
+  SetCharge(0);
+  fChiSq[0] = 0.;
+  fChiSq[1] = 0.;
+}
+
+
+void AliHLTTPCConfMapTrack::SetProperties(Bool_t usage)
+{
+  //Set the hits to this track to 'usage'
+  
+  for(StartLoop(); LoopDone(); GetNextHit())
+    {
+      AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)currentHit;
+      p->SetUsage(usage);
+    }
+  return;
+}
+
+void AliHLTTPCConfMapTrack::Reset()
+{
+  //Resets the fit parameters of this track.
+
+  //xy-plane
+  s11Xy   = 0;
+  s12Xy   = 0;
+  s22Xy   = 0;
+  g1Xy    = 0;
+  g2Xy    = 0;
+  fChiSq[0]  = 0.;
+    
+  //sz-plane
+  s11Sz = 0;
+  s12Sz = 0;
+  s22Sz = 0;
+  g1Sz  = 0;
+  g2Sz  = 0;
+  fChiSq[1] = 0; 
+  SetLength(0);
+  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)  
+    firstHit = thisHit;
+  else
+    ((AliHLTTPCConfMapPoint*)lastHit)->nextTrackHit = thisHit;
+  lastHit = thisHit;
+
+  
+  s11Xy = s11Xy + thisHit->GetXYWeight() ;
+  s12Xy = s12Xy + thisHit->GetXYWeight() * thisHit->GetXprime() ;
+  s22Xy = s22Xy + thisHit->GetXYWeight() * pow((thisHit->GetXprime()),2) ;
+  g1Xy  = g1Xy  + thisHit->GetXYWeight() * thisHit->GetYprime() ;
+  g2Xy  = g2Xy  + thisHit->GetXYWeight() * thisHit->GetXprime() * thisHit->GetYprime() ;
+    
+  ddXy  = s11Xy * s22Xy - pow((s12Xy),2) ;
+  if ( ddXy != 0 ) 
+    {
+      a1Xy  = ( g1Xy * s22Xy - g2Xy * s12Xy ) / ddXy ;
+      a2Xy  = ( g2Xy * s11Xy - g1Xy * s12Xy ) / ddXy ;
+    }
+
+  //     Now in the sz plane
+  s11Sz = s11Sz + thisHit->GetZWeight() ;
+  s12Sz = s12Sz + thisHit->GetZWeight() * thisHit->GetS() ;
+  s22Sz = s22Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetS() ;
+  g1Sz  = g1Sz  + thisHit->GetZWeight() * thisHit->GetZ() ;
+  g2Sz  = g2Sz  + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetZ() ;
+  
+        
+  ddSz  = s11Sz * s22Sz -  s12Sz * s12Sz ;
+  if ( ddSz != 0 ) {
+    a1Sz  = ( g1Sz * s22Sz - g2Sz * s12Sz ) / ddSz ;
+    a2Sz  = ( g2Sz * s11Sz - g1Sz * s12Sz ) / ddSz ;
+  }
+}
+
+
+void AliHLTTPCConfMapTrack::Fill(AliHLTTPCVertex *vertex,Double_t max_Dca)
+{
+  //Fill track variables with or without fit.
+  
+  //fRadius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
+  Double_t radius = sqrt(a2Xy*a2Xy+1)/(2*fabs(a1Xy));
+  SetRadius(radius);
+
+  //fPt = (Double_t)(BFACT * AliHLTTPCTransform::GetBField() * fRadius);
+  Double_t pt = (Double_t)(BFACT * AliHLTTPCTransform::GetBField() * GetRadius());
+  SetPt(pt);
+
+  if(GetPt() > max_Dca) //go for fit of helix in real space
+    {
+      AliHLTTPCConfMapFit *fit = new AliHLTTPCConfMapFit(this,vertex);
+      fit->FitHelix();
+      
+      AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)lastHit;
+      AliHLTTPCConfMapPoint *fHit = (AliHLTTPCConfMapPoint*)firstHit;
+      
+      if(AliHLTTPC::IsTracksAtFirstPoint())
+       {
+         //Z0 should not be overwritten here, since it is used as a starting
+         //point for the track swim in UpdateToFirstPoint. fFirstPointX and Y
+         //will be overwritten in UpdateToFirstPoint with the track fit 
+         //crossing point.
+         SetFirstPoint(lHit->GetX(),lHit->GetY(),GetZ0());
+         UpdateToFirstPoint();
+       }
+      else
+       {
+         SetFirstPoint(vertex->GetX(),vertex->GetY(),vertex->GetZ());
+       }
+      
+      SetLastPoint(fHit->GetX(),fHit->GetY(),fHit->GetZ());
+      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;
+    }
+}
+/*
+void AliHLTTPCConfMapTrack::UpdateToFirstPoint()
+{
+  //Update track parameters to the innermost point on the track.
+  //Basically it justs calculates the intersection of the track, and a cylinder
+  //with radius = r(innermost point). Then the parameters are updated to this point.
+  //Should be called after the helixfit (in FillTracks).
+  
+  //AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fPoints->Last();
+  AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)lastHit;
+  Double_t radius = sqrt(lHit->GetX()*lHit->GetX()+lHit->GetY()*lHit->GetY());
+  
+  //Get the track parameters
+  
+  Double_t tPhi0 = GetPsi() + GetCharge() * 0.5 * pi / abs(GetCharge()) ;
+  Double_t x0    = GetR0() * cos(GetPhi0()) ;
+  Double_t y0    = GetR0() * sin(GetPhi0()) ;
+  Double_t rc    = fabs(GetPt()) / ( BFACT * AliHLTTPCTransform::GetBField() )  ;
+  Double_t xc    = x0 - rc * cos(tPhi0) ;
+  Double_t yc    = y0 - rc * sin(tPhi0) ;
+  
+  //Check helix and cylinder intersect
+  
+  Double_t fac1 = xc*xc + yc*yc ;
+  Double_t sfac = sqrt( fac1 ) ;
+    
+  if ( fabs(sfac-rc) > radius || fabs(sfac+rc) < radius ) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapTrack::UpdateToLastPoint","Tracks")<<AliHLTTPCLog::kDec<<
+      "Track does not intersect"<<ENDLOG;
+    return;
+  }
+  
+  //Find intersection
+  
+  Double_t fac2   = ( radius*radius + fac1 - rc*rc) / (2.00 * radius * sfac ) ;
+  Double_t phi    = atan2(yc,xc) + GetCharge()*acos(fac2) ;
+  Double_t td     = atan2(radius*sin(phi) - yc,radius*cos(phi) - xc) ;
+  
+  //Intersection in z
+  
+  if ( td < 0 ) td = td + 2. * pi ;
+  Double_t deltat = fmod((-GetCharge()*td + GetCharge()*tPhi0),2*pi) ;
+  if ( deltat < 0.      ) deltat += 2. * pi ;
+  if ( deltat > 2.*pi ) deltat -= 2. * pi ;
+  Double_t z = GetZ0() + rc * GetTgl() * deltat ;
+  
+  Double_t xExtra = radius * cos(phi) ;
+  Double_t yExtra = radius * sin(phi) ;
+  
+  Double_t tPhi = atan2(yExtra-yc,xExtra-xc);
+  
+  //if ( tPhi < 0 ) tPhi += 2. * M_PI ;
+  
+  Double_t tPsi = tPhi - GetCharge() * 0.5 * pi / abs(GetCharge()) ;
+  if ( tPsi > 2. * pi ) tPsi -= 2. * pi ;
+  if ( tPsi < 0.        ) tPsi += 2. * pi ;
+  
+  //And finally, update the track parameters
+  
+  SetCenterX(xc);
+  SetCenterY(yc);
+  SetR0(radius);
+  SetPhi0(phi);
+  SetZ0(z);
+  SetPsi(tPsi);
+}
+*/
+Int_t 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/Ref/AliHLTTPCConfMapTrack.h b/HLT/TPCLib/Ref/AliHLTTPCConfMapTrack.h
new file mode 100644 (file)
index 0000000..451cf6e
--- /dev/null
@@ -0,0 +1,68 @@
+// @(#) $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 {
+  
+ private:
+
+  
+ public:
+  
+  AliHLTTPCConfMapTrack();
+  virtual ~AliHLTTPCConfMapTrack();
+  void Fill(AliHLTTPCVertex *vertex,Double_t max_Dca);
+  //void UpdateToFirstPoint();
+  void Reset();
+  void UpdateParam(AliHLTTPCConfMapPoint *hit);
+  void DeleteCandidate();
+
+  void StartLoop() {currentHit = firstHit;}  //!
+  void GetNextHit() {currentHit = ((AliHLTTPCConfMapPoint*)currentHit)->nextTrackHit;} //!
+  Int_t LoopDone() {return currentHit != 0;}  //!
+  AliHLTTPCConfMapPoint *currentHit;  //!
+  AliHLTTPCConfMapPoint *lastHit;  //!
+  AliHLTTPCConfMapPoint *firstHit;  //!
+
+
+  // getter
+  Double_t const  *GetChiSq()   const { return fChiSq;}
+  Int_t GetMCLabel();
+
+  // setter   
+  void  SetChiSq1(Double_t f) {fChiSq[0]=f;} 
+  void  SetChiSq2(Double_t f) {fChiSq[1]=f;}
+  void   SetProperties(Bool_t fUsage);
+
+  Double_t fChiSq[2];
+  
+  //fit parameters. Bad naming convention, i know...
+  Double_t    s11Xy  ; 
+  Double_t    s12Xy  ;
+  Double_t    s22Xy  ;
+  Double_t    g1Xy   ;
+  Double_t    g2Xy   ;       
+  Double_t    s11Sz  ;
+  Double_t    s12Sz  ;
+  Double_t    s22Sz  ;
+  Double_t    g1Sz   ;
+  Double_t    g2Sz   ; 
+  
+  Double_t    ddXy, a1Xy, a2Xy ;    /*fit par in xy */
+  Double_t    ddSz, a1Sz, a2Sz ;    /*fit par in sz */
+  
+  ClassDef(AliHLTTPCConfMapTrack,1) //Conformal mapping track class
+};
+    
+#endif
+    
diff --git a/HLT/TPCLib/Ref/AliHLTTPCConfMapper.cxx b/HLT/TPCLib/Ref/AliHLTTPCConfMapper.cxx
new file mode 100644 (file)
index 0000000..b1d290e
--- /dev/null
@@ -0,0 +1,899 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+#include "AliHLTTPCStandardIncludes.h"
+#include <sys/time.h>
+
+#include "AliHLTTPCLogging.h" 
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCConfMapper.h"
+
+/** \class AliHLTTPCConfMapper
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapper
+//
+// Conformal mapping base class
+//
+</pre>
+*/
+
+ClassImp(AliHLTTPCConfMapper)
+
+Double_t AliHLTTPCConfMapper::pi=3.14159265358979323846;
+Double_t AliHLTTPCConfMapper::twopi=2*pi;
+Double_t AliHLTTPCConfMapper::todeg=180./pi;
+
+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 max_num_of_tracks = 2000;
+  //Int_t max_num_of_hits = 120000;
+  Int_t max_num_of_tracks = 3500;
+  Int_t max_num_of_hits = 200000;
+  
+  if(fHit)
+    delete [] fHit;
+  if(fTrack)
+    delete fTrack;
+    
+  fHit = new AliHLTTPCConfMapPoint[max_num_of_hits];
+  fTrack = new AliHLTTPCTrackArray("AliHLTTPCConfMapTrack",max_num_of_tracks);
+}
+
+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 = -1.*10/todeg;//fParam->GetAngle(sector) - 10/todeg;
+  fPhiMax = 10/todeg;//fParam->GetAngle(sector) + 10/todeg;
+
+  nTracks=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 )
+{
+  Int_t nhit=(Int_t)count; 
+  for(Int_t i=0;i<nhit;i++)
+    {
+      fHit[fClustersUnused].Reset();
+      fHit[fClustersUnused].ReadHits(&(hits[i]));
+      fClustersUnused++;    
+    }
+//   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 local_counter=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->phiIndex=(Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1);
+      
+      if(thisHit->phiIndex<1 || thisHit->phiIndex>fNumPhiSegment)
+       {
+         //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
+         fPhiHitsOutOfRange++;
+         continue;
+       }
+      
+      thisHit->etaIndex=(Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1);
+      if(thisHit->etaIndex<1 || thisHit->etaIndex>fNumEtaSegment)
+       {
+         //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
+         fEtaHitsOutOfRange++;
+         continue;
+       }
+      local_counter++;
+      
+      volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne+thisHit->phiIndex*fNumEtaSegmentPlusOne+thisHit->etaIndex;
+      
+      if(fVolume[volumeIndex].first == NULL)
+       fVolume[volumeIndex].first = (void *)thisHit;
+      else
+       ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->nextVolumeHit=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))->nextRowHit = thisHit;
+       fRow[(localrow-fRowMin)].last = (void *)thisHit;
+    }
+  
+  if(fClustersUnused>0 && local_counter==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: "<<(nTracks-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)
+{
+  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 vertex_constraint)
+{
+  //Sets cuts of tracklets. Right now this is only:
+  //maxangle:  Maximum angle when forming segments (if trackletlength > 2)
+  fGoodDist=goodDist;
+  SetMaxAngleTracklet(maxangle, vertex_constraint);
+}
+
+void 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 row_segm,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(row_segm = fRowMax; row_segm >= lastrow; row_segm--)
+    {
+      if(fRow[(row_segm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(row_segm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
+       break;
+
+      for(hit = (AliHLTTPCConfMapPoint*)fRow[(row_segm-fRowMin)].first; hit!=0; hit=hit->nextRowHit)
+       {
+         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 *closest_hit = NULL;
+  AliHLTTPCConfMapTrack *track = NULL;
+  
+  Int_t point;
+  Int_t tracks = nTracks;
+  nTracks++;
+
+  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((closest_hit = GetNextNeighbor(hit)))
+       {//closest hit exist
+         
+         //   Calculate track length in sz plane
+         dx = ((AliHLTTPCConfMapPoint*)closest_hit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
+         dy = ((AliHLTTPCConfMapPoint*)closest_hit)->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);
+
+         //closest_hit->SetS(track->fLength);
+         closest_hit->SetS(track->GetLength());
+
+         //update fit parameters
+         track->UpdateParam(closest_hit);
+         trackhitnumber[track->GetNumberOfPoints()-1] = closest_hit->GetHitNumber();
+       
+         hit = closest_hit;
+       }
+      else
+       {
+         //closest hit does not exist:
+         track->DeleteCandidate();
+         fTrack->RemoveLast();
+         nTracks--;
+         point = fTrackletLength[fVertexConstraint];
+       }
+    }
+  
+  //tracklet is long enough to be extended to a track
+  if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
+    {
+      
+      track->SetProperties(true);
+            
+      if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
+       {//proof if the first points seem to be a beginning of a track
+         track->SetProperties(false);
+         track->DeleteCandidate();
+         fTrack->RemoveLast();
+         nTracks--;
+       }
+      
+      else//good tracklet ->proceed, follow the trackfit
+       {
+         tracks++;
+                                 
+         //define variables to keep the total chi:
+         Double_t xyChi2 = track->fChiSq[0];
+         Double_t szChi2 = track->fChiSq[1];
+         
+         for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
+           {
+             track->fChiSq[0] = fHitChi2Cut[fVertexConstraint];
+             closest_hit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->lastHit,track);
+             
+             if(closest_hit)
+               {
+                 
+                 //keep total chi:
+                 Double_t lxyChi2 = track->fChiSq[0]-track->fChiSq[1];
+                 xyChi2 += lxyChi2;
+                 closest_hit->xyChi2 = lxyChi2;
+                                 
+                 //update track length:
+                 //track->fLength = closest_hit->GetS();
+                 track->SetLength(closest_hit->GetS());
+                 szChi2 += track->fChiSq[1];
+                 closest_hit->szChi2 = track->fChiSq[1];
+                 
+                 track->UpdateParam(closest_hit);
+                 trackhitnumber[track->GetNumberOfPoints()-1] = closest_hit->GetHitNumber();
+                 
+                 //add closest hit to track
+                 closest_hit->SetUsage(true);
+                 closest_hit->SetTrackNumber(tracks-1);
+                 
+               }//closest_hit
+             
+             else
+               {
+                 //closest hit does not exist
+                 point = fNumRowSegment; //continue with next hit in segment
+               }//else
+             
+           }//create tracks
+         
+         //store track chi2:
+         track->fChiSq[0] = xyChi2;
+         track->fChiSq[1] = szChi2;
+         Double_t normalized_chi2 = (track->fChiSq[0]+track->fChiSq[1])/track->GetNumberOfPoints();
+         
+         //remove tracks with not enough points already now
+         if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalized_chi2 > fTrackChi2Cut[fVertexConstraint])
+           {
+             track->SetProperties(false);
+             nTracks--;
+             track->DeleteCandidate();
+             fTrack->RemoveLast();
+             tracks--;
+           }
+         
+         else
+           {
+             fClustersUnused -= track->GetNumberOfPoints();
+             track->ComesFromMainVertex(fVertexConstraint);
+             //mark track as main vertex track or not
+             track->SetSector(2); //only needed for testing purposes.
+             track->SetRowRange(fRowMin,fRowMax);
+
+             if(fVertexConstraint) 
+               fMainVertexTracks++;
+           }
+     
+       }//good tracklet
+      
+    }
+  
+  return;
+}
+
+AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *start_hit,
+                                         AliHLTTPCConfMapTrack *track)
+{
+  //When forming segments: Finds closest hit to input hit
+  //When forming tracks: Find closest hit to track fit.
+  
+  Double_t dist,closest_dist = fMaxDist[fVertexConstraint];
+  
+  AliHLTTPCConfMapPoint *hit = NULL;
+  AliHLTTPCConfMapPoint *closest_hit = NULL;
+    
+  Int_t sub_row_segm;
+  Int_t sub_phi_segm;
+  Int_t sub_eta_segm;
+  Int_t volumeIndex;
+  Int_t test_hit;
+
+  Int_t max_row = start_hit->GetPadRow()-1;
+  Int_t min_row;
+
+  if(track) //finding hit close to trackfit
+    {
+      min_row = start_hit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
+    }
+  else
+    {
+      min_row = start_hit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
+    }
+
+  //make a smart loop
+  Int_t loop_eta[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 loop_phi[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(min_row < fRowMin)
+    min_row = fRowMin;
+  if(max_row < fRowMin)
+    return 0;  //reached the last padrow under consideration
+
+  else
+    {
+      //loop over sub rows
+      for(sub_row_segm=max_row; sub_row_segm>=min_row; sub_row_segm--)
+       {
+         //loop over subsegments, in the order defined above.
+         for(Int_t i=0; i<9; i++)  
+           {
+             sub_phi_segm = start_hit->phiIndex + loop_phi[i];
+             
+             if(sub_phi_segm < 0 || sub_phi_segm >= fNumPhiSegment)
+               continue;
+             /*
+               if(sub_phi_segm<0)
+               sub_phi_segm += fNumPhiSegment;
+               
+               else if(sub_phi_segm >=fNumPhiSegment)
+               sub_phi_segm -= fNumPhiSegment;
+             */
+             //loop over sub eta segments
+             
+             sub_eta_segm = start_hit->etaIndex + loop_eta[i];
+             
+             if(sub_eta_segm < 0 || sub_eta_segm >=fNumEtaSegment)
+               continue;//segment exceeds bounds->skip it
+             
+             //loop over hits in this sub segment:
+             volumeIndex= (sub_row_segm-fRowMin)*fNumPhiEtaSegmentPlusOne +
+               sub_phi_segm*fNumEtaSegmentPlusOne + sub_eta_segm;
+             
+             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->nextVolumeHit)
+               {
+                 
+                 if(!hit->GetUsage())
+                   {//hit was not used before
+                     
+                     //set conformal mapping if looking for nonvertex tracks:
+                     if(!fVertexConstraint)
+                       {
+                         hit->SetAllCoord(start_hit);
+                       }
+                    
+                     if(track)//track search - look for nearest neighbor to extrapolated track
+                       {
+                         if(!VerifyRange(start_hit,hit))
+                           continue;
+                                                 
+                         test_hit = EvaluateHit(start_hit,hit,track);
+                         
+                         if(test_hit == 0)//chi2 not good enough, keep looking
+                           continue;
+                         else if(test_hit==2)//chi2 good enough, return it
+                           return hit;
+                         else
+                           closest_hit = hit;//chi2 acceptable, but keep looking
+                         
+                       }//track search
+                     
+                     else //tracklet search, look for nearest neighbor
+                       {
+                         
+                         if((dist=CalcDistance(start_hit,hit)) < closest_dist)
+                           {
+                             if(!VerifyRange(start_hit,hit))
+                               continue;
+                             closest_dist = dist;
+                             closest_hit = hit;
+                        
+                             //if this hit is good enough, return it:
+                             if(closest_dist < fGoodDist)
+                               return closest_hit;
+                           }
+                         else
+                           continue;//sub hit was farther away than a hit before
+                         
+                       }//tracklet search
+                     
+                   }//hit not used before
+                 
+                 else continue; //sub hit was used before
+                 
+               }//loop over hits in sub segment
+                     
+           }//loop over sub segments
+                 
+       }//loop over subrows
+      
+    }//else
+
+  //closest hit found:
+  if(closest_hit)// && closest_dist < mMaxDist)
+    return closest_hit;
+  else
+    return 0;
+}
+
+Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *start_hit,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->a2Xy*hit->GetXprime()-hit->GetYprime()+track->a1Xy);
+  dxy = temp*temp/(track->a2Xy*track->a2Xy + 1.);
+  
+  //Calculate chi2
+  lchi2 = (dxy*hit->GetXYWeight());
+  
+  if(lchi2 > track->fChiSq[0])//chi2 was worse than before.
+    return 0;
+    
+  //calculate s and the distance hit-line
+  dx = start_hit->GetX()-hit->GetX();
+  dy = start_hit->GetY()-hit->GetY();
+  //slocal = track->fLength+sqrt(dx*dx+dy*dy);
+  slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
+  
+  temp = (track->a2Sz*slocal-hit->GetZ()+track->a1Sz);
+  dsz = temp*temp/(track->a2Sz*track->a2Sz+1);
+  
+  //calculate chi2
+  lszChi2 = dsz*hit->GetZWeight();
+  lchi2 += lszChi2;
+  
+    
+  //check whether chi2 is better than previous one:
+  if(lchi2 < track->fChiSq[0])
+    {
+      track->fChiSq[0] = lchi2;
+      track->fChiSq[1] = lszChi2;
+    
+      hit->SetS(slocal);
+  
+      //if chi2 good enough, stop here:
+      if(lchi2 < fGoodHitChi2[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 phi_diff = fabs( hit1->GetPhi() - hit2->GetPhi() );
+  if (phi_diff > pi) phi_diff = twopi - phi_diff;
+  
+  return todeg*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) * (phi_diff + 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 > pi) dphi = fabs(twopi - dphi);
+  if(dphi > fMaxPhi) return false;
+  
+  deta = fabs(hit1->GetEta() - hit2->GetEta());
+  if(deta > fMaxEta) return false;
+
+  return true;
+
+}
+
+Double_t 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->currentHit;
+      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 num_of_tracks = nTracks;
+  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","nTracks")<<AliHLTTPCLog::kDec<<
+    "Number of found tracks: "<<nTracks<<ENDLOG;
+  
+  if(nTracks == 0)
+    {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::FillTracks","nTracks")<<AliHLTTPCLog::kDec<<
+       "No tracks found!!"<<ENDLOG;
+      return 0;
+    }
+  
+  //  fTrack->Sort();
+  for(int i=0; i<num_of_tracks; 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.);
+ //return (Double_t)(clock()) / CLOCKS_PER_SEC;
+}
diff --git a/HLT/TPCLib/Ref/AliHLTTPCConfMapper.h b/HLT/TPCLib/Ref/AliHLTTPCConfMapper.h
new file mode 100644 (file)
index 0000000..160f9ac
--- /dev/null
@@ -0,0 +1,148 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapper
+#define ALIHLTTPC_ConfMapper
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCSpacePointData.h"
+
+class AliHLTTPCConfMapPoint;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+class AliHLTTPCTrackArray;
+
+struct AliHLTTPCConfMapContainer 
+{
+  void *first;
+  void *last;
+};
+
+//
+//Conformal mapping base class
+
+class AliHLTTPCConfMapper {
+
+ private:
+
+  Bool_t fBench; //run-time measurements
+
+  Int_t nTracks; //number of tracks build.
+
+  //  AliTPCParam *fParam;   
+  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;
+  Int_t  fNumPhiSegmentPlusOne;
+  Int_t  fNumEtaSegmentPlusOne;
+  Int_t  fNumPhiEtaSegmentPlusOne;
+  Int_t  fBounds;         
+  Int_t  fPhiHitsOutOfRange;
+  Int_t  fEtaHitsOutOfRange;
+
+  //tracking range:
+  Float_t fPhiMin; //MinPhi angle to consider
+  Float_t fPhiMax; //MaxPhi angle to consider
+  Float_t fEtaMin; //MinEta to consider
+  Float_t fEtaMax; //MaxEta to consider
+  Int_t fRowMin;   //Minimum row to consider
+  Int_t fRowMax;   //Maximum row to consider
+
+  Bool_t fVertexConstraint;       //vertex constraint (true or false)
+  Int_t fTrackletLength[2];       //minimal length of tracks 
+  Int_t fRowScopeTracklet[2];     //number of row segments to look for the next point of a tracklet
+  Int_t fRowScopeTrack[2];        //number of row segments to look for the next point of a track
+  Int_t fMinPoints[2];            //minimum number of points on one track
+  
+  // Cuts
+  Double_t fMaxAngleTracklet[2];  //limit of angle between to pieces of a tracklet
+  Int_t fMaxDist[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;
+  Double_t fMaxEta;
+
+  // Tracking informtion
+  Int_t fMainVertexTracks; //number of tracks coming from the main vertex
+  Int_t fClustersUnused;   //number of unused clusters
+
+  static Double_t todeg;
+  static Double_t pi;
+  static Double_t twopi;
+
+  //setter:
+  void SetMinPoints(Int_t f,Bool_t vertex_constraint) {fMinPoints[(Int_t)vertex_constraint] = f; }  
+  void SetVertexConstraint(Bool_t f) {fVertexConstraint =f;}
+  
+  void 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 vertex_constraint)         { fRowScopeTrack[(Int_t)vertex_constraint] = f; }     // sets one row scope for tracks
+  void SetRowScopeTracklet(Int_t f, Bool_t vertex_constraint)      { fRowScopeTracklet[(Int_t)vertex_constraint] = f; }  // sets one row scope for tracklets
+  void SetMaxAngleTracklet(Double_t f, Bool_t vertex_constraint)   { fMaxAngleTracklet[(Int_t)vertex_constraint] = f; }  // sets one angle cut
+
+  void SetPointers();
+  Double_t CpuTime();
+  void SetParamDone(Bool_t vertex_constraint) {fParamSet[(Int_t)vertex_constraint] = kTRUE;}
+  
+  
+ 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() {return nTracks;}
+  AliHLTTPCTrackArray *GetTracks() {return fTrack;}
+  Double_t GetMaxDca()  const {return fMaxDca;}
+  AliHLTTPCVertex* GetVertex() const {return fVertex;}
+
+  //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 vertex_constraint);   //Set cut of tracklet for the given vertex_constraint
+  void SetNSegments(Int_t f,Int_t g) {fNumPhiSegment=f,fNumEtaSegment=g;} //Set number of subvolumes (#segments in (phi,eta)
+  void SetMaxDca(Double_t f) {fMaxDca = f;}
+
+  ClassDef(AliHLTTPCConfMapper,1) //Base class for conformal mapping tracking
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLDataFileHandler.cxx b/HLT/TPCLib/Ref/AliHLTTPCDDLDataFileHandler.cxx
new file mode 100644 (file)
index 0000000..bd79fbe
--- /dev/null
@@ -0,0 +1,330 @@
+// @(#) $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 "../RAW/AliRawReaderRoot.h"
+#include "../RAW/AliRawReaderDate.h"
+#else
+#include "AliHLTTPCDDLTPCRawStream.h"
+#include "AliHLTTPCDDLRawReaderFile.h"
+#endif
+#include "AliHLTTPCDDLDataFileHandler.h"
+
+#if GCCVERSION == 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()
+{
+  fReader=0;
+  fTPCStream=0;
+}
+
+AliHLTTPCDDLDataFileHandler::~AliHLTTPCDDLDataFileHandler()
+{
+  FreeAll();
+}
+
+void AliHLTTPCDDLDataFileHandler::FreeAll()
+{
+  if(fReader) delete fReader;
+  if(fTPCStream) delete fTPCStream;
+  fReader = 0;
+  fTPCStream = 0;
+}
+
+
+#ifdef use_newio
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name,Int_t event)
+{
+  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(name);
+  }
+  fTPCStream=new AliTPCRawStream(fReader);
+
+  return kTRUE;
+}
+#else
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name, Bool_t add)
+{
+  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)
+{
+  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()
+{
+  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)
+{
+  return kTRUE;
+}
+#endif
+
+AliHLTTPCDigitRowData * AliHLTTPCDDLDataFileHandler::DDLData2Memory(UInt_t &nrow,Int_t event)
+{
+#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[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 ddls_to_search=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[ddls_to_search++]=ddlid-1;  
+      lddlid=ddlid-1;
+    }
+    if((lddlid==-1)||(ddlid!=lddlid)){
+      ddls[ddls_to_search++]=ddlid;
+      lddlid=ddlid;
+    }
+    if((r==90)||(r==139)){ //dont forget the split row on the next ddl
+      ddls[ddls_to_search++]=ddlid+1;  
+      lddlid=ddlid+1;
+    }
+  }
+  //for(Int_t i=0;i<ddls_to_search;i++) cout << ddls[i] <<endl;
+
+  for(Int_t i=0;i<ddls_to_search;i++){
+#ifdef use_newio
+    fReader->Reset();
+    fReader->Select(0,ddls[i],ddls[i]+1);
+#else
+    fTPCStream->SetDDLID(ddls[i]); //ddl to read out
+#endif
+
+    while (fTPCStream->Next()){
+  
+      UShort_t dig=fTPCStream->GetSignal();
+      if(dig <= AliHLTTPCTransform::GetZeroSup()) continue;
+      if(dig >= AliHLTTPCTransform::GetADCSat())
+       dig = AliHLTTPCTransform::GetADCSat();
+
+      Int_t time=fTPCStream->GetTime();
+      Int_t pad=fTPCStream->GetPad();
+      Int_t sector=fTPCStream->GetSector();
+      Int_t row=fTPCStream->GetRow();
+      Int_t slice,srow;
+
+      //test row criteria (patch boundaries)
+      AliHLTTPCTransform::Sector2Slice(slice,srow,sector,row);
+      if((srow<fRowMin)||(srow>fRowMax))continue;
+      if(slice!=fSlice){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Slice")
+         <<AliHLTTPCLog::kDec<<"Found slice "<<slice<<", expected "<<fSlice<<ENDLOG;
+       continue;
+      }
+
+      //cut out the inner cone
+      Float_t xyz[3];
+      AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+      if(AliHLTTPCTransform::Row2X(srow)<230./250.*fabs(xyz[2]))
+       continue; // why 230???
+
+      Int_t lrow=srow-fRowMin;
+      if((lrow<0)||lrow>=nrows){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Row")
+         <<AliHLTTPCLog::kDec<<"Row value out of bounds "<<lrow<<" "<<nrows<<ENDLOG;
+       continue;
+      }
+      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;
+      }
+      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
+      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;
+
+  return data;
+}
+
+
+Bool_t AliHLTTPCDDLDataFileHandler::DDLData2CompBinary(Int_t event)
+{
+  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/Ref/AliHLTTPCDDLDataFileHandler.h b/HLT/TPCLib/Ref/AliHLTTPCDDLDataFileHandler.h
new file mode 100644 (file)
index 0000000..341e5d6
--- /dev/null
@@ -0,0 +1,51 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLDATAFILEHANDLER_H
+#define ALIHLTTPCDDLDATAFILEHANDLER_H
+
+#ifdef use_newio
+#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{
+  private:
+#ifdef use_newio
+   TString          fFilename;
+   Int_t            fEvent;
+   AliRawReader    *fReader;
+   AliTPCRawStream *fTPCStream;
+#else
+   AliHLTTPCDDLRawReaderFile *fReader;
+   AliHLTTPCDDLTPCRawStream *fTPCStream;
+#endif
+
+  public:
+
+   AliHLTTPCDDLDataFileHandler();
+   virtual ~AliHLTTPCDDLDataFileHandler();
+
+#ifdef use_newio
+   Bool_t SetReaderInput(Char_t *name,Int_t event=0);
+   Bool_t IsDigit(Int_t i=0);
+   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);
+
+   ClassDef(AliHLTTPCDDLDataFileHandler,1)   //DDL Data Filehandler class
+};
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.cxx b/HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.cxx
new file mode 100644 (file)
index 0000000..35fc1f4
--- /dev/null
@@ -0,0 +1,149 @@
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+
+#include "AliHLTTPCDDLRawReader.h"
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** \class AliHLTTPCDDLRawReader
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDDLRawReader (taken from the offline AliROOT code,
+// original authors: D.Favretto and A.K.Mohanty)
+//
+// This is the base class for reading ddl raw data 
+// and providing information about digits
+</pre>
+*/
+
+ClassImp(AliHLTTPCDDLRawReader)
+
+AliHLTTPCDDLRawReader::AliHLTTPCDDLRawReader()
+{
+  fMiniHeader = NULL;
+  fCount = 0;
+  fSelectDetectorID = -1;
+  fSelectMinDDLID = -1;
+  fSelectMaxDDLID = -1;
+}
+
+AliHLTTPCDDLRawReader::~AliHLTTPCDDLRawReader()
+{
+}
+
+void AliHLTTPCDDLRawReader::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
+{
+  // read only data of the detector with the given ID and in the given
+  // range of DDLs (minDDLID <= DDLID < maxDDLID).
+  // no selection is applied if a value < 0 is used.
+
+  fSelectDetectorID = detectorID;
+  fSelectMinDDLID = minDDLID;
+  fSelectMaxDDLID = maxDDLID;
+}
+
+Bool_t AliHLTTPCDDLRawReader::IsSelected()
+{
+  // apply the selection (if any)
+
+  if (fSelectDetectorID >= 0) {
+    if (fMiniHeader->fDetectorID != fSelectDetectorID) return kFALSE;
+    if ((fSelectMinDDLID >= 0) && (fMiniHeader->fDDLID < fSelectMinDDLID))
+      return kFALSE;
+    if ((fSelectMaxDDLID >= 0) && (fMiniHeader->fDDLID >= fSelectMaxDDLID))
+      return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReader::CheckMiniHeader()
+{
+  // check the magic number of the mini header
+
+  if ((fMiniHeader->fMagicWord[2] != 0x12) ||
+      (fMiniHeader->fMagicWord[1] != 0x34) ||
+      (fMiniHeader->fMagicWord[0] != 0x56)) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::CheckMiniHeader","MH")
+      <<"DDL mini header has wrong magic word!"<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReader::ReadNextInt(UInt_t& data)
+{
+  // reads the next 4 bytes at the current position
+  // returns kFALSE if the data could not be read
+
+  while (fCount == 0) {
+    if (!ReadMiniHeader()) return kFALSE;
+  }
+  if (fCount < (Int_t) sizeof(data)) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::ReadNextInt","Data")
+      <<AliHLTTPCLog::kDec<<"Too few data left ("<<fCount<<") to read UInt_t!"<<ENDLOG;
+    return kFALSE;
+  }
+  if (!ReadNext((UChar_t*) &data, sizeof(data))) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::ReadNextInt","Data")
+      <<"Could not read data."<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReader::ReadNextShort(UShort_t& data)
+{
+  // reads the next 2 bytes at the current position
+  // returns kFALSE if the data could not be read
+
+  while (fCount == 0) {
+    if (!ReadMiniHeader()) return kFALSE;
+  }
+  if (fCount < (Int_t) sizeof(data)) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::ReadNextShort","Data")
+      <<AliHLTTPCLog::kDec<<"Too few data left ("<<fCount<<") to read UShort_t!"<<ENDLOG;
+    return kFALSE;
+  }
+  if (!ReadNext((UChar_t*) &data, sizeof(data))) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::ReadNextShort","Data")
+      <<"Could not read data."<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReader::ReadNextChar(UChar_t& data)
+{
+  // reads the next 1 byte at the current stream position
+  // returns kFALSE if the data could not be read
+
+  while (fCount == 0) {
+    if (!ReadMiniHeader()) return kFALSE;
+  }
+  if (!ReadNext((UChar_t*) &data, sizeof(data))) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReader::ReadNextChar","Data")
+      <<"Could not read data."<<ENDLOG;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.h b/HLT/TPCLib/Ref/AliHLTTPCDDLRawReader.h
new file mode 100644 (file)
index 0000000..1054140
--- /dev/null
@@ -0,0 +1,56 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLRAWREADER_H
+#define ALIHLTTPCDDLRAWREADER_H
+
+// see description in upcoming ALICE note
+// by D.Favretto and A.K.Mohanty
+struct AliHLTTPCDDLMiniHeader 
+{
+  UInt_t    fSize;
+  UChar_t   fDetectorID;
+  UChar_t   fMagicWord[3];
+  UChar_t   fVersion;
+  UChar_t   fCompressionFlag;
+  UShort_t  fDDLID;
+};
+
+class AliHLTTPCDDLRawReader 
+{
+  public :
+    AliHLTTPCDDLRawReader();
+    virtual ~AliHLTTPCDDLRawReader();
+
+    void Select(Int_t detectorID, Int_t minDDLID = -1, Int_t maxDDLID = -1);
+
+    inline Int_t     GetDataSize()   const {return fMiniHeader->fSize;};
+    inline Int_t     GetDetectorID() const {return fMiniHeader->fDetectorID;};
+    inline Int_t     GetDDLID()      const {return fMiniHeader->fDDLID;};
+    inline Int_t     GetVersion()    const {return fMiniHeader->fVersion;};
+    inline Bool_t    IsCompressed()  const {return fMiniHeader->fCompressionFlag != 0;};
+
+    virtual Bool_t   ReadMiniHeader() = 0;
+    virtual Bool_t   ReadNextData(UChar_t*& data) = 0;
+    virtual Bool_t   ReadNextInt(UInt_t& data);
+    virtual Bool_t   ReadNextShort(UShort_t& data);
+    virtual Bool_t   ReadNextChar(UChar_t& data);
+
+    virtual Bool_t   Reset() = 0;
+
+  protected :
+    Bool_t           IsSelected();
+
+    Bool_t           CheckMiniHeader();
+    virtual Bool_t   ReadNext(UChar_t* data, Int_t size) = 0;
+
+    AliHLTTPCDDLMiniHeader*  fMiniHeader;  // current mini header
+    Int_t                fCount;       // counter of bytes to be read for current DDL
+
+    Int_t            fSelectDetectorID;  // id of selected detector (<0 = no selection)
+    Int_t            fSelectMinDDLID;    // minimal index of selected DDLs (<0 = no selection)
+    Int_t            fSelectMaxDDLID;    // maximal index of selected DDLs (<0 = no selection)
+
+    ClassDef(AliHLTTPCDDLRawReader,1) //AliHLTTPCDDLRawReader
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.cxx b/HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.cxx
new file mode 100644 (file)
index 0000000..ed168c2
--- /dev/null
@@ -0,0 +1,182 @@
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group
+
+#include <iostream>
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+
+#include "AliHLTTPCDDLRawReaderFile.h"
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** \class AliHLTTPCDDLRawReaderFile
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDDLRawReaderFile (taken from the offline AliROOT code,
+// original authors: D.Favretto and A.K.Mohanty)
+//
+// This is the base class for reading ddl raw data 
+// and providing information about digits
+</pre>
+*/
+
+
+ClassImp(AliHLTTPCDDLRawReaderFile)
+
+
+AliHLTTPCDDLRawReaderFile::AliHLTTPCDDLRawReaderFile(const Char_t* name, Bool_t addnum)
+{
+  // create an object to read digits from the given input file(s)
+  // if addNumber is true, a number starting at 1 is appended to the file name
+
+  fFileName = new Char_t[1024];
+  strcpy(fFileName,name);
+  if (!addnum) {
+    fFileNumber = -1;
+    fStream = new fstream(fFileName, ios::binary|ios::in);
+  } else {
+    fFileNumber = 0;
+    fStream = NULL;
+    OpenNextFile();
+  }
+  fMiniHeader = new AliHLTTPCDDLMiniHeader;
+  fBuffer = NULL;
+  fBufferSize = 0;
+}
+
+AliHLTTPCDDLRawReaderFile::~AliHLTTPCDDLRawReaderFile()
+{
+  // close the input file
+  if(fFileName) delete fFileName;
+
+  if (fStream) {
+    if (fStream->is_open()) fStream->close();
+    delete fStream;
+  }
+  delete fMiniHeader;
+  if (fBuffer) delete[] fBuffer;
+}
+
+Bool_t AliHLTTPCDDLRawReaderFile::OpenNextFile()
+{
+  if (fStream) {
+    if (fStream->is_open()) fStream->close();
+    delete fStream;
+    fStream = NULL;
+  }
+  if (fFileNumber < 0) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReaderFile::OpenNextFile","File")
+      <<"Could not open file, file number is negative."<<ENDLOG;
+    return kFALSE;
+  }
+
+  fFileNumber++;
+  Char_t fileName[1024];
+  sprintf(fileName, "%s%d", fFileName, fFileNumber);
+
+  fStream = new fstream(fileName, ios::binary|ios::in);
+  return (fStream->is_open());
+}
+
+Bool_t AliHLTTPCDDLRawReaderFile::ReadMiniHeader()
+{
+  // read a mini header at the current stream position
+  // returns kFALSE if the mini header could not be read
+
+  if (!fStream) return kFALSE;
+  do {
+    if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
+    while (!fStream->read((Char_t*) fMiniHeader, sizeof(AliHLTTPCDDLMiniHeader))) {
+      if (!OpenNextFile()) return kFALSE;
+    }
+    //cout << fMiniHeader->fSize << " " << fMiniHeader->fDetectorID << " " << fMiniHeader->fVersion << " " << fMiniHeader->fCompressionFlag << " " << fMiniHeader->fDDLID << endl;
+    //cout << "loop here " << (Int_t)fMiniHeader->fDDLID<< endl;
+    CheckMiniHeader();
+    fCount = fMiniHeader->fSize;
+  } while (!IsSelected());
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReaderFile::ReadNextData(UChar_t*& data)
+{
+  // reads the next payload at the current stream position
+  // returns kFALSE if the data could not be read
+
+  while (fCount == 0) {
+    if (!ReadMiniHeader()) return kFALSE;
+  }
+  if (fBufferSize < fCount) {
+    if (fBuffer) delete[] fBuffer;
+    fBufferSize = Int_t(fCount*1.2);
+    fBuffer = new UChar_t[fBufferSize];
+  }
+  if (!fStream->read((Char_t*) fBuffer, fCount)) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReaderFile::ReadNextData","Data")
+      <<"Could not read next data!"<<ENDLOG;
+    return kFALSE;
+  }
+  fCount = 0;
+
+  data = fBuffer;
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReaderFile::ReadNext(UChar_t* data, Int_t size)
+{
+  // reads the next block of data at the current stream position
+  // returns kFALSE if the data could not be read
+
+  if (!fStream->read((Char_t*) data, size)) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReaderFile::ReadNext","Data")
+      <<"Could not read next data!"<<ENDLOG;
+    return kFALSE;
+  }
+  fCount -= size;
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLRawReaderFile::Reset()
+{
+  // reset the current stream position to the beginning of the file
+
+  if ((fFileNumber > 0) && fStream) {
+    if (fStream->is_open()) fStream->close();
+    delete fStream;
+    fStream = NULL;
+    fFileNumber = 0;
+  }
+
+  if (!fStream) {
+    if (fFileNumber < 0) {
+      fStream = new fstream(fFileName, ios::binary|ios::in);
+    } else {
+      if (!OpenNextFile()){
+       LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLRawReaderFile::Reset","Data")
+         <<"Could not reset data stream!"<<ENDLOG;
+       return kFALSE;
+      }
+    }
+  }
+
+  if (!fStream || !fStream->rdbuf()->is_open()) return kFALSE;
+  fStream->seekg(0);
+  fCount = 0;
+  return kTRUE;
+}
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.h b/HLT/TPCLib/Ref/AliHLTTPCDDLRawReaderFile.h
new file mode 100644 (file)
index 0000000..2718a3d
--- /dev/null
@@ -0,0 +1,33 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLRAWREADERFILE_H
+#define ALIHLTTPCDDLRAWREADERFILE_H
+
+#include "AliHLTTPCDDLRawReader.h"
+
+class AliHLTTPCDDLRawReaderFile: public AliHLTTPCDDLRawReader 
+{
+  public :
+    AliHLTTPCDDLRawReaderFile(const Char_t* name, Bool_t addnum = kTRUE);
+    virtual ~AliHLTTPCDDLRawReaderFile();
+
+    virtual Bool_t   ReadMiniHeader();
+    virtual Bool_t   ReadNextData(UChar_t*& data);
+
+    virtual Bool_t   Reset();
+
+  protected :
+    Bool_t           OpenNextFile();
+
+    virtual Bool_t   ReadNext(UChar_t* data, Int_t size);
+
+    Char_t*          fFileName;    //! name of input files
+    Int_t            fFileNumber;  //  number of current input file
+    fstream*         fStream;      //! stream of raw digits
+    UChar_t*         fBuffer;      //!  buffer for payload
+    Int_t            fBufferSize;  //  size of fBuffer in bytes
+
+    ClassDef(AliHLTTPCDDLRawReaderFile, 1) //AliHLTTPCDDLRawReaderFile
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.cxx b/HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.cxx
new file mode 100644 (file)
index 0000000..bd6a130
--- /dev/null
@@ -0,0 +1,192 @@
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCDDLRawReader.h"
+
+#include "AliHLTTPCDDLTPCRawStream.h"
+//#include "AliTPCHuffman.h"
+
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** \class AliHLTTPCDDLTPCRawReaderStream
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDDLTPCRawReaderStream (taken from the offline AliROOT code,
+// original authors: D.Favretto and A.K.Mohanty)
+//
+// This is a base class for reading TPC raw data 
+// and providing information about digits
+</pre>
+*/
+
+ClassImp(AliHLTTPCDDLTPCRawStream)
+
+AliHLTTPCDDLTPCRawStream::AliHLTTPCDDLTPCRawStream(AliHLTTPCDDLRawReader* rawReader)
+{
+  // create an object to read TPC raw digits
+
+  fRawReader = rawReader;
+  fRawReader->Select(0);
+  fData = new UShort_t[fkDataMax];
+  fDataSize = fPosition = 0;
+  fCount = fBunchLength = 0;
+
+  fSector = fPrevSector = fRow = -1;
+  fPrevRow = fPad = fPrevPad = -1;
+  fTime = fSignal = -1;
+}
+
+AliHLTTPCDDLTPCRawStream::~AliHLTTPCDDLTPCRawStream()
+{
+  // clean up
+  delete[] fData;
+}
+
+Bool_t AliHLTTPCDDLTPCRawStream::SetDDLID(Int_t d)
+{
+  if((d<0)||(d>216)){
+    LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLTPCRawStream::SetDDLID","DDL")
+      <<AliHLTTPCLog::kDec<<"DDL number out of range "<<d<<ENDLOG;
+    return kFALSE;
+  }
+
+  //partial clean
+  fDataSize = fPosition = 0;
+  fCount = fBunchLength = 0;
+
+  fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1;
+
+  fRawReader->Reset();
+  fRawReader->Select(0,d,d+1);
+       
+  return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLTPCRawStream::Next()
+{
+  // read the next raw digit
+  // returns kFALSE if there is no digit left
+
+  fPrevSector = fSector;
+  fPrevRow = fRow;
+  fPrevPad = fPad;
+
+  while (fCount == 0) {  // next trailer
+    if (fPosition >= fDataSize) {  // next payload
+      UChar_t* data;
+      do {
+       if (!fRawReader->ReadNextData(data)) return kFALSE;
+      } while (fRawReader->GetDataSize() == 0);
+
+      if (fRawReader->IsCompressed()) {  // compressed data
+       LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLTPCRawStream::Next","Compression")
+      <<"Compression is not implemented (yet)!"<<ENDLOG;
+       return kFALSE;
+      } else {                           // uncompressed data
+       fDataSize = 0;
+       Int_t pos = (fRawReader->GetDataSize() * 8) / 10;
+       while (Get10BitWord(data, pos-1) == 0x2AA) pos--;
+       while (pos > 0) {
+         for (Int_t i = 0; i < 4; i++) {  // copy trailer
+           fData[fDataSize++] = Get10BitWord(data, pos-4+i);
+         }
+         pos -= 4;
+         Int_t count = fData[fDataSize-4];
+         pos -= (4 - (count % 4)) % 4;  // skip fill words
+
+         while (count > 0) {
+           UShort_t bunchLength = Get10BitWord(data, pos-1);
+           fData[fDataSize++] = bunchLength;
+           fData[fDataSize++] = Get10BitWord(data, pos-2);  // time bin
+
+           // copy signal amplitudes in increasing order on time
+           for (Int_t i = 0; i < bunchLength-2; i++) {
+             fData[fDataSize++] = Get10BitWord(data, pos - bunchLength + i);
+           }
+           pos -= bunchLength;
+           count -= bunchLength;
+         }
+       }
+      }
+
+      fPosition = 0;
+    }
+    if (fPosition + 4 >= fDataSize) {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLTPCRawStream::Next","Data")
+      <<"Could not read trailer"<<ENDLOG;
+      return kFALSE;
+    }
+    fCount = fData[fPosition++];
+    fPad = fData[fPosition++];
+    fRow = fData[fPosition++];
+    fSector = fData[fPosition++];
+    fBunchLength = 0;
+  }
+
+  if (fBunchLength == 0) {
+    if (fPosition >= fDataSize) {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLTPCRawStream::Next","Data")
+      <<"Could not read bunch length"<<ENDLOG;
+      return kFALSE;
+    }
+    fBunchLength = fData[fPosition++] - 2;
+    fCount--;
+
+    if (fPosition >= fDataSize) {
+      LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLTPCRawStream::Next","Data")
+      <<"Could not read time bin"<<ENDLOG;
+      return kFALSE;
+    }
+    fTime = fData[fPosition++] - fBunchLength;
+    fCount--;
+  }
+
+  fTime++;
+  if (fPosition >= fDataSize) {
+    LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLTPCRawStream::Next","Data")
+      <<"Could not read sample amplitude"<<ENDLOG;
+    return kFALSE;
+  }
+
+  fSignal = fData[fPosition++] + fkOffset;
+  fCount--;
+  fBunchLength--;
+
+  return kTRUE;
+}
+
+UShort_t AliHLTTPCDDLTPCRawStream::Get10BitWord(UChar_t* buffer, Int_t position)
+{
+  // return a word in a 10 bit array as an UShort_t
+  Int_t iBit = position * 10;
+  Int_t iByte = iBit / 8;
+  Int_t shift = iBit % 8;
+
+  // recalculate the byte numbers and the shift because
+  // the raw data is written as integers where the high bits are filled first
+  // -> little endian is assumed here !
+  Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
+  iByte++;
+  Int_t iByteLow  = 4 * (iByte / 4) + 3 - (iByte % 4);
+  shift = 6 - shift;
+  return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF;
+}
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.h b/HLT/TPCLib/Ref/AliHLTTPCDDLTPCRawStream.h
new file mode 100644 (file)
index 0000000..8f2602b
--- /dev/null
@@ -0,0 +1,55 @@
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLTPCRAWSTREAM_H
+#define ALIHLTTPCDDLTPCRAWSTREAM_H
+
+class AliHLTTPCDDLRawReader;
+
+class AliHLTTPCDDLTPCRawStream 
+{
+  public :
+    AliHLTTPCDDLTPCRawStream(AliHLTTPCDDLRawReader* rawReader);
+    virtual ~AliHLTTPCDDLTPCRawStream();
+
+    virtual Bool_t   Next();
+    Bool_t SetDDLID(Int_t d); //choose ddlid to readout
+
+    inline Int_t     GetSector() const {return fSector;};
+    inline Int_t     GetPrevSector() const {return fPrevSector;};
+    inline Bool_t    IsNewSector() const {return fSector != fPrevSector;};
+    inline Int_t     GetRow() const {return fRow;};
+    inline Int_t     GetPrevRow() const {return fPrevRow;};
+    inline Bool_t    IsNewRow() const {return (fRow != fPrevRow) || IsNewSector();};
+    inline Int_t     GetPad() const {return fPad;};
+    inline Int_t     GetPrevPad() const {return fPrevPad;};
+    inline Bool_t    IsNewPad() const {return (fPad != fPrevPad) || IsNewRow();};
+    inline Int_t     GetTime() const {return fTime;};
+    inline Int_t     GetSignal() const {return fSignal;};
+
+  protected :
+    UShort_t         Get10BitWord(UChar_t* buffer, Int_t position);
+
+    static const Int_t fkOffset  = 1;         // offset of signal
+    static const Int_t fkDataMax = 10000000;  // size of array for uncompressed raw data
+
+    AliHLTTPCDDLRawReader* fRawReader;  // object for reading the raw data
+
+    UShort_t*        fData;         //[fkDataMax] uncompressed raw data
+    Int_t            fDataSize;     // actual size of the uncompressed raw data
+    Int_t            fPosition;     // current position in fData
+    Int_t            fCount;        // counter of words to be read for current trailer
+    Int_t            fBunchLength;  // remaining number of signal bins in the current bunch
+
+    Int_t            fSector;       // index of current sector
+    Int_t            fPrevSector;   // index of previous sector
+    Int_t            fRow;          // index of current row
+    Int_t            fPrevRow;      // index of previous row
+    Int_t            fPad;          // index of current pad
+    Int_t            fPrevPad;      // index of previous pad
+    Int_t            fTime;         // index of current time bin
+    Int_t            fSignal;       // signal in ADC counts
+
+    ClassDef(AliHLTTPCDDLTPCRawStream, 1) // AliHLTTPCDDLTPCRawStream
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDataCompressor.cxx b/HLT/TPCLib/Ref/AliHLTTPCDataCompressor.cxx
new file mode 100644 (file)
index 0000000..c4c8a9e
--- /dev/null
@@ -0,0 +1,1025 @@
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright &copy ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCCompress.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCModelTrack.h"
+#include "AliHLTTPCBenchmark.h"
+#include "AliHLTTPCClusterFitter.h"
+
+#ifdef use_aliroot
+#include "AliHLTTPCFileHandler.h"
+#include <AliTPCcluster.h>
+#include <AliTPCParamSR.h>
+#include <AliTPCDigitsArray.h>
+#include <AliTPCClustersArray.h>
+#include <AliTPCClustersRow.h>
+#include <AliSimDigits.h>
+#include <AliTPC.h>
+#include <AliTPCv2.h>
+#include <AliRun.h>
+#endif
+
+#ifdef use_root
+#include <TFile.h>
+#include <TMath.h>
+#include <TDirectory.h>
+#include <TSystem.h>
+#include <TH2F.h>
+#endif
+
+#include "AliHLTTPCDataCompressor.h"
+
+#if GCCVERSION == 3
+using namespace std;
+#endif
+
+//_____________________________________________________________
+//
+//  AliHLTTPCDataCompression
+//
+// Interface class; binary <-> AliROOT handling of TPC data compression classes.
+//
+
+
+ClassImp(AliHLTTPCDataCompressor)
+
+Int_t AliHLTTPCDataCompressor::fNumTimeBits = 12;
+Int_t AliHLTTPCDataCompressor::fNumPadBits = 12;
+Int_t AliHLTTPCDataCompressor::fNumChargeBits = 14;
+Int_t AliHLTTPCDataCompressor::fNumShapeBits = 14;
+Float_t AliHLTTPCDataCompressor::fXYResidualStep1 = 0.03;
+Float_t AliHLTTPCDataCompressor::fXYResidualStep2 = 0.03;
+Float_t AliHLTTPCDataCompressor::fXYResidualStep3 = 0.03;
+Float_t AliHLTTPCDataCompressor::fZResidualStep1 = 0.05;
+Float_t AliHLTTPCDataCompressor::fZResidualStep2 = 0.05;
+Float_t AliHLTTPCDataCompressor::fZResidualStep3 = 0.05;
+Float_t AliHLTTPCDataCompressor::fXYWidthStep = 0.005;
+Float_t AliHLTTPCDataCompressor::fZWidthStep = 0.005;
+Int_t AliHLTTPCDataCompressor::fClusterCharge = 100;
+
+AliHLTTPCDataCompressor::AliHLTTPCDataCompressor()
+{
+  fBenchmark=0;
+  fInputTracks=0;
+  fKeepRemaining=kTRUE;
+  fEvent=0;
+  fWriteClusterShape=kFALSE;
+  fOutputFile=0;
+  fCompRatioFile=0;
+  fNusedClusters=0;
+  fNunusedClusters=0;
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+}
+
+AliHLTTPCDataCompressor::AliHLTTPCDataCompressor(Char_t *path,Bool_t keep,Bool_t writeshape)
+{
+  strcpy(fPath,path);
+  fBenchmark = new AliHLTTPCBenchmark();
+  fInputTracks=0;
+  fKeepRemaining=keep;
+  fWriteClusterShape = writeshape;
+  fEvent=0;
+  fOutputFile=0;
+  fNusedClusters=0;
+  fNunusedClusters=0;
+  memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+#ifdef use_root
+  Char_t name[1024];
+  sprintf(name,"rm -f %s/comp/*",path);//Clean the directory
+  gSystem->Exec(name);
+#endif
+  OpenOutputFile();
+}
+
+AliHLTTPCDataCompressor::~AliHLTTPCDataCompressor()
+{
+  if(fInputTracks)
+    delete fInputTracks;
+  if(fBenchmark)
+    delete fBenchmark;
+  if(fClusters)
+    {
+      for(Int_t i=0; i<36; i++)
+       for(Int_t j=0; j<6; j++)
+         if(fClusters[i][j])
+           delete fClusters[i][j];
+    }
+  CloseOutputFile();
+}
+
+void AliHLTTPCDataCompressor::DoBench(Char_t *fname)
+{
+  fBenchmark->Analyze(fname);
+}
+
+void AliHLTTPCDataCompressor::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
+{
+  fNumPadBits = pad;
+  fNumTimeBits = time;
+  fNumChargeBits = charge;
+  fNumShapeBits = shape;
+}
+
+void AliHLTTPCDataCompressor::SetTransverseResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width)
+{
+  fXYResidualStep1 = res1;
+  fXYResidualStep2 = res2;
+  fXYResidualStep3 = res3;
+  fXYWidthStep = width;
+}
+
+void AliHLTTPCDataCompressor::SetLongitudinalResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width)
+{
+  fZResidualStep1 = res1;
+  fZResidualStep2 = res2;
+  fZResidualStep3 = res3;
+  fZWidthStep = width;
+}
+
+const Float_t AliHLTTPCDataCompressor::GetXYResidualStep(Int_t row) 
+{
+  if(row < AliHLTTPCTransform::GetNRowLow())
+    return fXYResidualStep1;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1())
+    return fXYResidualStep2;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1() + AliHLTTPCTransform::GetNRowUp2())
+    return fXYResidualStep3;
+  else
+    {
+      cerr<<"AliHLTTPCDataCompressor::GetXYResidualStep : Wrong row number "<<row<<endl;
+      return -1;
+    }
+}
+
+const Float_t AliHLTTPCDataCompressor::GetZResidualStep(Int_t row) 
+{
+  if(row < AliHLTTPCTransform::GetNRowLow())
+    return fZResidualStep1;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1())
+    return fZResidualStep2;
+  else if(row < AliHLTTPCTransform::GetNRowLow() + AliHLTTPCTransform::GetNRowUp1() + AliHLTTPCTransform::GetNRowUp2())
+    return fZResidualStep3;
+  else
+    {
+      cerr<<"AliHLTTPCDataCompressor::GetXYResidualStep : Wrong row number "<<row<<endl;
+      return -1;
+    }
+}
+
+void AliHLTTPCDataCompressor::OpenOutputFile()
+{
+#ifndef use_aliroot
+   LOG(AliHLTTPCLog::kError,"AliHLTTPCDataCompressor::OpenOutputFile","Version")
+     <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
+#else
+  Char_t filename[1024];
+  
+  sprintf(filename,"%s/comp/comprates.txt",fPath);
+  fCompRatioFile = new ofstream(filename);
+  
+  if(fOutputFile)
+    if(fOutputFile->IsOpen())
+      fOutputFile->Close();
+
+  sprintf(filename,"%s/alirunfile.root",fPath);
+  TFile *f = TFile::Open(filename);
+  AliTPCParam *param = (AliTPCParam*)f->Get(AliHLTTPCTransform::GetParamName());
+  sprintf(filename,"%s/comp/AliTPCclusters.root",fPath);
+  fOutputFile = TFile::Open(filename,"RECREATE");
+  param->Write(param->GetTitle());
+  f->Close();
+#endif
+}
+
+void AliHLTTPCDataCompressor::CloseOutputFile()
+{
+  if(fCompRatioFile)
+    {
+      fCompRatioFile->close();
+      delete fCompRatioFile;
+    }
+  
+  if(!fOutputFile)
+    return;
+#ifdef use_root
+  if(!fOutputFile->IsOpen())
+    return;
+  fOutputFile->Close();
+#else
+  fclose(fOutputFile);
+#endif
+  fOutputFile=0;
+}
+
+void AliHLTTPCDataCompressor::LoadData(Int_t event,Bool_t sp)
+{
+  fSinglePatch=sp;
+  fEvent=event;
+  AliHLTTPCMemHandler *clusterfile[36][6];
+  Char_t fname[1024];
+  for(Int_t s=0; s<=35; s++)
+    {
+      for(Int_t p=0; p<6; p++)
+       {
+         if(fClusters[s][p])
+           delete fClusters[s][p];
+         fClusters[s][p] = 0;
+         clusterfile[s][p] = new AliHLTTPCMemHandler();
+         if(fSinglePatch)
+           sprintf(fname,"%s/cf/points_%d_%d_%d.raw",fPath,fEvent,s,-1);
+         else
+           sprintf(fname,"%s/cf/points_%d_%d_%d.raw",fPath,fEvent,s,p);
+         clusterfile[s][p]->SetBinaryInput(fname);
+         
+         fClusters[s][p] = (AliHLTTPCSpacePointData*)clusterfile[s][p]->Allocate();
+         clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+         clusterfile[s][p]->CloseBinaryInput();
+         
+         if(fSinglePatch)
+           break;
+       }
+    }
+  
+  sprintf(fname,"%s/cf/tracks_%d.raw",fPath,fEvent);
+  AliHLTTPCMemHandler *tfile = new AliHLTTPCMemHandler();
+  tfile->SetBinaryInput(fname);
+  
+  if(fInputTracks)
+    delete fInputTracks;
+  fInputTracks = new AliHLTTPCTrackArray();
+  tfile->Binary2TrackArray(fInputTracks);
+  tfile->CloseBinaryInput();
+  delete tfile;
+}
+
+void AliHLTTPCDataCompressor::FillData(Int_t min_hits,Bool_t expand)
+{
+  
+  //Fill the track data into track and cluster structures, and write to file.
+  //Preparation for compressing it.
+  
+#if 0
+  cout<<"Filling data; "<<fInputTracks->GetNTracks()<<" tracks"<<endl;
+#endif
+  AliHLTTPCTrackArray *comptracks = new AliHLTTPCTrackArray("AliHLTTPCModelTrack");
+  fInputTracks->QSort();
+  for(Int_t i=0; i<fInputTracks->GetNTracks(); i++)
+    {
+      AliHLTTPCTrack *intrack = fInputTracks->GetCheckedTrack(i);
+      if(!intrack) continue;
+
+      if(intrack->GetNHits()<min_hits) break;
+
+      intrack->CalculateHelix();
+      
+      AliHLTTPCModelTrack *outtrack = (AliHLTTPCModelTrack*)comptracks->NextTrack();
+      outtrack->SetNHits(intrack->GetNHits());
+      outtrack->SetRowRange(intrack->GetFirstRow(),intrack->GetLastRow());
+      outtrack->SetFirstPoint(intrack->GetFirstPointX(),intrack->GetFirstPointY(),intrack->GetFirstPointZ());
+      outtrack->SetLastPoint(intrack->GetLastPointX(),intrack->GetLastPointY(),intrack->GetLastPointZ());
+      outtrack->SetPt(intrack->GetPt());
+      outtrack->SetPsi(intrack->GetPsi());
+      outtrack->SetTgl(intrack->GetTgl());
+      outtrack->SetCharge(intrack->GetCharge());
+      outtrack->CalculateHelix();
+      Int_t nhits = intrack->GetNHits();
+      UInt_t *hitids = intrack->GetHitNumbers();
+      Int_t origslice = (hitids[nhits-1]>>25)&0x7f;
+      outtrack->Init(origslice,-1);
+      for(Int_t j=nhits-1; j>=0; j--)
+       {
+         UInt_t id=hitids[j];
+         Int_t slice = (id>>25)&0x7f;
+         Int_t patch = (id>>22)&0x7;
+         UInt_t pos = id&0x3fffff;          
+
+         //UInt_t size;
+         AliHLTTPCSpacePointData *points = fClusters[slice][patch];//->GetDataPointer(size);
+         Float_t xyz[3] = {points[pos].fX,points[pos].fY,points[pos].fZ};
+         Int_t padrow = points[pos].fPadRow;
+
+         //Calculate the crossing point between track and padrow
+         Float_t angle = 0; //Perpendicular to padrow in local coordinates
+         AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+         if(!intrack->CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(padrow)))
+           {
+             cerr<<"AliHLTTPCDataCompressor::FillData : Error in crossing point calc on slice "<<slice<<" row "<<padrow<<endl;
+             break;
+             //outtrack->Print(kFALSE);
+             //exit(5);
+           }
+         
+         Float_t xyz_cross[3] = {intrack->GetPointX(),intrack->GetPointY(),intrack->GetPointZ()};
+         
+         Int_t sector,row;
+         AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
+         AliHLTTPCTransform::Global2Raw(xyz_cross,sector,row);
+         AliHLTTPCTransform::Global2Raw(xyz,sector,row);
+         
+         outtrack->SetPadHit(padrow,xyz_cross[1]);
+         outtrack->SetTimeHit(padrow,xyz_cross[2]);
+
+         if(fWriteClusterShape)
+           {
+             Float_t angle = intrack->GetCrossingAngle(padrow,slice);
+             outtrack->SetCrossingAngleLUT(padrow,angle);
+             outtrack->CalculateClusterWidths(padrow,kTRUE);
+             Int_t patch = AliHLTTPCTransform::GetPatch(padrow);
+             Float_t sigmaY2 = points[pos].fSigmaY2 / pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2);
+             Float_t sigmaZ2 = points[pos].fSigmaZ2 / pow(AliHLTTPCTransform::GetZWidth(),2);
+             outtrack->SetCluster(padrow,xyz[1],xyz[2],points[pos].fCharge,sigmaY2,sigmaZ2,3);
+           }
+         else
+           outtrack->SetCluster(padrow,xyz[1],xyz[2],points[pos].fCharge,0,0,3);
+         
+         //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTTPCModelTrack::FillTrack!
+         outtrack->GetClusterModel(padrow)->fSlice=slice;
+         points[pos].fCharge = 0;//Mark this cluster as used.
+         fNusedClusters++;
+       }
+      if(!expand)
+       outtrack->SetNClusters(AliHLTTPCTransform::GetNRows(-1));
+    }
+  
+  if(expand)
+    ExpandTrackData(comptracks);
+  
+#if 0
+  cout<<"Writing "<<comptracks->GetNTracks()<<" tracks to file"<<endl;
+#endif
+  AliHLTTPCCompress *comp = new AliHLTTPCCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
+  comp->WriteFile(comptracks);
+  delete comp;
+  delete comptracks;
+  
+}
+
+void AliHLTTPCDataCompressor::ExpandTrackData(AliHLTTPCTrackArray *tracks)
+{
+  //Loop over tracks and try to assign unused clusters.
+  //Only clusters which are closer than the max. residual are taken.
+  
+#if 0
+  cout<<"Expanding "<<tracks->GetNTracks()<<" tracks"<<endl;
+#endif
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)tracks->GetCheckedTrack(i);
+      if(!track) continue;
+      if(track->GetNHits() == AliHLTTPCTransform::GetNRows()) continue;
+      
+      Int_t nhits = track->GetNHits();
+      //cout<<"Expanding track with "<<nhits<<" clusters"<<endl;
+      
+      Int_t last_slice=-1;
+      for(Int_t padrow=AliHLTTPCTransform::GetNRows()-1; padrow>=0; padrow--)
+       {
+         if(track->IsPresent(padrow))
+           {
+             last_slice = track->GetClusterModel(padrow)->fSlice;
+             continue;
+           }
+         
+         if(last_slice < 0) //the outer cluster is missing, so skip it - it will be written anyhow.
+           continue;
+         
+         //Check the slice of the next padrow:
+         Int_t next_padrow = padrow-1;
+         Int_t next_slice = -1;
+         while(next_padrow >=0)
+           {
+             if(track->IsPresent(next_padrow))
+               {
+                 next_slice = track->GetClusterModel(next_padrow)->fSlice;
+                 break;
+               }
+             next_padrow--;
+           }
+         if(next_slice>=0)
+           if(next_slice != last_slice)//The track crosses a slice boundary here
+             continue;
+         
+         //UInt_t size;
+         AliHLTTPCSpacePointData *points = fClusters[last_slice][0];//->GetDataPointer(size);
+         
+         Float_t angle = 0;
+         AliHLTTPCTransform::Local2GlobalAngle(&angle,last_slice);
+         if(!track->CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(padrow)))
+           continue;
+         Float_t xyz_cross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
+         AliHLTTPCTransform::Global2Local(xyz_cross,last_slice,kTRUE);
+         Float_t mindist = 123456789;
+         AliHLTTPCSpacePointData *closest=0;
+         for(UInt_t j=0; j<fNcl[last_slice][0]; j++)
+           {
+             if(points[j].fCharge == 0) continue;// || points[j].fPadRow != padrow) continue;
+             if(points[j].fPadRow < padrow) continue;
+             if(points[j].fPadRow > padrow) break;
+             Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
+             AliHLTTPCTransform::Global2Local(xyz,last_slice,kTRUE);
+             
+             //Check for overflow:
+             Int_t temp = (Int_t)rint((xyz_cross[1]-xyz[1])/GetXYResidualStep(padrow));
+             if( abs(temp) > 1<<(GetNPadBits()-1))
+               continue;
+             
+             temp = (Int_t)rint((xyz_cross[2]-xyz[2])/GetZResidualStep(padrow));
+             if( abs(temp) > 1<<(GetNTimeBits()-1))
+               continue;
+             
+             Float_t dist = sqrt( pow(xyz_cross[1]-xyz[1],2) + pow(xyz_cross[2]-xyz[2],2) );
+             if(dist < mindist)
+               {
+                 closest = &points[j];
+                 mindist = dist;
+               }
+           }
+         if(closest) //there was a cluster assigned
+           {
+             Int_t sector,row;
+             Float_t xyz[3] = {closest->fX,closest->fY,closest->fZ};
+             AliHLTTPCTransform::Slice2Sector(last_slice,padrow,sector,row);
+             AliHLTTPCTransform::Local2Raw(xyz_cross,sector,row);
+             AliHLTTPCTransform::Global2Raw(xyz,sector,row);
+             
+             track->SetPadHit(padrow,xyz_cross[1]);
+             track->SetTimeHit(padrow,xyz_cross[2]);
+             
+             if(fWriteClusterShape)
+               {
+                 Float_t angle = track->GetCrossingAngle(padrow,last_slice);
+                 track->SetCrossingAngleLUT(padrow,angle);
+                 track->CalculateClusterWidths(padrow,kTRUE);
+                 Int_t patch = AliHLTTPCTransform::GetPatch(padrow);
+                 Float_t sigmaY2 = closest->fSigmaY2 / pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2);
+                 Float_t sigmaZ2 = closest->fSigmaZ2 / pow(AliHLTTPCTransform::GetZWidth(),2);
+                 track->SetCluster(padrow,xyz[1],xyz[2],closest->fCharge,sigmaY2,sigmaZ2,3);
+               }
+             else
+               track->SetCluster(padrow,xyz[1],xyz[2],closest->fCharge,0,0,3);
+             nhits++;
+             
+             //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTTPCModelTrack::FillTrack!
+             track->GetClusterModel(padrow)->fSlice=last_slice;
+             closest->fCharge = 0;//Mark this cluster as used.
+           }
+       }
+      track->SetNClusters(AliHLTTPCTransform::GetNRows());
+      //cout<<"Track was assigned "<<nhits<<" clusters"<<endl;
+    }
+  
+}
+
+void AliHLTTPCDataCompressor::WriteRemaining(Bool_t select)
+{
+  //Write remaining clusters (not assigned to any tracks) to file
+
+  
+  if(!fKeepRemaining)
+    return;
+  
+  if(select)
+    SelectRemainingClusters();
+  
+  Char_t filename[1024];
+  
+  if(!fSinglePatch)
+    {
+      cerr<<"AliHLTTPCCompressor::WriteRemaining : You have to modify this function when not running singlepatch"<<endl;
+      return;
+    }
+
+#if 0
+  cout<<"Writing remaining clusters "<<endl;
+#endif
+  Int_t nrows = AliHLTTPCTransform::GetNRows();
+  Int_t *npoints = new Int_t[nrows];
+  for(Int_t i=0; i<=35; i++)
+    {
+      for(Int_t patch=0; patch < 1; patch++)
+       {
+         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
+         FILE *outfile = fopen(filename,"w");
+         if(!outfile)
+           {
+             cerr<<"AliHLTTPCDataCompressor::WriteRemaining : Cannot open file "<<filename<<endl;
+             exit(5);
+           }
+         //UInt_t dummy;
+         AliHLTTPCSpacePointData *points = fClusters[i][patch];//->GetDataPointer(dummy);
+         
+         memset(npoints,0,nrows*sizeof(Int_t));
+         
+         for(UInt_t j=0; j<fNcl[i][patch]; j++)
+           {
+             if(points[j].fCharge == 0) continue; //has been used
+             npoints[points[j].fPadRow]++;
+           }
+         Int_t size =0;
+         Byte_t *data = 0;
+         AliHLTTPCRemainingRow *tempPt=0;
+         
+         Int_t last_row = -2;
+         Int_t localcounter=0;
+         
+         for(UInt_t j=0; j<fNcl[i][patch]; j++)
+           {
+             if(points[j].fCharge == 0) continue; //has been used
+             
+             Int_t padrow = points[j].fPadRow;
+             if(padrow != last_row)
+               {
+                 if(last_row != -2)
+                   {
+                     if(!tempPt)
+                       {
+                         cerr<<"AliHLTTPCDataCompressor::WriteRemaining : Zero row pointer "<<endl;
+                         exit(5);
+                       }
+                     if(localcounter != tempPt->fNClusters)
+                       {
+                         cerr<<"AliHLTTPCDataCompressor::WriteRemaining : Mismatching clustercounter "<<localcounter<<" "
+                             <<(Int_t)tempPt->fNClusters<<endl;
+                         exit(5);
+                       }
+                     //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
+                     fwrite(tempPt,size,1,outfile);
+                   }
+                 if(data)
+                   delete [] data;
+                 size = sizeof(AliHLTTPCRemainingRow) + npoints[padrow]*sizeof(AliHLTTPCRemainingCluster);
+                 data = new Byte_t[size];
+                 tempPt = (AliHLTTPCRemainingRow*)data;
+                 
+                 localcounter=0;
+                 tempPt->fPadRow = padrow;
+                 tempPt->fNClusters = npoints[padrow];
+                 last_row = padrow;
+               }
+             if(localcounter >= npoints[padrow])
+               {
+                 cerr<<"AliHLTTPCDataCompressor::WriteRemaining : Cluster counter out of range: "
+                     <<localcounter<<" "<<npoints[padrow]<<endl;
+                 exit(5);
+               }
+             
+             Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
+             AliHLTTPCTransform::Global2Local(xyz,i,kTRUE);
+             
+             tempPt->fClusters[localcounter].fY = xyz[1];
+             tempPt->fClusters[localcounter].fZ = xyz[2];
+             tempPt->fClusters[localcounter].fCharge = points[j].fCharge;
+             tempPt->fClusters[localcounter].fSigmaY2 = points[j].fSigmaY2;
+             tempPt->fClusters[localcounter].fSigmaZ2 = points[j].fSigmaZ2;
+             localcounter++;
+             fNunusedClusters++;
+           }
+         
+         //Write the last row:
+         fwrite(tempPt,size,1,outfile);
+         if(data)
+           delete [] data;
+         fclose(outfile);
+       }
+    }
+  delete [] npoints;
+}
+
+void AliHLTTPCDataCompressor::SelectRemainingClusters()
+{
+  //Select which remaining clusters to write in addition to the compressed data.
+  //In particular one can here make sure that "important" clusters are not missed:
+  //The offline track finder perform seed finding in the outer padrows;
+  //the first seeding is using pair of points on outermost padrow and 
+  //0.125*nrows more rows towards the vertex. The second seeding uses pair
+  //of points on the outermost padrow-0.5*0.125*nrows and 0.125*nrows + 0.5*0.125*nrows
+  //more rows towards the vertex. In order to evaluate the seeds, the track offline
+  //track finder checks whether a certain amount of possible clusters (padrows) is 
+  //attached to the track, and then the kalman filtering starts.
+  //To ensure a minimal loss off efficiency, all clusters in this region should be
+  //intact.....
+  
+#if 0
+  cout<<"Cleaning up clusters"<<endl;
+#endif
+  Int_t nrows = AliHLTTPCTransform::GetNRows();
+  Int_t gap=(Int_t)(0.125*nrows), shift=(Int_t)(0.5*gap);
+  
+  for(Int_t slice=0; slice<36; slice++)
+    {
+      //UInt_t dummy;
+      AliHLTTPCSpacePointData *points = fClusters[slice][0];//->GetDataPointer(dummy);
+      for(UInt_t i=0; i<fNcl[slice][0]; i++)
+       {
+         if(points[i].fCharge == 0) continue; //Already removed
+         Int_t padrow = (Int_t)points[i].fPadRow;
+         
+         Float_t xyz[3] = {points[i].fX,points[i].fY,points[i].fZ};
+         Int_t sector,row;
+         AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
+         AliHLTTPCTransform::Global2Raw(xyz,sector,row);
+         
+         if(padrow >= nrows-1-gap-shift) continue;//save all the clusters in this region
+         
+         //if(padrow >= nrows-1-shift) continue;
+
+         //Save the clusters at the borders:
+         //if(xyz[1] < 3 || xyz[1] >= AliHLTTPCTransform::GetNPads(padrow)-4)
+         // continue;
+
+         //Save clusters on padrows used for offline seeding:
+         if(padrow == nrows - 1 || padrow == nrows - 1 - gap ||                 //First seeding
+            padrow == nrows - 1 - shift || padrow == nrows - 1 - gap - shift)   //Second seeding
+           continue;
+         
+         //Cluster did not meet any of the above criteria, so disregard it:
+         points[i].fCharge = 0;
+       }
+    }
+  
+}
+
+void AliHLTTPCDataCompressor::CompressAndExpand()
+{
+  //Read tracks/clusters from file, compress data and uncompress it. Write compression rates to file.
+#if 0
+  cout<<"Compressing and expanding data"<<endl;
+#endif
+  AliHLTTPCCompress *comp = new AliHLTTPCCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
+  comp->CompressFile();
+  comp->ExpandFile();
+  comp->PrintCompRatio(fCompRatioFile);
+  delete comp;
+  
+  //Write the ratio between used and unused clusters to comp file:
+  ofstream &out = *fCompRatioFile;
+  out<<fNusedClusters<<' '<<fNunusedClusters<<endl;
+}
+
+
+void AliHLTTPCDataCompressor::RestoreData(Bool_t remaining_only)
+{
+  //Restore the uncompressed data together with the remaining clusters,
+  //and write to a final cluster file which serves as an input to the
+  //final offline tracker.
+  
+#ifndef use_aliroot
+   LOG(AliHLTTPCLog::kError,"AliHLTTPCDataCompressor::RestoreData","Version")
+     <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
+#else
+
+#if 0
+  cout<<"Restoring data"<<endl;
+#endif
+  
+  const Int_t maxpoints=500000;
+  TempCluster **clusters = new TempCluster*[36];
+  Int_t *ncl = new Int_t[36];
+  for(Int_t i=0; i<36; i++)
+    {
+      ncl[i]=0;
+      clusters[i] = new TempCluster[maxpoints];
+    }
+  
+  if(!remaining_only)
+    ReadUncompressedData(clusters,ncl,maxpoints);
+  
+  if(fKeepRemaining)
+    ReadRemaining(clusters,ncl,maxpoints);
+  
+  Char_t filename[1024];
+  sprintf(filename,"%s/digitfile.root",fPath);
+  TFile *rootfile = TFile::Open(filename);
+  rootfile->cd();
+  AliTPCParam *param = (AliTPCParam*)rootfile->Get(AliHLTTPCTransform::GetParamName());
+
+  AliTPCDigitsArray *darray = new AliTPCDigitsArray();
+  darray->Setup(param);
+  darray->SetClass("AliSimDigits");
+  sprintf(filename,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),fEvent);
+  Bool_t ok = darray->ConnectTree(filename);
+  if(!ok)
+    {
+      cerr<<"AliHLTTPCDataCompressor::RestoreData : Problems connecting tree"<<endl;
+      return;
+    }
+
+  fOutputFile->cd();
+    
+  AliTPCClustersArray *carray = new AliTPCClustersArray();
+  carray->Setup(param);
+  carray->SetClusterType("AliTPCcluster");
+  carray->MakeTree();
+  
+  Int_t totcounter=0;
+  for(Int_t slice=0; slice<=35; slice++)
+    {
+      TempCluster **clPt = new TempCluster*[maxpoints];
+#if 0
+      cout<<"Sorting "<<ncl[slice]<<" clusters in slice "<<slice<<endl;
+#endif
+      for(Int_t i=0; i<ncl[slice]; i++)
+       clPt[i] = &clusters[slice][i];
+      
+      QSort(clPt,0,ncl[slice]);
+      
+      //cout<<"padrow "<<clPt[i]->padrow<<" pad "<<clPt[i]->pad<<" time "<<clPt[i]->time<<endl;
+
+      Int_t falseid=0;
+      Int_t counter=0;
+      for(Int_t padrow=AliHLTTPCTransform::GetFirstRow(-1); padrow<=AliHLTTPCTransform::GetLastRow(-1); padrow++)
+       {
+         Int_t sec,row;
+         AliHLTTPCTransform::Slice2Sector(slice,padrow,sec,row);
+         AliTPCClustersRow *clrow=carray->CreateRow(sec,row);
+         AliSimDigits *digits = (AliSimDigits*)darray->LoadRow(sec,row);
+         digits->ExpandBuffer();
+         digits->ExpandTrackBuffer();
+         Int_t patch = AliHLTTPCTransform::GetPatch(padrow);
+         while(counter < ncl[slice] && clPt[counter]->padrow == padrow)
+           {
+             Float_t temp[3];
+             AliHLTTPCTransform::Raw2Local(temp,sec,row,clPt[counter]->pad,clPt[counter]->time);
+             
+             AliTPCcluster *c = new AliTPCcluster();
+             c->SetY(temp[1]);
+             c->SetZ(temp[2]);
+             c->SetQ(clPt[counter]->charge);
+             
+             c->SetSigmaY2(clPt[counter]->sigmaY2*pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2));
+             c->SetSigmaZ2(clPt[counter]->sigmaZ2*pow(AliHLTTPCTransform::GetZWidth(),2));
+             Int_t pad = TMath::Nint(clPt[counter]->pad);
+             Int_t time = TMath::Nint(clPt[counter]->time);
+             
+             if(pad < 0)
+               pad=0;
+             if(pad >= AliHLTTPCTransform::GetNPads(padrow))
+               pad = AliHLTTPCTransform::GetNPads(padrow)-1;
+             if(time < 0 || time >= AliHLTTPCTransform::GetNTimeBins())
+               cerr<<"row "<<padrow<<" pad "<<pad<<" time "<<time<<endl;
+             
+             for(Int_t lab=0; lab<3; lab++)
+               {
+                 Int_t label = digits->GetTrackIDFast(time,pad,lab);
+                 if(label > 1)
+                   c->SetLabel(label-2,lab);
+                 else if(label==0)
+                   c->SetLabel(-2,lab);
+                 else
+                   c->SetLabel(-1,lab);
+                 if(lab==0 && c->GetLabel(0) < 0)
+                   {
+                     falseid++;
+                     //AliHLTTPCTransform::Local2Global(temp,slice);
+                     //cout<<"slice "<<slice<<" padrow "<<padrow<<" y "<<temp[1]<<" z "<<temp[2]<<" label "<<c->GetLabel(0)<<endl;
+                   }
+               }
+             //cout<<"row "<<padrow<<" pad "<<clPt[counter]->pad<<" time "<<clPt[counter]->time<<" sigmaY2 "<<c->GetSigmaY2()<<" sigmaZ2 "<<c->GetSigmaZ2()<<endl;
+             clrow->InsertCluster(c);
+             delete c;
+             counter++;
+             totcounter++;
+           }
+         carray->StoreRow(sec,row);
+         carray->ClearRow(sec,row);
+         darray->ClearRow(sec,row);
+       }
+      //cerr<<"Slice "<<slice<<" nclusters "<<counter<<" falseones "<<falseid<<endl;
+      if(counter != ncl[slice])
+       cerr<<"AliLDataCompressor::RestoreData : Mismatching cluster count :"<<counter<<" "<<ncl[slice]<<endl;
+      delete [] clPt;
+    }
+
+#if 0
+  cout<<"Writing "<<totcounter<<" clusters to rootfile "<<endl;
+#endif
+
+  sprintf(filename,"TreeC_TPC_%d",fEvent);
+  carray->GetTree()->SetName(filename);
+  carray->GetTree()->Write();
+  delete carray;
+  delete darray;
+  rootfile->Close();
+  
+  for(Int_t i=0; i<36; i++)
+    delete [] clusters[i];
+  delete [] clusters;
+  delete [] ncl;
+#endif
+}
+
+void AliHLTTPCDataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints)
+{
+
+#if 0
+  cout<<"Reading uncompressed tracks "<<endl;
+#endif
+  AliHLTTPCCompress *comp = new AliHLTTPCCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
+  
+  if(!comp->ReadFile('u'))
+    return;
+  
+  AliHLTTPCTrackArray *tracks = comp->GetTracks();
+  
+  Int_t charge;
+  Float_t pad,time,sigmaY2,sigmaZ2;
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)tracks->GetCheckedTrack(i);
+      if(!track) continue;
+      for(Int_t padrow=0; padrow < AliHLTTPCTransform::GetNRows(-1); padrow++)
+       {
+         if(!track->IsPresent(padrow)) continue;
+         track->GetPad(padrow,pad);
+         track->GetTime(padrow,time);
+         track->GetClusterCharge(padrow,charge);
+         track->GetXYWidth(padrow,sigmaY2);
+         track->GetZWidth(padrow,sigmaZ2);
+         Int_t slice = track->GetClusterModel(padrow)->fSlice;
+         /*
+           if(pad < -1 || pad > AliHLTTPCTransform::GetNPads(padrow) || time < -1 || time > AliHLTTPCTransform::GetNTimeBins())
+           {
+           cerr<<"AliHLTTPCDataCompressor::ReadUncompressData : Wrong pad "<<pad<<" or time "<<time<<" on row "<<padrow<<" track index "<<i<<endl;
+           track->Print();
+           exit(5);
+           }
+         */
+         if(ncl[slice] >= maxpoints)
+           {
+             cerr<<"AliHLTTPCDataCompressor::ReadUncompressedData : Too many clusters"<<endl;
+             exit(5);
+           }
+         clusters[slice][ncl[slice]].pad = pad;
+         clusters[slice][ncl[slice]].time = time;
+         clusters[slice][ncl[slice]].charge = charge;
+         clusters[slice][ncl[slice]].sigmaY2 = sigmaY2;
+         clusters[slice][ncl[slice]].sigmaZ2 = sigmaZ2;
+         clusters[slice][ncl[slice]].padrow = padrow;
+         //cout<<"row "<<padrow<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<" sigmas "<<sigmaY2<<" "<<sigmaZ2<<endl;
+         ncl[slice]++;
+       }
+    }
+
+  delete comp;
+}
+
+void AliHLTTPCDataCompressor::ReadRemaining(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints)
+{
+  
+  Char_t filename[1024];
+#if 0
+  cout<<"Reading remaining clusters "<<endl;
+#endif
+  AliHLTTPCMemHandler mem;
+  
+  for(Int_t slice=0; slice<=35; slice++)
+    {
+      for(Int_t p=0; p<1; p++)
+       {
+         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+         
+         mem.SetBinaryInput(filename);
+         AliHLTTPCRemainingRow *tempPt = (AliHLTTPCRemainingRow*)mem.Allocate();
+         
+         Int_t nrows=0;
+         FILE *infile = mem.GetFilePointer();
+         while(!feof(infile))
+           {
+             Byte_t *dPt = (Byte_t*)tempPt;
+             if(fread(tempPt,sizeof(AliHLTTPCRemainingRow),1,infile)!=1) break;
+             
+             dPt += sizeof(AliHLTTPCRemainingRow);
+             
+             Int_t size = sizeof(AliHLTTPCRemainingCluster)*tempPt->fNClusters;
+             
+             fread(dPt,size,1,infile);
+             dPt += size;
+             tempPt = (AliHLTTPCRemainingRow*)dPt;
+             nrows++;
+           }
+         
+         mem.CloseBinaryInput();
+         UInt_t dummy;
+         tempPt = (AliHLTTPCRemainingRow*)mem.GetDataPointer(dummy);
+         
+         for(Int_t i=0; i<nrows; i++)
+           {
+             AliHLTTPCRemainingCluster *points = tempPt->fClusters;
+             Int_t padrow = (Int_t)tempPt->fPadRow;
+             Int_t patch = AliHLTTPCTransform::GetPatch(padrow);
+             Int_t sector,row;
+             AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
+             //cout<<"Loading slice "<<slice<<" row "<<padrow<<" with "<<(Int_t)tempPt->fNClusters<<" clusters "<<endl;
+             for(Int_t j=0; j<tempPt->fNClusters; j++)
+               {
+                 
+                 Float_t xyz[3] = {AliHLTTPCTransform::Row2X(padrow),points[j].fY,points[j].fZ};
+                 
+                 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
+                 
+                 if(ncl[slice] >= maxpoints)
+                   {
+                     cerr<<"AliHLTTPCDataCompressor::ReadRemaining : Too many clusters"<<endl;
+                     exit(5);
+                   }
+                 //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
+                 clusters[slice][ncl[slice]].pad = xyz[1];
+                 clusters[slice][ncl[slice]].time = xyz[2];
+                 clusters[slice][ncl[slice]].charge = points[j].fCharge;
+                 clusters[slice][ncl[slice]].sigmaY2 = points[j].fSigmaY2/pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2);
+                 clusters[slice][ncl[slice]].sigmaZ2 = points[j].fSigmaZ2/pow(AliHLTTPCTransform::GetZWidth(),2);
+                 clusters[slice][ncl[slice]].padrow = padrow;
+                 ncl[slice]++;
+               }
+             Byte_t *dPt = (Byte_t*)tempPt;
+             Int_t size = sizeof(AliHLTTPCRemainingRow) + tempPt->fNClusters*sizeof(AliHLTTPCRemainingCluster);
+             dPt += size;
+             tempPt = (AliHLTTPCRemainingRow*)dPt;
+           }
+         
+         mem.Free();
+       }
+    }
+}
+
+void AliHLTTPCDataCompressor::QSort(TempCluster **a, Int_t first, Int_t last)
+{
+  static TempCluster *tmp;
+   static int i;           // "static" to save stack space
+   int j;
+
+   while (last - first > 1) {
+      i = first;
+      j = last;
+      for (;;) {
+       while (++i < last && Compare(a[i], a[first]) < 0)
+         ;
+       while (--j > first && Compare(a[j], a[first]) > 0)
+         ;
+         if (i >= j)
+            break;
+
+         tmp  = a[i];
+         a[i] = a[j];
+         a[j] = tmp;
+      }
+      if (j == first) {
+         ++first;
+         continue;
+      }
+      tmp = a[first];
+      a[first] = a[j];
+      a[j] = tmp;
+      if (j - first < last - (j + 1)) {
+         QSort(a, first, j);
+         first = j + 1;   // QSort(j + 1, last);
+      } else {
+         QSort(a, j + 1, last);
+         last = j;        // QSort(first, j);
+      }
+   }
+}
+
+Int_t AliHLTTPCDataCompressor::Compare(TempCluster *a,TempCluster *b)
+{
+  /*
+  if(a->padrow < 0 || a->padrow > AliHLTTPCTransform::GetNRows(-1) ||
+     b->padrow < 0 || b->padrow > AliHLTTPCTransform::GetNRows(-1))
+    {
+      cerr<<"AliHLTTPCCompressor::Compare : Wrong padrows "<<a->padrow<<" "<<b->padrow<<endl;
+      exit(5);
+    }
+  else if(a->pad < 0 || a->pad > AliHLTTPCTransform::GetNPads(a->padrow) || 
+         b->pad < 0 || b->pad > AliHLTTPCTransform::GetNPads(b->padrow))
+    {
+      cerr<<"AliHLTTPCCompressor::Compare : Wrong pads "<<a->pad<<" "<<b->pad<<endl;
+      exit(5);
+    }
+  else if(a->time < 0 || a->time > AliHLTTPCTransform::GetNTimeBins() || 
+         b->time < 0 || b->time > AliHLTTPCTransform::GetNTimeBins())
+    {
+      cerr<<"AliHLTTPCCompressor::Compare : Wrong timebins "<<a->time<<" "<<b->time<<endl;
+      exit(5);
+    }
+  */
+  if(a->padrow < b->padrow) return -1;
+  if(a->padrow > b->padrow) return 1;
+
+  if(rint(a->pad) == rint(b->pad) && rint(a->time) == rint(b->time)) return 0;
+  
+  if(rint(a->pad) < rint(b->pad)) return -1;
+  if(rint(a->pad) == rint(b->pad) && rint(a->time) < rint(b->time)) return -1;
+  
+  return 1;
+}
+
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDataCompressor.h b/HLT/TPCLib/Ref/AliHLTTPCDataCompressor.h
new file mode 100644 (file)
index 0000000..8afd95a
--- /dev/null
@@ -0,0 +1,109 @@
+// @(#) $Id$
+
+#ifndef AliHLTTPC_DataCompressor
+#define AliHLTTPC_DataCompressor
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCBenchmark;
+class AliHLTTPCTrackArray;
+class AliHLTTPCTrack;
+
+#ifdef use_root
+class TH2F;
+class TFile;
+#endif
+
+struct TempCluster {
+  Float_t pad;
+  Float_t time;
+  Float_t sigmaY2;
+  Float_t sigmaZ2;
+  Int_t charge;
+  Int_t padrow;
+};
+
+class AliHLTTPCDataCompressor {
+  
+ private:
+  AliHLTTPCBenchmark *fBenchmark;    //!
+  AliHLTTPCTrackArray *fInputTracks; //!
+  AliHLTTPCSpacePointData *fClusters[36][6]; //!
+  std::ofstream *fCompRatioFile;      //!
+#ifdef use_root
+  TFile *fOutputFile;            //!
+#else
+  FILE *fOutputFile;
+#endif
+  
+  UInt_t fNcl[36][6];
+  
+  static Int_t fNumPadBits;
+  static Int_t fNumTimeBits;
+  static Int_t fNumChargeBits;
+  static Int_t fNumShapeBits;
+  
+  static Float_t fXYResidualStep1;
+  static Float_t fXYResidualStep2;
+  static Float_t fXYResidualStep3;
+  static Float_t fZResidualStep1;
+  static Float_t fZResidualStep2;
+  static Float_t fZResidualStep3;
+  static Float_t fXYWidthStep;
+  static Float_t fZWidthStep;
+  static Int_t fClusterCharge;
+  
+  void SelectRemainingClusters();
+  void ExpandTrackData(AliHLTTPCTrackArray *tracks);
+  void ReadUncompressedData(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints);
+  void ReadRemaining(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints);
+  void QSort(TempCluster **a, Int_t first, Int_t last);
+  Int_t Compare(TempCluster *a,TempCluster *b);
+  void OpenOutputFile();
+  void CloseOutputFile();
+  
+ protected:
+  Char_t fPath[1024];            //!
+  Int_t fEvent;
+  Int_t fNusedClusters;
+  Int_t fNunusedClusters;
+  
+  Bool_t fWriteClusterShape;
+  Bool_t fKeepRemaining;
+  Bool_t fSinglePatch;
+  Bool_t fWriteIdsToFile;
+  
+ public:
+  AliHLTTPCDataCompressor();
+  AliHLTTPCDataCompressor(Char_t *path,Bool_t keep,Bool_t writeshape);
+  virtual ~AliHLTTPCDataCompressor();
+  
+  virtual void LoadData(Int_t event,Bool_t sp=kTRUE);
+  virtual void FillData(Int_t minhits,Bool_t expand);
+  virtual void WriteRemaining(Bool_t select);
+  void CompressAndExpand();
+  void RestoreData(Bool_t remaining_only=kFALSE);
+  void DoBench(Char_t *fname="benchmark");
+  
+  void SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape);
+  void SetTransverseResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width=0.005);
+  void SetLongitudinalResolutions(Float_t res1,Float_t res2,Float_t res3,Float_t width=0.005);
+  
+  Int_t GetNusedClusters() {return fNusedClusters;}
+  Int_t GetNunusedClusters() {return fNunusedClusters;}
+  
+  static const Int_t GetNPadBits() {return fNumPadBits;}
+  static const Int_t GetNTimeBits() {return fNumTimeBits;}
+  static const Int_t GetNChargeBits() {return fNumChargeBits;}
+  static const Int_t GetNShapeBits() {return fNumShapeBits;}
+  static const Float_t GetXYWidthStep() {return fXYWidthStep;}
+  static const Float_t GetZWidthStep() {return fZWidthStep;}
+  static const Int_t GetClusterCharge() {return fClusterCharge;}
+  static const Float_t GetXYResidualStep(Int_t row);
+  static const Float_t GetZResidualStep(Int_t row);
+
+
+  ClassDef(AliHLTTPCDataCompressor,1) 
+
+};
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDataCompressorHelper.cxx b/HLT/TPCLib/Ref/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/Ref/AliHLTTPCDataCompressorHelper.h b/HLT/TPCLib/Ref/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
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDefinitions.cxx b/HLT/TPCLib/Ref/AliHLTTPCDefinitions.cxx
new file mode 100644 (file)
index 0000000..e80fb63
--- /dev/null
@@ -0,0 +1,37 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
+ *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
+ *          for The ALICE Off-line Project.                               *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// Definitions for the HLT TPC components                                    //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliHLTTPCDefinitions.h"
+
+
+ClassImp(AliHLTTPCDefinitions)
+
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkDDLPackedRawDataType = { sizeof(AliHLTComponent_DataType), {'D','D','L','_','R','W','P','K'},{'T','P','C',' '}};;
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkPackedRawDataType = { sizeof(AliHLTComponent_DataType), {'R','A','W','P','A','K','E','D'},{'T','P','C',' '}};;
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkUnpackedRawDataType = { sizeof(AliHLTComponent_DataType), {'R','A','W','U','N','P','A','K'},{'T','P','C',' '}};;
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkClustersDataType = { sizeof(AliHLTComponent_DataType), {'C','L','U','S','T','E','R','S'},{'T','P','C',' '}};;
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkVertexDataType = { sizeof(AliHLTComponent_DataType), {'V','E','R','T','E','X',' ',' '},{'T','P','C',' '}};;
+const AliHLTComponent_DataType AliHLTTPCDefinitions::gkTrackSegmentsDataType = { sizeof(AliHLTComponent_DataType), {'T','R','A','K','S','E','G','S'},{'T','P','C',' '}};;
+
+    
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDefinitions.h b/HLT/TPCLib/Ref/AliHLTTPCDefinitions.h
new file mode 100644 (file)
index 0000000..f58852b
--- /dev/null
@@ -0,0 +1,71 @@
+// XEmacs -*-C++-*-
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDEFINITIONS_H
+#define ALIHLTTPCDEFINITIONS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* AliHLTTPCDefinitions
+ */
+
+#include "AliHLTDataTypes.h"
+#include "TObject.h"
+
+class AliHLTTPCDefinitions
+    {
+    public:
+
+       static AliHLTUInt8_t GetMinSliceNr( const AliHLTComponent_BlockData& block )
+               {
+               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,
+                                               AliHLTUInt8_t minPatchNr,
+                                               AliHLTUInt8_t maxPatchNr )
+               {
+               return ((maxSliceNr & 0xFF) << 24) | ((minSliceNr & 0xFF) << 16) | ((maxPatchNr & 0xFF) << 8) | ((minPatchNr & 0xFF));
+               }
+
+       static const AliHLTComponent_DataType gkDDLPackedRawDataType;
+       static const AliHLTComponent_DataType gkPackedRawDataType;
+       static const AliHLTComponent_DataType gkUnpackedRawDataType;
+       static const AliHLTComponent_DataType gkClustersDataType;
+       static const AliHLTComponent_DataType gkTrackSegmentsDataType;
+       static const AliHLTComponent_DataType gkVertexDataType;
+
+       ClassDef(AliHLTTPCDefinitions, 0)
+
+    };
+
+#endif
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDigitData.h b/HLT/TPCLib/Ref/AliHLTTPCDigitData.h
new file mode 100644 (file)
index 0000000..75a3e3d
--- /dev/null
@@ -0,0 +1,34 @@
+// @(#) $Id$
+
+#ifndef _DIGITDATA_H_
+#define _DIGITDATA_H_
+
+#include "AliHLTTPCRootTypes.h" 
+
+struct AliHLTTPCDigitData
+{
+#ifdef do_mc
+  Int_t fTrackID[3];
+#endif
+  UShort_t fCharge;
+  UChar_t fPad;
+  UShort_t fTime;
+};
+typedef struct AliHLTTPCDigitData AliHLTTPCDigitData;
+
+struct AliHLTTPCDigitRowData
+{
+  UInt_t fNDigit;
+  UInt_t fRow;
+  AliHLTTPCDigitData fDigitData[0];
+};
+typedef struct AliHLTTPCDigitRowData AliHLTTPCDigitRowData;
+
+struct AliHLTTPCRandomDigitData{
+  UChar_t fRow;
+  UShort_t fCharge;
+  UChar_t fPad;
+  UShort_t fTime;
+};
+typedef struct AliHLTTPCRandomDigitData AliHLTTPCRandomDigitData;
+#endif /* _DIGITDATA_H_ */
diff --git a/HLT/TPCLib/Ref/AliHLTTPCDisplay.cxx b/HLT/TPCLib/Ref/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/Ref/AliHLTTPCDisplay.h b/HLT/TPCLib/Ref/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/Ref/AliHLTTPCFileHandler.cxx b/HLT/TPCLib/Ref/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();