--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © 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');
+}
--- /dev/null
+// @(#) $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
+
+
+
+
+
--- /dev/null
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © 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;}
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © 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
--- /dev/null
+// @(#) $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
+
+
--- /dev/null
+#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_
--- /dev/null
+// $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;
+ }
+
+
--- /dev/null
+// 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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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;
+}
+
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
+//*-- Copyright © 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
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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 ;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
+//*-- Copyright © 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());
+}
+*/
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © 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;
+ */
+}
+
--- /dev/null
+// @(#) $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
+
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: C. Loizides <loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © 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;
+}
+
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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;
+}
+
--- /dev/null
+// @(#) $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
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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
--- /dev/null
+// $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',' '}};;
+
+
--- /dev/null
+// 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
--- /dev/null
+// @(#) $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_ */
--- /dev/null
+// @(#) $Id$
+
+/** \class AliHLTTPCDisplay
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDisplay
+//
+// Simple display class for the HLT tracks.
+</pre>
+*/
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © 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;
+}
--- /dev/null
+// @(#) $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 © 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
--- /dev/null
+// @(#) $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 © 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();