--- /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
+
+#ifdef use_newio
+#include <AliRunLoader.h>
+#endif
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPC.h"
+#include "AliHLTTPCConfMapper.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCVertexFinder.h"
+#include "AliHLTTPCTrackMerger.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCInterMerger.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCFitter.h"
+#ifdef use_aliroot
+#include "AliHLTTPCFileHandler.h"
+#endif
+#include "AliHLTTPCBenchmark.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCVertexData.h"
+#include "AliHLTTPCDDLDataFileHandler.h"
+
+/** \class AliHLTTPC
+<pre>
+//_____________________________________________________________
+//
+// AliHLTTPC
+//
+// Interface class for HLTTPC tracker.
+// For example how to use, see exa/runtracker.C (root)
+// or programs/runtracker.cxx (standalone program).
+//Begin_Html
+//<img src="tpcsectorsnb.gif">
+//End_Html
+</pre>
+*/
+
+ClassImp(AliHLTTPC)
+
+Bool_t AliHLTTPC::fgDoVertexFit = kTRUE;//Include the vertex in the final track fit
+
+AliHLTTPC::AliHLTTPC()
+{
+ //Default constructor. Should also be used when input is from binary files.
+ //In that case the path to where the binary files are located has to be
+ //passed to the AliLevel::Init function.
+
+ fVertexFinder=0;
+ fVertex=0;
+ fTracker=0;
+ fTrackMerger=0;
+ fInterMerger=0;
+ fFileHandler=0;
+ fGlobalMerger=0;
+ fInputFile=0;
+#ifdef use_newio
+ fRunLoader=0;
+#endif
+}
+
+AliHLTTPC::AliHLTTPC(Char_t *infile)
+{
+ //Constructor to use for when input is anything else but binary files,
+ //meaning rootfiles or raw files.
+
+ fVertexFinder=0;
+ fVertex=0;
+ fTracker=0;
+ fTrackMerger=0;
+ fInterMerger=0;
+ fFileHandler=0;
+ fGlobalMerger=0;
+ fInputFile = infile;
+#ifdef use_newio
+ fRunLoader=0;
+#endif
+}
+
+#ifdef use_newio
+AliHLTTPC::AliHLTTPC(AliRunLoader *rl)
+{
+ //Constructor to use when input is aliroot runloader
+ fVertexFinder=0;
+ fVertex=0;
+ fTracker=0;
+ fTrackMerger=0;
+ fInterMerger=0;
+ fFileHandler=0;
+ fGlobalMerger=0;
+ fInputFile=0;
+ fRunLoader = rl;
+}
+#endif
+
+void AliHLTTPC::Init(Char_t *path,EFileType filetype,Int_t npatches)
+{
+ //Init the whole standard tracker chain
+#ifndef use_newio
+ if (filetype==kRunLoader){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+ <<"You have not supplied the input rootfile; if you want "
+ <<"to run with RunLoader use -Duse_newio for compiling!"<<ENDLOG;
+ }
+#endif
+
+ if((filetype!=kBinary) && (filetype!=kDate)
+ && (filetype!=kRunLoader)&& !fInputFile)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+ <<"You have not supplied the input rootfile; use the appropriate ctor!"<<ENDLOG;
+ return;
+ }
+#if use_newio
+ if((filetype==kRunLoader) && !fRunLoader)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
+ <<"You have not supplied the input runloader; use the appropriate ctor!"<<ENDLOG;
+ return;
+ }
+#endif
+
+ fWriteOut = kFALSE;
+ fPileUp = kFALSE;
+ fNoCF=kFALSE;
+ fUseBinary = (filetype==kBinary);
+ SetPath(path);
+
+ fDoRoi = kFALSE;
+ fDoNonVertex = kFALSE;
+ fFindVertex = kFALSE;
+ SetClusterFinderParam();
+
+ fEta[0] = 0.;
+ fEta[1] = 1.1;
+
+ fEvent=0;
+#ifdef use_aliroot /*just to be sure*/
+ AliHLTTPCFileHandler::CleanStaticIndex();
+#endif
+
+ switch(npatches){
+ case 0:
+ fNPatch = 1;
+ fRow[0][0] = AliHLTTPCTransform::GetFirstRow(3);
+ fRow[0][1] = AliHLTTPCTransform::GetLastRow(5);
+ break;
+ case 1:
+ fNPatch = 1; //number of patches change row in process
+ fRow[0][0] = 0;
+ fRow[0][1] = AliHLTTPCTransform::GetLastRow(-1);
+ break;
+ case 2:
+ fNPatch = 2; //number of patches change row in process
+ fRow[0][0] = 0; // first row
+ fRow[0][1] = AliHLTTPCTransform::GetLastRow(1);
+ fRow[1][0] = AliHLTTPCTransform::GetFirstRow(2);
+ fRow[1][1] = AliHLTTPCTransform::GetLastRow(5);
+ break;
+ default:
+ fNPatch = 6;
+ fRow[0][0] = AliHLTTPCTransform::GetFirstRow(0);
+ fRow[0][1] = AliHLTTPCTransform::GetLastRow(0);
+ fRow[1][0] = AliHLTTPCTransform::GetFirstRow(1);
+ fRow[1][1] = AliHLTTPCTransform::GetLastRow(1);
+ fRow[2][0] = AliHLTTPCTransform::GetFirstRow(2);
+ fRow[2][1] = AliHLTTPCTransform::GetLastRow(2);
+ fRow[3][0] = AliHLTTPCTransform::GetFirstRow(3);
+ fRow[3][1] = AliHLTTPCTransform::GetLastRow(3);
+ fRow[4][0] = AliHLTTPCTransform::GetFirstRow(4);
+ fRow[4][1] = AliHLTTPCTransform::GetLastRow(4);
+ fRow[5][0] = AliHLTTPCTransform::GetFirstRow(5);
+ fRow[5][1] = AliHLTTPCTransform::GetLastRow(5);
+ }
+
+ fVertexFinder = new AliHLTTPCVertexFinder();
+ fVertex = new AliHLTTPCVertex();
+ fTracker = new AliHLTTPCConfMapper();
+ fTrackMerger = new AliHLTTPCTrackMerger(fNPatch);
+ fInterMerger = new AliHLTTPCInterMerger();
+ fGlobalMerger = new AliHLTTPCGlobalMerger();
+ SetMergerParameters();//Set default merger parameters
+#ifdef use_aliroot
+ if(filetype==kRoot){
+ fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
+ fFileHandler->SetAliInput(fInputFile);
+ }else if(filetype==kRaw){
+ fFileHandler = new AliHLTTPCDDLDataFileHandler();
+ fFileHandler->SetReaderInput(fInputFile);
+ }else if(filetype==kDate){
+ fFileHandler = new AliHLTTPCDDLDataFileHandler();
+ fFileHandler->SetReaderInput(fInputFile,-1);
+ }
+#if use_newio
+ else if(filetype==kRunLoader){
+ fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
+ fFileHandler->SetAliInput(fRunLoader);
+ }
+#endif
+ else{
+ fFileHandler = new AliHLTTPCMemHandler();
+ }
+#else
+ if(filetype==kRaw){
+ fFileHandler = new AliHLTTPCDDLDataFileHandler();
+ fFileHandler->SetReaderInput(fInputFile);
+ }else{
+ fFileHandler = new AliHLTTPCMemHandler();
+ }
+#endif
+ fBenchmark = new AliHLTTPCBenchmark();
+}
+
+void AliHLTTPC::DoBench(char* name)
+{
+ //dobench
+ fBenchmark->Analyze(name);
+ delete fBenchmark;
+ fBenchmark = new AliHLTTPCBenchmark();
+}
+
+void AliHLTTPC::DoMc(char* file)
+{
+ //domc
+#ifdef use_aliroot
+ if(!fFileHandler->IsDigit(fEvent))
+ fFileHandler->SetMCOutput(file);
+#endif
+}
+
+AliHLTTPC::~AliHLTTPC()
+{
+ //Destructor
+ if(fVertexFinder) delete fVertexFinder;
+ if(fVertex) delete fVertex;
+ if(fTracker) delete fTracker;
+ if(fTrackMerger) delete fTrackMerger;
+ if(fInterMerger) delete fInterMerger;
+ if(fFileHandler) delete fFileHandler;
+ if(fGlobalMerger) delete fGlobalMerger;
+}
+
+void AliHLTTPC::SetClusterFinderParam(Float_t fXYError, Float_t fZError, Bool_t deconv)
+{
+ //set cluster finder parameter
+ fXYClusterError=fXYError;
+ fZClusterError=fZError;
+ fClusterDeconv=deconv;
+}
+
+void AliHLTTPC::SetTrackerParam(Int_t phi_segments, Int_t eta_segments,
+ Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,
+ Double_t min_pt_fit, Double_t maxangle,
+ Double_t goodDist, Double_t hitChi2Cut,
+ Double_t goodHitChi2, Double_t trackChi2Cut,
+ Int_t maxdist,Double_t maxphi,Double_t maxeta,
+ Bool_t vertexconstraint)
+{
+ //Set parameters input to the tracker
+ //If no arguments are given, default parameters will be used
+
+ fTracker->SetNSegments(phi_segments,eta_segments);
+ fTracker->SetMaxDca(min_pt_fit);
+ fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexconstraint);
+ fTracker->SetTrackletCuts(maxangle,goodDist,vertexconstraint);
+ if(vertexconstraint)
+ fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack,maxphi,maxeta);
+ else
+ fTracker->NonVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
+ fTracker->InitVolumes();
+}
+
+void AliHLTTPC::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
+{
+ //set global merger parameter
+ fGlobalMerger->SetParameter(maxy,maxz,maxkappa,maxpsi,maxtgl);
+}
+
+void AliHLTTPC::ProcessEvent(Int_t first,Int_t last,Int_t event)
+{
+ //Do tracking on all slices in region [first,last]
+ //Slices numbering in TPC goes from 0-35, which means that one slice
+ //corresponds to inner+outer sector.E.g. slice 2 corresponds to
+ //inner=2 + outer=38.
+
+ fGlobalMerger->Setup(first,last);
+#ifdef use_aliroot
+ if(fEvent!=event) AliHLTTPCFileHandler::CleanStaticIndex();
+#endif
+ fEvent=event;
+ for(Int_t i=first; i<=last; i++){
+ ProcessSlice(i);
+ fGlobalMerger->SetVertex(fVertex);
+ fGlobalMerger->InitSlice(i);
+ fGlobalMerger->FillTracks(fNTrackData,fTrackData);
+ fFileHandler->Free(); //free the memory
+ fNTrackData=0;
+ fTrackData=0;
+ }
+ fBenchmark->Start("Global track merger");
+ //fGlobalMerger->AddAllTracks();
+ fGlobalMerger->Merge();
+ //fGlobalMerger->SlowMerge(fWriteOutPath);
+ fBenchmark->Stop("Global track merger");
+
+ FitGlobalTracks();
+
+ if(fWriteOut) WriteResults();
+ fFileHandler->FreeDigitsTree();
+}
+
+void AliHLTTPC::ProcessSlice(Int_t slice)
+{
+ //process slice
+ char name[256];
+ Bool_t UseCF = kFALSE;
+#ifdef use_aliroot
+ UseCF = fFileHandler->IsDigit(fEvent);
+#endif
+ if(fUseBinary)
+ UseCF = kTRUE; //In case you are not using aliroot
+ if(fNoCF == kTRUE) //In case you don't want to run with cluster finder
+ UseCF = kFALSE;
+
+ const Int_t kmaxpoints=120000;
+ const Int_t kpointsize = kmaxpoints * sizeof(AliHLTTPCSpacePointData);
+ AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
+
+ fTrackMerger->Reset();
+ fTrackMerger->SetRows(fRow[0]);
+
+ for(Int_t patch=fNPatch-1;patch>=0;patch--){
+ fFileHandler->Init(slice,patch,&fRow[patch][0]);
+ UInt_t npoints=0;
+ AliHLTTPCSpacePointData *points =0;
+ UInt_t ndigits=0;
+ AliHLTTPCDigitRowData *digits =0;
+ if(UseCF){
+ if(fUseBinary){
+ if(!fDoRoi){
+ if(1){ //Binary to Memory
+ fFileHandler->Free();
+ if(fNPatch == 1)
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+ if(!fFileHandler->SetBinaryInput(name)) return;
+ if(fPileUp)
+ { //Read binary files which are not RLE
+ digits = (AliHLTTPCDigitRowData*)fFileHandler->Allocate();
+ fFileHandler->Binary2Memory(ndigits,digits);
+ }
+ else //Read RLE binary files
+ digits= (AliHLTTPCDigitRowData *)fFileHandler->CompBinary2Memory(ndigits);
+
+ fFileHandler->CloseBinaryInput();
+ }
+
+ if(0){ //Binary to Memory with Benchmark
+ fFileHandler->Free();
+ if(fNPatch == 1)
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+ if(!memory->SetBinaryInput(name)) return;
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliHLTTPCDigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ }
+
+ if(0){ //Binary to Memory with Random
+ fFileHandler->Free();
+ fFileHandler->ResetRandom();
+ fFileHandler->SetRandomCluster(100);
+ fFileHandler->SetNGenerate(100);
+ if(fNPatch == 1)
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+ if(!memory->SetBinaryInput(name)) return;
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t dsize=memory->GetMemorySize(ndigits,comp);
+ UInt_t rsize=fFileHandler->GetRandomSize();
+ digits=(AliHLTTPCDigitRowData*)fFileHandler->Allocate(dsize+rsize);
+ fBenchmark->Start("Unpacker");
+ fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ }
+ }
+
+ else{ //Binary to Memory with Roi
+ fFileHandler->Free();
+ Int_t sli[2]={0,0};
+ fFileHandler->SetROI(fEta,sli);
+ if(fNPatch==1)
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+ if(!memory->SetBinaryInput(name)) return;
+ UInt_t compsize=memory->GetFileSize();
+ UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
+ memory->CompBinary2CompMemory(ndigits,comp);
+ memory->CloseBinaryInput();
+ UInt_t datasize=memory->GetMemorySize(ndigits,comp);
+ digits=(AliHLTTPCDigitRowData *)fFileHandler->Allocate(datasize);
+ fBenchmark->Start("Unpacker");
+ datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp);
+ fBenchmark->Stop("Unpacker");
+ memory->Free();
+ }
+ }//end UseBinary
+ else{
+#ifdef use_aliroot
+ fBenchmark->Start("Dummy Unpacker");
+ if(fNPatch==1)
+ sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,-1);
+ else
+ sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,patch);
+ fBenchmark->Stop("Dummy Unpacker");
+
+ if(0){ //Ali to Binary
+ fFileHandler->SetBinaryOutput(name);
+ fFileHandler->AliDigits2CompBinary();
+ fFileHandler->CloseBinaryOutput();
+ }
+
+ if(1){ //Ali to Memory
+ digits=(AliHLTTPCDigitRowData *)fFileHandler->AliAltroDigits2Memory(ndigits,fEvent);
+ if(0){ //Memory to Binary
+ fFileHandler->SetBinaryOutput(name);
+ fFileHandler->Memory2CompBinary(ndigits,digits);
+ fFileHandler->CloseBinaryOutput();
+ }
+ }
+#endif
+ }//end else UseBinary
+
+ points = (AliHLTTPCSpacePointData *) memory->Allocate(kpointsize);
+ fClusterFinder = new AliHLTTPCClustFinderNew();
+ fClusterFinder->InitSlice(slice,patch,fRow[patch][0],fRow[patch][1],kmaxpoints);
+ fClusterFinder->SetDeconv(fClusterDeconv);
+ fClusterFinder->SetXYError(fXYClusterError);
+ fClusterFinder->SetZError(fZClusterError);
+ if((fXYClusterError>0)&&(fZClusterError>0))
+ fClusterFinder->SetCalcErr(kFALSE);
+ fClusterFinder->SetOutputArray(points);
+ fBenchmark->Start("Cluster finder");
+ fClusterFinder->Read(ndigits,digits);
+ fClusterFinder->ProcessDigits();
+ fBenchmark->Stop("Cluster finder");
+ npoints = fClusterFinder->GetNumberOfClusters();
+ delete fClusterFinder;
+ fClusterFinder = 0;
+ fFileHandler->Free();
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Cluster Finder")
+ <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
+ }//end UseCF
+ else{// if not use Clusterfinder
+ if(fUseBinary){//Binary to Memory
+ memory->Free();
+ if(fNPatch==1)
+ sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,patch);
+ if(!memory->SetBinaryInput(name)) return;
+ points = (AliHLTTPCSpacePointData *) memory->Allocate();
+ memory->Binary2Memory(npoints,points);
+ memory->CloseBinaryInput();
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Read Cluster")
+ <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points in File"<<ENDLOG;
+ }
+#ifdef use_aliroot
+ else{
+ points = fFileHandler->AliPoints2Memory(npoints);
+ }
+#endif
+ fBenchmark->Start("Dummy Unpacker");
+ fBenchmark->Stop("Dummy Unpacker");
+ fBenchmark->Start("Dummy CF");
+ fBenchmark->Stop("Dummy CF");
+ }
+
+ if(patch == fNPatch-1){
+ // Vertex
+ if(fFindVertex){
+ // Vertex Finder
+
+ fBenchmark->Start("Vertex Finder Read");
+ fVertexFinder->Reset();
+ fVertexFinder->Read(npoints,points);
+ fBenchmark->Stop("Vertex Finder Read");
+ fBenchmark->Start("Vertex Finder");
+ fVertexFinder->Analyze();
+ AliHLTTPCVertexData vertex[1];
+ fVertexFinder->Write(vertex);
+ fVertex->Read(vertex);
+ fBenchmark->Stop("Vertex Finder");
+ }
+ else{
+ //use 0,0,0 for vertex
+ fVertex->SetZero();
+ }
+ fTrackMerger->SetVertex(fVertex);
+ }
+
+ fTracker->InitSector(slice,fRow[patch],fEta);
+ fTracker->SetVertex(fVertex);
+ fBenchmark->Start("Tracker setup");
+ fTracker->ReadHits(npoints,points);
+ fTracker->MainVertexTracking_a();
+ fBenchmark->Stop("Tracker setup");
+ fBenchmark->Start("Track follower");
+ fTracker->MainVertexTracking_b();
+ fBenchmark->Stop("Track follower");
+ if(fDoNonVertex)
+ fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
+ fBenchmark->Start("Sector track fitting");
+ fTracker->FillTracks();
+ fBenchmark->Stop("Sector track fitting");
+
+ if(fWriteOut)
+ WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
+
+ //free memory
+ if(UseCF)
+ memory->Free();
+ else
+ fFileHandler->Free();
+
+ UInt_t ntracks0 =0;
+ AliHLTTPCTrackSegmentData *trackdata0 =
+ (AliHLTTPCTrackSegmentData *) memory->Allocate(fTracker->GetTracks());
+ memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
+
+ //write tracks
+ if(fWriteOut){
+ if(fNPatch==1)
+ sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
+ memory->SetBinaryOutput(name);
+ memory->Memory2Binary(ntracks0,trackdata0);
+ memory->CloseBinaryOutput();
+ }
+
+ fInterMerger->Reset();
+ fInterMerger->Init(fRow[patch],patch);
+
+ fInterMerger->FillTracks(ntracks0,trackdata0);
+
+ //fBenchmark->Start("Inter Merger");
+ // fInterMerger->Merge();
+ // fInterMerger->SlowMerge();
+
+ //fBenchmark->Stop("Inter Merger");
+ /*
+ //write inter merged tracks
+ if(fWriteOut){
+ sprintf(name,"%stracks_im_%d_%d.raw",fWriteOutPath,slice,patch);
+ WriteTracks(name,fInterMerger,'i'); //write output of intermerger
+ }
+ */
+ memory->Free();
+
+ UInt_t ntracks1 =0;
+ AliHLTTPCTrackSegmentData *trackdata1 =
+ (AliHLTTPCTrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
+ memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
+
+ fTrackMerger->InitSector(slice,patch);
+ fTrackMerger->FillTracks(ntracks1,trackdata1);
+
+ memory->Free();
+ }
+ //fBenchmark->Start("Patch Merger");
+ //fTrackMerger->SlowMerge();
+ fTrackMerger->AddAllTracks();
+ //fTrackMerger->Merge();
+ //fBenchmark->Stop("Patch Merger");
+ /*
+ //write merged tracks
+ if(fWriteOut){
+ sprintf(name,"%stracks_tm_%d.raw",fWriteOutPath,slice);
+ WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
+ }
+ */
+ fTrackData = (AliHLTTPCTrackSegmentData *)
+ fFileHandler->Allocate(fTrackMerger->GetOutTracks());
+
+ fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
+ fTrackMerger->GetOutTracks());
+
+ delete memory;
+}
+
+void AliHLTTPC::FitGlobalTracks()
+{
+ //fit global tracks
+ AliHLTTPCFitter *fitter = new AliHLTTPCFitter(fVertex,AliHLTTPC::DoVertexFit());
+ if(fNPatch==1)
+ fitter->LoadClusters(fWriteOutPath,fEvent,kTRUE);
+ else
+ fitter->LoadClusters(fWriteOutPath,fEvent,kFALSE);
+
+ fBenchmark->Start("Global track fitter");
+ AliHLTTPCTrackArray *tracks = fGlobalMerger->GetOutTracks();
+ for(Int_t i=0; i<tracks->GetNTracks(); i++)
+ {
+ AliHLTTPCTrack *tr = tracks->GetCheckedTrack(i);
+ if(!tr) continue;
+ fitter->FitHelix(tr);
+ tr->UpdateToFirstPoint();
+ }
+ fBenchmark->Stop("Global track fitter");
+ delete fitter;
+}
+
+void AliHLTTPC::WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+ Int_t slice,Int_t patch) const
+{
+ //write space points
+ char name[256];
+ if(fNPatch==1)
+ sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
+ else
+ sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
+ AliHLTTPCMemHandler * memory = new AliHLTTPCMemHandler();
+ memory->SetBinaryOutput(name);
+ memory->Transform(npoints,points,slice);
+ memory->Memory2Binary(npoints,points);
+ memory->CloseBinaryOutput();
+ delete memory;
+}
+
+Int_t AliHLTTPC::WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt) const
+{
+ //write tracks
+ AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
+ memory->SetBinaryOutput(filename);
+ if(opt=='a'||opt=='i'){ //add intracks
+ for(Int_t i=0;i<merger->GetNIn();i++){
+ AliHLTTPCTrackArray *tr=merger->GetInTracks(i);
+ memory->TrackArray2Binary(tr);
+ }
+ }
+
+ if(opt=='o'||opt=='a'){
+ AliHLTTPCTrackArray *tr=merger->GetOutTracks();
+ memory->TrackArray2Binary(tr);
+ }
+
+ memory->CloseBinaryOutput();
+ delete memory;
+ return 1;
+}
+
+void AliHLTTPC::WriteResults()
+{
+ //Write the resulting tracks to outputfile
+ Char_t fname[256];
+ sprintf(fname,"%s/tracks_%d.raw",fWriteOutPath,fEvent);
+ WriteTracks(fname,fGlobalMerger,'a');
+ //WriteTracks("tracks.raw",fGlobalMerger,'a');
+ sprintf(fname,"%s/tracks_gl_%d.raw",fWriteOutPath,fEvent);
+ WriteTracks(fname,fGlobalMerger,'o');
+ //WriteTracks("tracks_gl.raw",fGlobalMerger,'o');
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_H
+#define ALIHLTTPC_H
+
+#ifndef no_root
+#include <TObject.h>
+#include <TFile.h>
+#endif
+
+#ifdef use_newio
+class AliRunLoader;
+#endif
+
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCDigitData;
+class AliHLTTPCConfMapper;
+class AliHLTTPCVertex;
+class AliHLTTPCVertexFinder;
+class AliHLTTPCTrackMerger;
+class AliHLTTPCGlobalMerger;
+#ifndef no_root
+class TDirectory;
+#endif
+class AliHLTTPCClustFinderNew;
+class AliHLTTPCMerger;
+class AliHLTTPCInterMerger;
+class AliHLTTPCFileHandler;
+class AliHLTTPCMemHandler;
+class AliHLTTPCBenchmark;
+
+#ifdef no_root
+class AliHLTTPC {
+#else
+class AliHLTTPC : public TObject {
+#endif
+
+ private:
+ UInt_t fNTrackData; //count data
+ AliHLTTPCTrackSegmentData* fTrackData; //!
+ AliHLTTPCConfMapper *fTracker; //!
+ AliHLTTPCVertex *fVertex; //!
+ AliHLTTPCVertexFinder *fVertexFinder; //!
+ AliHLTTPCTrackMerger *fTrackMerger; //!
+ AliHLTTPCGlobalMerger *fGlobalMerger; //!
+ AliHLTTPCInterMerger *fInterMerger; //!
+ AliHLTTPCClustFinderNew *fClusterFinder; //!
+ AliHLTTPCMemHandler *fFileHandler; //!
+ AliHLTTPCBenchmark *fBenchmark;//!
+
+ Int_t fEvent; //event number
+ Int_t fNPatch; //number of patches
+ Int_t fRow[6][2];//rows
+ Float_t fEta[2]; //eta
+
+ Char_t *fInputFile;//!
+#ifdef use_newio
+ AliRunLoader *fRunLoader; //runloader
+#endif
+ Char_t fPath[256]; //path to aliroot
+ Char_t fWriteOutPath[256]; //path to store
+
+ Bool_t fDoRoi; //do region of interest
+ Bool_t fFindVertex; //find vertex
+ Bool_t fDoNonVertex;//do non vertex pass
+ Bool_t fPileUp; //do pileup
+ Bool_t fNoCF; //dont do cluster finder
+
+ Bool_t fUseBinary; //use binary input
+ Bool_t fWriteOut; //write tracks
+
+ static Bool_t fgDoVertexFit; //do vertex fix
+
+ Bool_t fClusterDeconv; //do cluster deconv
+ Float_t fXYClusterError; //Cluster error
+ Float_t fZClusterError; //Cluster error
+
+ void WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
+ Int_t slice,Int_t patch) const;
+ Int_t WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt='o') const;
+ void WriteResults();
+ void FitGlobalTracks();
+ void SetPath(char *p){sprintf(fPath,"%s",p);}
+
+ public:
+ AliHLTTPC ();
+ AliHLTTPC(Char_t *infile);
+#ifdef use_newio
+ AliHLTTPC(AliRunLoader *rl);
+#endif
+ virtual ~AliHLTTPC();
+ enum EFileType {kBinary, kBinary8, kRoot, kRaw, kDate, kRunLoader};
+ void Init(Char_t *path,EFileType filetype=kBinary,Int_t npatches=6);
+ void SetMergerParameters(Double_t maxy=1.2,Double_t maxz=1.6,Double_t maxkappa=0.003,
+ Double_t maxpsi=0.02,Double_t maxtgl=0.03);
+ void SetTrackerParam(Int_t phi_segments=50,Int_t eta_segments=100,
+ Int_t trackletlength=3,Int_t tracklength=5,
+ Int_t rowscopetracklet=2,Int_t rowscopetrack=3,
+ Double_t min_pt_fit=0,Double_t maxangle=1.31,
+ Double_t goodDist=5,Double_t hitChi2Cut=10,
+ Double_t goodHitChi2=20,Double_t trackChi2Cut=50,
+ Int_t maxdist=50,Double_t maxphi=0.1,Double_t maxeta=0.1,
+ Bool_t vertexconstraint=kTRUE);
+ void SetClusterFinderParam(Float_t fXYError=0.2,Float_t fZError=0.3,Bool_t deconv=kTRUE);
+
+ void ProcessEvent(Int_t first,Int_t last,Int_t event=0);
+ void ProcessSlice(Int_t slice);
+
+ void DoMc(char* file="point_mc.dat");
+ void DoNonVertexTracking() {fDoNonVertex=kTRUE;}
+ void FindVertex() {fFindVertex=kTRUE;}
+ void DoBench(char* name="benchmark");
+ void DoPileup() {fPileUp = kTRUE;}
+ void NoCF() {fNoCF=kTRUE;}
+ void DoRoi(Float_t e0=0.4,Float_t e1=0.5){fEta[0]=e0;fEta[1]=e1;fDoRoi=kTRUE;}
+ void WriteFiles(Char_t *path="./"){fWriteOut = kTRUE; sprintf(fWriteOutPath,"%s",path);}
+
+ static void SetVertexFit(Bool_t f) {fgDoVertexFit=f;}
+ static Bool_t DoVertexFit() {return fgDoVertexFit;}
+
+ ClassDef(AliHLTTPC,1) //Interface class for HLTTPC-tracking
+};
+
+#endif
+
+
+
+
+
--- /dev/null
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+/** \class AliHLTTPCBenchmark
+</pre>
+//_____________________________________________________________
+//
+// AliHLTTPCBenchmark
+//
+// Benchmark class for level3 code
+//
+//
+</pre>
+*/
+
+#ifndef no_root
+#include <TFile.h>
+#include <TGraphAsymmErrors.h>
+#include <TString.h>
+#include <TStopwatch.h>
+#include <TMath.h>
+#endif
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCBenchmark.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCBenchmark)
+
+AliHLTTPCBenchmark::AliHLTTPCBenchmark()
+{
+ //Constructor
+ fNbench = 0;
+ fNmax = 20;
+ fNames = 0;
+ fTimer = 0;
+ fSum = 0;
+ fMin = 0;
+ fMax = 0;
+ fCount = 0;
+}
+
+AliHLTTPCBenchmark::~AliHLTTPCBenchmark()
+{
+ //deconstructor
+ fNbench = 0;
+ if (fNames) {delete [] fNames; fNames = 0;}
+ if (fTimer) {delete [] fTimer; fTimer = 0;}
+ if (fSum) {delete [] fSum; fSum = 0;}
+ if (fMin) {delete [] fMin; fMin = 0;}
+ if (fMax) {delete [] fMax; fMax = 0;}
+ if (fCount) {delete [] fCount; fCount =0;}
+}
+
+Int_t AliHLTTPCBenchmark::GetBench(const Char_t *name)
+{
+ //get bench with name
+ for (Int_t i=0;i<fNbench;i++) {
+ if (!strcmp(name,(const Char_t*)fNames[i])) return i;
+ }
+ return -1;
+}
+
+
+void AliHLTTPCBenchmark::Start(const Char_t *name)
+{
+ //start the benchmark with name
+ if (!fNbench) {
+#ifdef no_root
+ fNames=new Char_t*[fNmax];
+ fTimer = new AliHLTTPCStopwatch[fNmax];
+#else
+ fNames = new TString[fNmax];
+ fTimer = new TStopwatch[fNmax];
+#endif
+
+ fSum = new Float_t[fNmax];
+ fMin = new Float_t[fNmax];
+ fMax = new Float_t[fNmax];
+ fCount = new Int_t[fNmax];
+ for(Int_t i =0;i<fNmax;i++){
+ fSum[i]=0;
+ fMin[i]=0;
+ fMax[i]=0;
+ fCount[i]=0;
+ }
+ }
+ Int_t bench = GetBench(name);
+ if (bench < 0 && fNbench < fNmax ) {
+ // define a new benchmark to Start
+#ifdef no_root
+ fNames[fNbench]=new Char_t[strlen(name)+1];
+ strcpy(fNames[fNbench],name);
+#else
+ fNames[fNbench] = name;
+#endif
+ bench = fNbench;
+ fNbench++;
+ fTimer[bench].Reset();
+ fTimer[bench].Start();
+ } else if (bench >=0) {
+ // Resume the existent benchmark
+ fTimer[bench].Reset();
+ fTimer[bench].Start();
+ }
+ else
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCBenchmark::Start","Start")
+ <<"too many benches"<<ENDLOG;
+}
+
+void AliHLTTPCBenchmark::Stop(const char *name)
+{
+ //stop the benchmark with name
+ Int_t bench = GetBench(name);
+ if (bench < 0) return;
+
+ fTimer[bench].Stop();
+ Float_t val = fTimer[bench].CpuTime();
+
+ fSum[bench] += val;
+ fCount[bench]++;
+ if(fCount[bench]==1){
+ fMin[bench] = val;
+ fMax[bench] = val;
+ }
+ else{
+ if(val<fMin[bench])fMin[bench]=val;
+ if(val>fMax[bench])fMax[bench]=val;
+ }
+}
+
+void AliHLTTPCBenchmark::Analyze(const Char_t* name)
+{
+ //get results of benchmark
+ Float_t *x = new Float_t[fNbench];
+ Float_t *y = new Float_t[fNbench];
+ Float_t *eyl = new Float_t[fNbench];
+ Float_t *eyh = new Float_t[fNbench];
+ Char_t filename[256];
+ sprintf(filename,"%s.dat",name);
+ FILE *f= fopen(filename,"w");
+ for (Int_t i=0;i<fNbench;i++) {
+ Float_t av =0;
+ if(fCount[i]) av = fSum[i]/fCount[i];
+ x[i]=i+1;
+ y[i]=av*1000;
+ eyl[i]=(av-fMin[i])*1000;
+ eyh[i]=(fMax[i]-av)*1000;
+#ifdef no_root
+ fprintf(f,"%2d. %s: ",i+1,fNames[i]);
+#else
+ fprintf(f,"%2d. %s: ",i+1,fNames[i].Data());
+#endif
+ fprintf(f,"total %4.0f patch %4.0f -%4.0f +%4.0f ms\n",fSum[i],av*1000,eyl[i],eyh[i]);
+ }
+ fclose(f);
+ sprintf(filename,"%s.tmp",name);
+/* only a workaround!!
+ FILE *f2= fopen(filename,"w");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",x[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",y[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",eyl[i]); fprintf(f2,"\n");
+ for (Int_t i=0;i<fNbench;i++) fprintf(f2,"%f ",eyh[i]); fprintf(f2,"\n");
+ fclose(f2);
+*/
+#ifndef no_root
+ sprintf(filename,"%s.root",name);
+ TFile *file = new TFile(filename,"RECREATE");
+ TGraphAsymmErrors *gr = new TGraphAsymmErrors(fNbench,x,y,0,0,eyl,eyh);
+ gr->SetTitle("benchmark");
+ gr->SetMarkerStyle(8);
+ gr->SetMinimum(0);
+ //gr->Draw("ALP");
+ gr->Write();
+ file->Close();
+ delete file;
+ file=0;
+#endif
+ delete[] x;
+ delete[] y;
+ delete[] eyl;
+ delete[] eyh;
+}
+
+Double_t AliHLTTPCBenchmark::GetCpuTime()
+{
+ //get cpu time
+ {return (Double_t)(clock()) / CLOCKS_PER_SEC;}
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef AliHLTTPCBenchmarkH
+#define AliHLTTPCBenchmarkH
+
+//_____________________________________________________________
+//
+// AliHLTTPCBenchmark
+//
+// Benchmark class for level3 code
+//
+//
+
+#ifndef no_root
+class TStopwatch;
+class TString;
+#else
+class AliHLTTPCStopwatch;
+#endif
+
+class AliHLTTPCBenchmark {
+
+public:
+ AliHLTTPCBenchmark();
+ virtual ~AliHLTTPCBenchmark();
+ Int_t GetBench(const char *name);
+ void Start(const char *name);
+ void Stop(const char *name);
+ void Analyze(const char* name);
+
+ static Double_t GetCpuTime();
+
+private:
+
+ Int_t fNbench; //Number of active benchmarks
+ Int_t fNmax; //Maximum number of benchmarks initialized
+#ifndef no_root
+ TString *fNames; //Names of benchmarks
+ TStopwatch *fTimer; //Timers
+#else
+ Char_t **fNames; //Names of benchmarks
+ AliHLTTPCStopwatch *fTimer; //Timers
+#endif
+ Float_t *fSum; //sum of time
+ Float_t *fMin; //min of time
+ Float_t *fMax; //max of time
+ Int_t *fCount;// counter
+
+ ClassDef(AliHLTTPCBenchmark,0) //HLTTPC benchmark
+};
+
+#endif
--- /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 "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+/** \class AliHLTTPCClustFinderNew
+<pre>
+//_____________________________________________________________
+// AliHLTTPCClustFinderNew
+//
+// The current cluster finder for HLT
+// (Based on STAR L3)
+//
+// The cluster finder is initialized with the Init function,
+// providing the slice and patch information to work on.
+// The input is a AliHLTTPCDigitRowData structure using the
+// Read function. The resulting space points will be in the
+// array given by the SetOutputArray function.
+//
+// There are several setters which control the behaviour:
+//
+// - SetXYError(Float_t): set fixed error in XY direction
+// - SetZError(Float_t): set fixed error in Z direction
+// (used if errors are not calculated)
+// - SetDeconv(Bool_t): switch on/off deconvolution
+// - SetThreshold(UInt_t): set charge threshold for cluster
+// - SetMatchWidth(UInt_t): set the match distance in
+// time for sequences to be merged
+// - SetSTDOutput(Bool_t): switch on/off output about found clusters
+// - SetCalcErr(Bool_t): switch on/off calculation of
+// space point errors (or widths in raw system)
+// - SetRawSP(Bool_t): switch on/off convertion to raw system
+//
+//
+// Example Usage:
+//
+// AliHLTTPCFileHandler *file = new AliHLTTPCFileHandler();
+// file->SetAliInput(digitfile); //give some input file
+// for(int slice=0; slice<=35; slice++){
+// for(int patch=0; pat<6; pat++){
+// file->Init(slice,patch);
+// UInt_t ndigits=0;
+// UInt_t maxclusters=100000;
+// UInt_t pointsize = maxclusters*sizeof(AliHLTTPCSpacePointData);
+// AliHLTTPCSpacePointData *points = (AliHLTTPCSpacePointData*)memory->Allocate(pointsize);
+// AliHLTTPCDigitRowData *digits = (AliHLTTPCDigitRowData*)file->AliAltroDigits2Memory(ndigits,event);
+// AliHLTTPCClustFinderNew *cf = new AliHLTTPCClustFinderNew();
+// cf->SetMatchWidth(2);
+// cf->InitSlice(slice,patch,maxclusters);
+// cf->SetSTDOutput(kTRUE); //Some output to standard IO
+// cf->SetRawSP(kFALSE); //Convert space points to local system
+// cf->SetThreshold(5); //Threshold of cluster charge
+// cf->SetDeconv(kTRUE); //Deconv in pad and time direction
+// cf->SetCalcErr(kTRUE); //Calculate the errors of the spacepoints
+// cf->SetOutputArray(points); //Move the spacepoints to the array
+// cf->Read(ndigits,digits); //give the data to the cf
+// cf->ProcessDigits(); //process the rows given by init
+// Int_t npoints = cf->GetNumberOfClusters();
+// AliHLTTPCMemHandler *out= new AliHLTTPCMemHandler();
+// out->SetBinaryOutput(fname);
+// out->Memory2Binary(npoints,points); //store the spacepoints
+// out->CloseBinaryOutput();
+// delete out;
+// file->free();
+// delete cf;
+// }
+// }
+</pre>
+*/
+
+ClassImp(AliHLTTPCClustFinderNew)
+
+AliHLTTPCClustFinderNew::AliHLTTPCClustFinderNew()
+{
+ //constructor
+ fMatch = 1;
+ fThreshold = 10;
+ fXYErr = 0.2;
+ fZErr = 0.3;
+ fDeconvPad = kTRUE;
+ fDeconvTime = kTRUE;
+ fStdout = kFALSE;
+ fCalcerr = kTRUE;
+ fRawSP = kFALSE;
+ fFirstRow=0;
+ fLastRow=0;
+}
+
+AliHLTTPCClustFinderNew::~AliHLTTPCClustFinderNew()
+{
+ //destructor
+ ;
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
+{
+ //init slice
+ fNClusters = 0;
+ fMaxNClusters = nmaxpoints;
+ fCurrentSlice = slice;
+ fCurrentPatch = patch;
+ fFirstRow = firstrow;
+ fLastRow = lastrow;
+}
+
+void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
+{
+ //init slice
+ fNClusters = 0;
+ fMaxNClusters = nmaxpoints;
+ fCurrentSlice = slice;
+ fCurrentPatch = patch;
+ fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
+ fLastRow=AliHLTTPCTransform::GetLastRow(patch);
+}
+
+void AliHLTTPCClustFinderNew::SetOutputArray(AliHLTTPCSpacePointData *pt)
+{
+ //set pointer to output
+ fSpacePointData = pt;
+}
+
+void AliHLTTPCClustFinderNew::Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr)
+{
+ //set input pointer
+ fNDigitRowData = ndigits;
+ fDigitRowData = ptr;
+}
+
+void AliHLTTPCClustFinderNew::ProcessDigits()
+{
+ //Loop over rows, and call processrow
+ AliHLTTPCDigitRowData *tempPt = (AliHLTTPCDigitRowData*)fDigitRowData;
+ fNClusters = 0;
+ for(Int_t i=fFirstRow; i<=fLastRow; i++)
+ {
+ fCurrentRow = i;
+ if((Int_t)tempPt->fRow!=fCurrentRow){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCClustFinderNew::ProcessDigits","Digits")
+ <<"Row number should match! "<<tempPt->fRow<<" "<<fCurrentRow<<ENDLOG;
+ continue;
+ }
+ ProcessRow(tempPt);
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+ tmp += size;
+ tempPt = (AliHLTTPCDigitRowData*)tmp;
+ }
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCClustFinderNew::ProcessDigits","Space points")
+ <<"Cluster finder found "<<fNClusters<<" clusters in slice "<<fCurrentSlice
+ <<" patch "<<fCurrentPatch<<ENDLOG;
+}
+
+void AliHLTTPCClustFinderNew::ProcessRow(AliHLTTPCDigitRowData *tempPt)
+{
+ //process row
+ UInt_t lastpad = 123456789;
+
+ AliClusterData *pad1[5000]; //2 lists for internal memory=2pads
+ AliClusterData *pad2[5000]; //2 lists for internal memory=2pads
+ AliClusterData clusterlist[10000]; //Clusterlist
+
+ AliClusterData **currentPt; //List of pointers to the current pad
+ AliClusterData **previousPt; //List of pointers to the previous pad
+ currentPt = pad2;
+ previousPt = pad1;
+ UInt_t nprevious=0,ncurrent=0,ntotal=0;
+
+ //Loop over sequences of this row:
+ for(UInt_t bin=0; bin<tempPt->fNDigit; bin++)
+ {
+ AliHLTTPCDigitData *data = tempPt->fDigitData;
+ if(data[bin].fPad != lastpad)
+ {
+ //This is a new pad
+
+ //Switch the lists:
+ if(currentPt == pad2)
+ {
+ currentPt = pad1;
+ previousPt = pad2;
+ }
+ else
+ {
+ currentPt = pad2;
+ previousPt = pad1;
+ }
+ nprevious = ncurrent;
+ ncurrent = 0;
+ if(bin[data].fPad != lastpad+1)
+ {
+ //this happens if there is a pad with no signal.
+ nprevious = ncurrent = 0;
+ }
+ lastpad = data[bin].fPad;
+ }
+
+ Bool_t newcluster = kTRUE;
+ UInt_t seqcharge=0,seqaverage=0,seqerror=0;
+ UInt_t lastcharge=0,lastwas_falling=0;
+ Int_t newbin=-1;
+
+ if(fDeconvTime)
+ {
+ redo: //This is a goto.
+ if(newbin > -1)
+ {
+ bin = newbin;
+ newbin = -1;
+ }
+
+ lastcharge=0;
+ lastwas_falling = 0;
+ }
+
+ while(1) //Loop over current sequence
+ {
+ if(data[bin].fTime >= AliHLTTPCTransform::GetNTimeBins())
+ {
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Digits")
+ <<"Timebin out of range "<<(Int_t)data[bin].fTime<<ENDLOG;
+ break;
+ }
+
+ //Get the current ADC-value
+ UInt_t charge = data[bin].fCharge;
+
+ if(fDeconvTime)
+ {
+ //Check if the last pixel in the sequence is smaller than this
+ if(charge > lastcharge)
+ {
+ if(lastwas_falling)
+ {
+ newbin = bin;
+ break;
+ }
+ }
+ else lastwas_falling = 1; //last pixel was larger than this
+ lastcharge = charge;
+ }
+
+ //Sum the total charge of this sequence
+ seqcharge += charge;
+ seqaverage += data[bin].fTime*charge;
+ seqerror += data[bin].fTime*data[bin].fTime*charge;
+
+ //Check where to stop:
+ if(bin >= tempPt->fNDigit - 1) //out of range
+ break;
+ if(data[bin+1].fPad != data[bin].fPad) //new pad
+ break;
+ if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence
+ break;
+
+ bin++;
+ }//end loop over sequence
+
+ //Calculate mean of sequence:
+ Int_t seqmean=0;
+ if(seqcharge)
+ seqmean = seqaverage/seqcharge;
+ else
+ {
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Data")
+ <<"Error in data given to the cluster finder"<<ENDLOG;
+ seqmean = 1;
+ seqcharge = 1;
+ }
+
+ //Calculate mean in pad direction:
+ Int_t padmean = seqcharge*data[bin].fPad;
+ Int_t paderror = data[bin].fPad*padmean;
+
+ //Compare with results on previous pad:
+ for(UInt_t p=0; p<nprevious; p++)
+ {
+ //dont merge sequences on the same pad twice
+ if(previousPt[p]->fLastMergedPad==data[bin].fPad) continue;
+
+ Int_t difference = seqmean - previousPt[p]->fMean;
+ if(difference < -fMatch) break;
+
+ if(difference <= fMatch) //There is a match here!!
+ {
+ AliClusterData *local = previousPt[p];
+
+ if(fDeconvPad)
+ {
+ if(seqcharge > local->fLastCharge)
+ {
+ if(local->fChargeFalling) //The previous pad was falling
+ {
+ break; //create a new cluster
+ }
+ }
+ else
+ local->fChargeFalling = 1;
+ local->fLastCharge = seqcharge;
+ }
+
+ //Don't create a new cluster, because we found a match
+ newcluster = kFALSE;
+
+ //Update cluster on current pad with the matching one:
+ local->fTotalCharge += seqcharge;
+ local->fPad += padmean;
+ local->fPad2 += paderror;
+ local->fTime += seqaverage;
+ local->fTime2 += seqerror;
+ local->fMean = seqmean;
+ local->fFlags++; //means we have more than one pad
+ local->fLastMergedPad = data[bin].fPad;
+
+ currentPt[ncurrent] = local;
+ ncurrent++;
+
+ break;
+ } //Checking for match at previous pad
+ } //Loop over results on previous pad.
+
+ if(newcluster)
+ {
+ //Start a new cluster. Add it to the clusterlist, and update
+ //the list of pointers to clusters in current pad.
+ //current pad will be previous pad on next pad.
+
+ //Add to the clusterlist:
+ AliClusterData *tmp = &clusterlist[ntotal];
+ tmp->fTotalCharge = seqcharge;
+ tmp->fPad = padmean;
+ tmp->fPad2 = paderror;
+ tmp->fTime = seqaverage;
+ tmp->fTime2 = seqerror;
+ tmp->fMean = seqmean;
+ tmp->fFlags = 0; //flags for single pad clusters
+ tmp->fLastMergedPad = data[bin].fPad;
+
+ if(fDeconvPad)
+ {
+ tmp->fChargeFalling = 0;
+ tmp->fLastCharge = seqcharge;
+ }
+
+ //Update list of pointers to previous pad:
+ currentPt[ncurrent] = &clusterlist[ntotal];
+ ntotal++;
+ ncurrent++;
+ }
+
+ if(fDeconvTime)
+ if(newbin >= 0) goto redo;
+ }//Loop over digits on this padrow
+
+ WriteClusters(ntotal,clusterlist);
+}
+
+void AliHLTTPCClustFinderNew::WriteClusters(Int_t nclusters,AliClusterData *list)
+{
+ //write cluster to output pointer
+ Int_t thisrow,thissector;
+ UInt_t counter = fNClusters;
+
+ for(int j=0; j<nclusters; j++)
+ {
+ if(!list[j].fFlags) continue; //discard single pad clusters
+ if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
+
+ Float_t xyz[3];
+ Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
+ Float_t fpad2=fXYErr*fXYErr; //fixed given error
+ Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
+ Float_t ftime2=fZErr*fZErr; //fixed given error
+
+ if(fCalcerr) { //calc the errors, otherwice take the fixed error
+ Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
+ UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
+ Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
+ sy2/=q2;
+ if(sy2 < 0) {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
+ <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
+ continue;
+ } else {
+ if(!fRawSP){
+ fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
+ if(sy2 != 0){
+ fpad2*=0.108; //constants are from offline studies
+ if(patch<2)
+ fpad2*=2.07;
+ }
+ } else fpad2=sy2; //take the width not the error
+ }
+ Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
+ sz2/=q2;
+ if(sz2 < 0){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
+ <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
+ continue;
+ } else {
+ if(!fRawSP){
+ ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
+ if(sz2 != 0) {
+ ftime2 *= 0.169; //constants are from offline studies
+ if(patch<2)
+ ftime2 *= 1.77;
+ }
+ } else ftime2=sz2; //take the width, not the error
+ }
+ }
+ if(fStdout==kTRUE)
+ cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
+
+ if(!fRawSP){
+ AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
+ AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
+
+ if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
+ <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
+ if(fNClusters >= fMaxNClusters)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
+ <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
+ return;
+ }
+
+ fSpacePointData[counter].fX = xyz[0];
+ fSpacePointData[counter].fY = xyz[1];
+ fSpacePointData[counter].fZ = xyz[2];
+
+ } else {
+ fSpacePointData[counter].fX = fCurrentRow;
+ fSpacePointData[counter].fY = fpad;
+ fSpacePointData[counter].fZ = ftime;
+ }
+
+ fSpacePointData[counter].fCharge = list[j].fTotalCharge;
+ fSpacePointData[counter].fPadRow = fCurrentRow;
+ fSpacePointData[counter].fSigmaY2 = fpad2;
+ fSpacePointData[counter].fSigmaZ2 = ftime2;
+
+ Int_t patch=fCurrentPatch;
+ if(patch==-1) patch=0; //never store negative patch number
+ fSpacePointData[counter].fID = counter
+ +((fCurrentSlice&0x7f)<<25)+((patch&0x7)<<22);//Uli
+#ifdef do_mc
+ Int_t trackID[3];
+ GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
+
+ fSpacePointData[counter].fTrackID[0] = trackID[0];
+ fSpacePointData[counter].fTrackID[1] = trackID[1];
+ fSpacePointData[counter].fTrackID[2] = trackID[2];
+
+ //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
+#endif
+
+ fNClusters++;
+ counter++;
+ }
+}
+
+#ifdef do_mc
+void AliHLTTPCClustFinderNew::GetTrackID(Int_t pad,Int_t time,Int_t *trackID)
+{
+ //get mc id
+ AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
+
+ trackID[0]=trackID[1]=trackID[2]=-2;
+ //cout<<"Looking for pad "<<pad<<" time "<<time<<endl;
+ for(Int_t i=fFirstRow; i<=fLastRow; i++){
+ if(rowPt->fRow < (UInt_t)fCurrentRow){
+ AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
+ continue;
+ }
+ AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
+ for(UInt_t j=0; j<rowPt->fNDigit; j++){
+ Int_t cpad = digPt[j].fPad;
+ Int_t ctime = digPt[j].fTime;
+ if(cpad != pad) continue;
+ if(ctime != time) continue;
+
+ trackID[0] = digPt[j].fTrackID[0];
+ trackID[1] = digPt[j].fTrackID[1];
+ trackID[2] = digPt[j].fTrackID[2];
+
+ //cout<<"Reading row "<<fCurrentRow<<" pad "<<cpad<<" time "<<ctime<<" trackID "<<digPt[j].fTrackID[0]<<endl;
+ break;
+ }
+ break;
+ }
+}
+#endif
--- /dev/null
+// @(#) $Id$
+
+#ifndef AliHLTTPC_ClustFinderNew
+#define AliHLTTPC_ClustFinderNew
+
+class AliHLTTPCDigitRowData;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCClustFinderNew {
+
+ public:
+ struct AliClusterData
+ {
+ UInt_t fTotalCharge; //tot charge of cluster
+ UInt_t fPad; //pad value
+ UInt_t fTime; //time value
+ ULong64_t fPad2; //for error in XY direction
+ ULong64_t fTime2; //for error in Z direction
+ UInt_t fMean; //mean in time
+ UInt_t fFlags; //different flags
+ UInt_t fChargeFalling; //for deconvolution
+ UInt_t fLastCharge; //for deconvolution
+ UInt_t fLastMergedPad; //dont merge twice per pad
+ };
+ typedef struct AliClusterData AliClusterData; //!
+
+ private:
+ AliHLTTPCDigitRowData *fDigitRowData; //!
+ AliHLTTPCSpacePointData *fSpacePointData; //!
+ Bool_t fDeconvTime; //deconv in time direction
+ Bool_t fDeconvPad; //deconv in pad direction
+ Bool_t fStdout; //have print out in write clusters
+ Bool_t fCalcerr; //calculate centroid sigmas
+ Bool_t fRawSP; //store centroids in raw system
+
+ UInt_t fNDigitRowData; //ndigts on row
+ Int_t fFirstRow; //first row
+ Int_t fLastRow; //last row
+ Int_t fCurrentRow; //current active row
+ Int_t fCurrentSlice; //current slice
+ Int_t fCurrentPatch; //current patch
+ Int_t fMatch; //size of match
+ UInt_t fThreshold; //threshold for clusters
+ Int_t fNClusters; //number of found clusters
+ Int_t fMaxNClusters; //max. number of clusters
+ Float_t fXYErr; //fixed error in XY
+ Float_t fZErr; //fixed error in Z
+
+#ifdef do_mc
+ void GetTrackID(Int_t pad,Int_t time,Int_t *trackID);
+#endif
+
+ public:
+ AliHLTTPCClustFinderNew();
+ virtual ~AliHLTTPCClustFinderNew();
+
+ void Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr);
+ void InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t maxpoints);
+ void InitSlice(Int_t slice,Int_t patch,Int_t maxpoints);
+ void ProcessDigits();
+ void ProcessRow(AliHLTTPCDigitRowData *tempPt);
+ void SetOutputArray(AliHLTTPCSpacePointData *pt);
+ void WriteClusters(Int_t n_clusters,AliClusterData *list);
+
+ void SetXYError(Float_t f) {fXYErr=f;}
+ void SetZError(Float_t f) {fZErr=f;}
+ void SetDeconv(Bool_t f) {fDeconvPad=f; fDeconvTime=f;}
+ void SetThreshold(UInt_t i) {fThreshold=i;}
+ void SetMatchWidth(UInt_t i) {fMatch=i;}
+ void SetSTDOutput(Bool_t f=kFALSE) {fStdout=f;}
+ void SetCalcErr(Bool_t f=kTRUE) {fCalcerr=f;}
+ void SetRawSP(Bool_t f=kFALSE) {fRawSP=f;}
+ Int_t GetNumberOfClusters() const {return fNClusters;}
+
+ ClassDef(AliHLTTPCClustFinderNew,1) //Fast cluster finder
+};
+#endif
+
+
struct AliHLTTPCClusterData
{
AliHLTUInt32_t fSpacePointCnt;
- AliL3SpacePointData fSpacePoints[];
+ AliHLTTPCSpacePointData fSpacePoints[];
};
#endif // _ALIHLTTPCCLUSTERFORMAT_H_
#endif
#include "AliHLTTPCClusterFinderComponent.h"
-#include "AliL3ClustFinderNew.h"
-#include "AliL3SpacePointData.h"
+#include "AliHLTTPCClustFinderNew.h"
+#include "AliHLTTPCSpacePointData.h"
#include "AliHLTTPCRawDataFormat.h"
#include "AliHLTTPCClusterDataFormat.h"
-#include "AliL3Transform.h"
+#include "AliHLTTPCTransform.h"
#include <stdlib.h>
#include <errno.h>
{
if ( fClusterFinder )
return EINPROGRESS;
- fClusterFinder = new AliL3ClustFinderNew();
+ fClusterFinder = new AliHLTTPCClustFinderNew();
fClusterDeconv = true;
fXYClusterError = -1;
fZClusterError = -1;
int i = 0;
while ( i < argc )
{
- if ( !strcmp( argv[i], "-pp-run" ) )
+ if ( !strcmp( argv[i], "pp-run" ) )
{
fClusterDeconv = false;
i++;
iter = blocks+ndx;
mysize = 0;
offset = tSize;
+ char tmp1[14], tmp2[14];
+ DataType2Text( iter->fDataType, tmp1 );
+ DataType2Text( AliHLTTPCDefinitions::gkUnpackedRawDataType, tmp2 );
+ Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Event received",
+ "Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
+ evtData.fEventID, evtData.fEventID, tmp1, tmp2 );
if ( iter->fDataType != AliHLTTPCDefinitions::gkUnpackedRawDataType )
continue;
slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
- row[0] = AliL3Transform::GetFirstRow( patch );
- row[1] = AliL3Transform::GetLastRow( patch );
+ row[0] = AliHLTTPCTransform::GetFirstRow( patch );
+ row[1] = AliHLTTPCTransform::GetLastRow( patch );
Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints",
"Input: Number of spacepoints: %lu Slice/Patch/RowMin/RowMax: %d/%d/%d/%d.",
outPtr = (AliHLTTPCClusterData*)outBPtr;
inPtr = (AliHLTTPCUnpackedRawData*)iter->fPtr;
- maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliL3SpacePointData);
+ maxPoints = (size-tSize-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
fClusterFinder->InitSlice( slice, patch, row[0], row[1], maxPoints );
fClusterFinder->SetDeconv( fClusterDeconv );
"Number of spacepoints found: %lu.", realPoints );
outPtr->fSpacePointCnt = realPoints;
- nSize = sizeof(AliL3SpacePointData)*realPoints;
+ nSize = sizeof(AliHLTTPCSpacePointData)*realPoints;
mysize += nSize+sizeof(AliHLTTPCClusterData);
Logging( kHLTLogDebug, "HLT::TPCClusterFinder::DoEvent", "Input Spacepoints",
#include "AliHLTProcessor.h"
#include "AliHLTTPCDefinitions.h"
-class AliL3ClustFinderNew;
+class AliHLTTPCClustFinderNew;
class AliHLTTPCClusterFinderComponent : public AliHLTProcessor
{
private:
- AliL3ClustFinderNew* fClusterFinder;
+ AliHLTTPCClustFinderNew* fClusterFinder;
bool fClusterDeconv;
float fXYClusterError;
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCConfMapFit.h"
+
+/** \class AliHLTTPCConfMapFit
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapFit
+//
+// Fit class for conformal mapping tracking
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapFit)
+
+
+AliHLTTPCConfMapFit::AliHLTTPCConfMapFit(AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex)
+{
+ //constructor
+ fTrack = track;
+ fVertex = vertex;
+}
+
+Int_t AliHLTTPCConfMapFit::FitHelix()
+{
+ //fit the helix
+ if(FitCircle())
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems during circle fit"<<ENDLOG;
+ return 1;
+ }
+ if(FitLine())
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems during line fit"<<ENDLOG;
+ return 1;
+ }
+ return 0;
+}
+
+Int_t AliHLTTPCConfMapFit::FitCircle()
+{
+ //-----------------------------------------------------------------
+ //Fits circle parameters using algorithm
+ //described by ChErnov and Oskov in Computer Physics
+ //Communications.
+ //
+ //Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin
+ //Moved to C by Pablo Yepes
+ //Moved to AliROOT by ASV.
+ //------------------------------------------------------------------
+
+ Double_t wsum = 0.0 ;
+ Double_t xav = 0.0 ;
+ Double_t yav = 0.0 ;
+
+ Int_t num_of_hits = fTrack->GetNumberOfPoints();
+ //
+ // Loop over hits calculating average
+ Int_t co=0;
+
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ co++;
+ AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+ cHit->SetXYWeight( 1./ (Double_t)(cHit->GetXerr()*cHit->GetXerr() + cHit->GetYerr()*cHit->GetYerr()) );
+ wsum += cHit->GetXYWeight() ;
+ xav += cHit->GetXYWeight() * cHit->GetX() ;
+ yav += cHit->GetXYWeight() * cHit->GetY() ;
+ }
+ if(co!=num_of_hits)
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Mismatch of hits. Counter: "<<co<<" nHits: "<<num_of_hits<<ENDLOG;
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ wsum += fVertex->GetXYWeight() ;
+ xav += fVertex->GetX() ;
+ yav += fVertex->GetY() ;
+ }
+
+ xav = xav / wsum ;
+ yav = yav / wsum ;
+//
+// CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
+//
+ Double_t xxav = 0.0 ;
+ Double_t xyav = 0.0 ;
+ Double_t yyav = 0.0 ;
+ Double_t xi, yi ;
+
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint *)hits->At(hit_counter);
+ AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+ xi = cHit->GetX() - xav ;
+ yi = cHit->GetY() - yav ;
+ xxav += xi * xi * cHit->GetXYWeight() ;
+ xyav += xi * yi * cHit->GetXYWeight() ;
+ yyav += yi * yi * cHit->GetXYWeight() ;
+ }
+
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ xi = fVertex->GetX() - xav ;
+ yi = fVertex->GetY() - yav ;
+ xxav += xi * xi * fVertex->GetXYWeight() ;
+ xyav += xi * yi * fVertex->GetXYWeight() ;
+ yyav += yi * yi * fVertex->GetXYWeight() ;
+ }
+ xxav = xxav / wsum ;
+ xyav = xyav / wsum ;
+ yyav = yyav / wsum ;
+//
+//--> ROTATE COORDINATES SO THAT <XY> = 0
+//
+//--> SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
+//--> & > ==> NEW : (XXAV-YYAV) > 0
+//--> SIGN(S) = SIGN(XYAV) >
+
+ Double_t a = fabs( xxav - yyav ) ;
+ Double_t b = 4.0 * xyav * xyav ;
+
+ Double_t asqpb = a * a + b ;
+ Double_t rasqpb = sqrt ( asqpb) ;
+
+ Double_t splus = 1.0 + a / rasqpb ;
+ Double_t sminus = b / (asqpb * splus) ;
+
+ splus = sqrt (0.5 * splus ) ;
+ sminus = sqrt (0.5 * sminus) ;
+//
+//-> FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
+//
+ Double_t sinrot, cosrot ;
+ if ( xxav <= yyav ) {
+ cosrot = sminus ;
+ sinrot = splus ;
+ }
+ else {
+ cosrot = splus ;
+ sinrot = sminus ;
+ }
+//
+//-> REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
+//
+ if ( xyav < 0.0 ) sinrot = - sinrot ;
+//
+//--> WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
+//--> TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
+//--> OUTWARD FROM THE ORGIN. WE ARE FREE TO CHANGE SIGNS OF BOTH
+//--> COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
+//
+//--> CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
+//
+ if ( cosrot*xav+sinrot*yav < 0.0 ) {
+ cosrot = -cosrot ;
+ sinrot = -sinrot ;
+ }
+//
+//-> NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
+//
+ Double_t rrav = xxav + yyav ;
+ Double_t rscale = sqrt(rrav) ;
+
+ xxav = 0.0 ;
+ yyav = 0.0 ;
+ xyav = 0.0 ;
+ Double_t xrrav = 0.0 ;
+ Double_t yrrav = 0.0 ;
+ Double_t rrrrav = 0.0 ;
+
+ Double_t xixi, yiyi, riri, wiriri, xold, yold ;
+
+ //for (hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+ AliHLTTPCConfMapPoint* cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+
+ xold = cHit->GetX() - xav ;
+ yold = cHit->GetY() - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = cHit->GetXYWeight() * riri ;
+
+ xyav += cHit->GetXYWeight() * xi * yi ;
+ xxav += cHit->GetXYWeight() * xixi ;
+ yyav += cHit->GetXYWeight() * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+ //
+// Include vertex if required
+//
+ if (fTrack->ComesFromMainVertex() == true)
+ {
+ xold = fVertex->GetX() - xav ;
+ yold = fVertex->GetY() - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = fVertex->GetXYWeight() * riri ;
+
+ xyav += fVertex->GetXYWeight() * xi * yi ;
+ xxav += fVertex->GetXYWeight() * xixi ;
+ yyav += fVertex->GetXYWeight() * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+ //
+ //
+ //
+ //--> DIVIDE BY WSUM TO MAKE AVERAGES
+ //
+ xxav = xxav / wsum ;
+ yyav = yyav / wsum ;
+ xrrav = xrrav / wsum ;
+ yrrav = yrrav / wsum ;
+ rrrrav = rrrrav / wsum ;
+ xyav = xyav / wsum ;
+
+ Int_t const ntry = 5 ;
+//
+//--> USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
+//--> DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
+//
+ Double_t xrrxrr = xrrav * xrrav ;
+ Double_t yrryrr = yrrav * yrrav ;
+ Double_t rrrrm1 = rrrrav - 1.0 ;
+ Double_t xxyy = xxav * yyav ;
+
+ Double_t c0 = rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
+ Double_t c1 = - rrrrm1 + xrrxrr + yrryrr - 4.0*xxyy ;
+ Double_t c2 = 4.0 + rrrrm1 - 4.0*xxyy ;
+ Double_t c4 = - 4.0 ;
+//
+//--> COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
+//
+ Double_t c2d = 2.0 * c2 ;
+ Double_t c4d = 4.0 * c4 ;
+//
+//--> 0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
+//
+// LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
+ Double_t lamda = 0.0 ;
+ Double_t dlamda = 0.0 ;
+//
+ Double_t chiscl = wsum * rscale * rscale ;
+ Double_t dlamax = 0.001 / chiscl ;
+
+ Double_t p, pd ;
+ for ( int itry = 1 ; itry <= ntry ; itry++ ) {
+ p = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
+ pd = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
+ dlamda = -p / pd ;
+ lamda = lamda + dlamda ;
+ if (fabs(dlamda)< dlamax) break ;
+ }
+
+ Double_t chi2 = (Double_t)(chiscl * lamda) ;
+
+ fTrack->SetChiSq1(chi2);
+ // Double_t dchisq = chiscl * dlamda ;
+//
+//--> NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
+//
+ Double_t h11 = xxav - lamda ;
+ Double_t h14 = xrrav ;
+ Double_t h22 = yyav - lamda ;
+ Double_t h24 = yrrav ;
+ Double_t h34 = 1.0 + 2.0*lamda ;
+ if ( h11 == 0.0 || h22 == 0.0 ){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems fitting circle"<<ENDLOG;
+ return 1 ;
+ }
+ Double_t rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
+
+ Double_t ratio, kappa, beta ;
+ if ( fabs(h22) > fabs(h24) ) {
+ ratio = h24 / h22 ;
+ rootsq = ratio * ratio + rootsq ;
+ kappa = 1.0 / sqrt(rootsq) ;
+ beta = - ratio * kappa ;
+ }
+ else {
+ ratio = h22 / h24 ;
+ rootsq = 1.0 + ratio * ratio * rootsq ;
+ beta = 1.0 / sqrt(rootsq) ;
+ if ( h24 > 0 ) beta = - beta ;
+ kappa = -ratio * beta ;
+ }
+ Double_t alpha = - (h14/h11) * kappa ;
+//
+//--> transform these into the lab coordinate system
+//--> first get kappa and back to real dimensions
+//
+ Double_t kappa1 = kappa / rscale ;
+ Double_t dbro = 0.5 / kappa1 ;
+//
+//--> next rotate alpha and beta and scale
+//
+ Double_t alphar = (cosrot * alpha - sinrot * beta)* dbro ;
+ Double_t betar = (sinrot * alpha + cosrot * beta)* dbro ;
+//
+//--> then translate by (xav,yav)
+//
+ Double_t acent = (double)(xav - alphar) ;
+ Double_t bcent = (double)(yav - betar ) ;
+ Double_t radius = (double)dbro ;
+//
+// Get charge
+//
+ Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
+
+ fTrack->SetCharge(q);
+
+
+ //Set the first point on the track to the space point coordinates of the innermost track
+ //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
+ Double_t x0,y0,psi,pt ;
+ AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fTrack->GetLastHit();
+ x0 = lHit->GetX();
+ y0 = lHit->GetY();
+ fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
+
+ psi = (Double_t)atan2(bcent-y0,acent-x0) ;
+ psi = psi + q * AliHLTTPCTransform::PiHalf();
+ if ( psi < 0 ) psi = psi + AliHLTTPCTransform::TwoPi();
+ pt = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * radius ) ;
+
+ //Update the track parameters with the parameters from this fit:
+ fTrack->SetPsi(psi);
+ fTrack->SetPt(pt);
+ fTrack->SetRadius(radius);
+ fTrack->SetCenterX(acent);
+ fTrack->SetCenterY(bcent);
+
+ //
+// Get errors from fast fit
+//
+ //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+ return 0 ;
+
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliHLTTPCConfMapFit::FitLine ( )
+{
+ //
+ //Initialization
+ //
+ Double_t sum = 0.F ;
+ Double_t ss = 0.F ;
+ Double_t sz = 0.F ;
+ Double_t sss = 0.F ;
+ Double_t ssz = 0.F ;
+ //
+ //find sum , sums ,sumz, sumss
+ //
+ Double_t dx, dy ;
+ Double_t radius = (Double_t)(fTrack->GetPt() / AliHLTTPCTransform::GetBFieldValue() ) ;
+
+ //TObjArray *hits = fTrack->GetHits();
+ //Int_t num_of_hits = fTrack->GetNumberOfPoints();
+
+ if (0)// fTrack->ComesFromMainVertex() == true )
+ {
+ dx = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetX() - fVertex->GetX();
+ dy = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetY() - fVertex->GetY() ;
+ }
+ else
+ {
+ dx = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetX() ;
+ dy = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetY() ;
+ //dx = ((AliHLTTPCConfMapPoint *)hits->First())->GetX() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetX() ;
+ //dy = ((AliHLTTPCConfMapPoint *)hits->First())->GetY() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetY() ;
+ }
+
+ Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
+ Double_t total_s ;
+
+ if ( fabs(localPsi) < 1. )
+ {
+ total_s = 2.0 * radius * asin ( localPsi ) ;
+ }
+ else
+ {
+ total_s = 2.0 * radius * AliHLTTPCTransform::Pi() ;
+ }
+
+ AliHLTTPCConfMapPoint *previousHit = NULL;
+
+ // FtfBaseHit *previousHit = 0 ;
+
+ //for ( startLoop() ; done() ; nextHit() ) {
+ Double_t dpsi,s;
+
+ // for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ // AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+ AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+ // if ( GetCurrentHit() != GetFirstHit() )
+ if(cHit != fTrack->GetFirstHit())// hits->First())
+ {
+ dx = cHit->GetX() - previousHit->GetX() ;
+ dy = cHit->GetY() - previousHit->GetY() ;
+ dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
+ fTrack->SetPsierr(dpsi);
+ s = previousHit->GetS() - 2.0 * radius * (Double_t)asin ( dpsi ) ;
+ cHit->SetS(s);
+ }
+ else
+ cHit->SetS(total_s);
+ // cHit->s = total_s ;
+
+ sum += cHit->GetZWeight() ;
+ ss += cHit->GetZWeight() * cHit->GetS() ;
+ sz += cHit->GetZWeight() * cHit->GetZ() ;
+ sss += cHit->GetZWeight() * cHit->GetS() * cHit->GetS() ;
+ ssz += cHit->GetZWeight() * cHit->GetS() * cHit->GetZ() ;
+ previousHit = cHit ;
+ }
+
+ Double_t chi2,det = sum * sss - ss * ss;
+ if ( fabs(det) < 1e-20)
+ {
+ chi2 = 99999.F ;
+ fTrack->SetChiSq2(chi2);
+ return 0 ;
+ }
+
+ //Compute the best fitted parameters A,B
+ Double_t tanl,z0,dtanl,dz0;
+
+ tanl = (Double_t)((sum * ssz - ss * sz ) / det );
+ z0 = (Double_t)((sz * sss - ssz * ss ) / det );
+
+ fTrack->SetTgl(tanl);
+ fTrack->SetZ0(z0);
+
+ // calculate chi-square
+
+ chi2 = 0.;
+ Double_t r1 ;
+
+ //for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
+ for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
+ {
+ //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
+ AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
+ r1 = cHit->GetZ() - tanl * cHit->GetS() - z0 ;
+ chi2 += (Double_t) ( (Double_t)cHit->GetZWeight() * (r1 * r1) );
+ }
+ fTrack->SetChiSq2(chi2);
+ //
+ // calculate estimated variance
+ // varsq=chi/(double(n)-2.)
+ // calculate covariance matrix
+ // siga=sqrt(varsq*sxx/det)
+ // sigb=sqrt(varsq*sum/det)
+ //
+ dtanl = (Double_t) ( sum / det );
+ dz0 = (Double_t) ( sss / det );
+
+ fTrack->SetTglerr(dtanl);
+ fTrack->SetZ0err(dz0);
+
+ return 0 ;
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_ConfMapFit
+#define ALIHLTTPC_ConfMapFit
+
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapFit {
+
+ private:
+ AliHLTTPCConfMapTrack *fTrack; //!
+ AliHLTTPCVertex *fVertex; //!
+
+ public:
+ AliHLTTPCConfMapFit (AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex);
+ virtual ~AliHLTTPCConfMapFit() {};
+
+ Int_t FitHelix();
+ Int_t FitCircle();
+ Int_t FitLine();
+
+ ClassDef(AliHLTTPCConfMapFit,1) //Conformal mapping fit class
+};
+
+#endif
--- /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::fgDontMap=kFALSE;
+
+AliHLTTPCConfMapPoint::AliHLTTPCConfMapPoint()
+{
+ //Constructor
+
+ SetUsage(false);
+ SetHitNumber(-1);
+ SetX(0);
+ SetY(0);
+ SetZ(0);
+ SetXerr(0);
+ SetYerr(0);
+ SetZerr(0);
+
+ SetPhi(0.);
+ SetEta(0.);
+
+ SetXprime(0.);
+ SetYprime(0.);
+ SetXprimeerr(0.);
+ SetYprimeerr(0.);
+ SetIntPoint(0., 0., 0., 0., 0., 0.);
+ SetShiftedCoord();
+ SetMCTrackID(0,0,0);
+}
+
+AliHLTTPCConfMapPoint::~AliHLTTPCConfMapPoint()
+{
+ // Destructor.
+ ;
+}
+
+Bool_t AliHLTTPCConfMapPoint::ReadHits(AliHLTTPCSpacePointData* hits )
+{
+ //read the hits
+ SetHitNumber(hits->fID);
+ SetPadRow(hits->fPadRow);
+ Int_t slice = (hits->fID>>25) & 0x7f;
+ SetSector(slice);
+ SetX(hits->fX);
+ SetY(hits->fY);
+ SetZ(hits->fZ);
+ SetXerr(sqrt(hits->fSigmaY2));
+ SetYerr(sqrt(hits->fSigmaY2));
+ SetZerr(sqrt(hits->fSigmaZ2));
+ return kTRUE;
+}
+
+void AliHLTTPCConfMapPoint::Reset()
+{
+ //Reset this point.
+ SetUsage(kFALSE);
+ SetS(0);
+ fNextRowHit = 0;
+ fNextVolumeHit=0;
+ fNextTrackHit=0;
+}
+
+void AliHLTTPCConfMapPoint::Setup(AliHLTTPCVertex *vertex)
+{
+ //Setup. Sets the vertex, conformal coordinates,
+ //and phi and eta of each hit.
+
+ SetIntPoint(vertex->GetX(), vertex->GetY(), vertex->GetZ(),
+ vertex->GetXErr(), vertex->GetYErr(), vertex->GetZErr());
+ SetShiftedCoord();
+ SetConfCoord();
+ // The angles are set properly if they are set after
+ // the interaction point and the shifted coordinates
+ SetAngles();
+ //SetDist(0., 0.);
+ return;
+}
+
+void AliHLTTPCConfMapPoint::SetIntPoint(Double_t inx, Double_t iny, Double_t inz,
+ Double_t inxerr, Double_t inyerr, Double_t inzerr)
+{
+ // Defines a new interaction point. This point is needed to calculate
+ // the conformal coordinates.
+
+ SetXt(inx);
+ SetYt(iny);
+ SetZt(inz);
+ SetXterr(inxerr);
+ SetYterr(inyerr);
+ SetZterr(inzerr);
+
+ return;
+}
+
+void AliHLTTPCConfMapPoint::SetAllCoord(const AliHLTTPCConfMapPoint *precedinghit)
+{
+ // Sets the interaction point, the shifted coordinates, and the conformal mapping coordinates.
+ // These values are calculated from the interaction point of the given cluster which should be a
+ // already found cluster on the same track.
+
+ if (this == precedinghit) {
+ SetIntPoint(precedinghit->GetX(), precedinghit->GetY(), precedinghit->GetZ(),
+ precedinghit->GetXerr(), precedinghit->GetYerr(), precedinghit->GetZerr());
+ }
+
+ else {
+ SetIntPoint(precedinghit->GetXt(), precedinghit->GetYt(), precedinghit->GetZt(),
+ precedinghit->GetXterr(), precedinghit->GetYterr(), precedinghit->GetZterr());
+ }
+
+ SetShiftedCoord();
+ SetConfCoord();
+
+ return;
+}
+
+void AliHLTTPCConfMapPoint::SetShiftedCoord()
+{
+ // Sets the coordinates with resepct to the given vertex point
+
+ SetXv(GetX() - fXt);
+ SetYv(GetY() - fYt);
+ SetZv(GetZ() - fZt);
+ /*
+ SetXverr(TMath::Sqrt(GetXerr()*GetXerr() + fXterr*fXterr));
+ SetYverr(TMath::Sqrt(GetYerr()*GetYerr() + fYterr*fYterr));
+ SetZverr(TMath::Sqrt(GetZerr()*GetZerr() + fZterr*fZterr));
+ */
+ return;
+}
+
+void AliHLTTPCConfMapPoint::SetConfCoord()
+{
+ // Calculates the conformal coordinates of one cluster.
+ // If the option "vertex_constraint" applies the interaction point is
+ // assumed to be at (0, 0, 0). Otherwise the function will use the
+ // interaction point specified by fXt and fYt.
+
+ if(fgDontMap){
+ fXprime = fx;
+ fYprime = fy;
+ fWxy = 0;
+ fs = 0; //track trajectory
+ fWz = 0;
+ return;
+ }
+
+ Double_t r2;
+ Double_t xyErrorScale = 1;
+ Double_t szErrorScale = 1;
+
+ if ((r2 = fXv*fXv + fYv*fYv))
+ {
+ fXprime = fXv / r2;
+ fYprime = -fYv / r2;
+
+ //set weights:
+ fWxy = r2*r2 / ((xyErrorScale*xyErrorScale)*((fxerr*fxerr)+(fyerr*fyerr)));
+ fs = 0; //track trajectory
+ fWz = (Double_t)(1./(szErrorScale*fzerr*fzerr));
+ } else {
+ fXprime = 0.;
+ fYprime = 0.;
+ fXprimeerr = 0.;
+ fYprimeerr = 0.;
+ fWxy = 0;
+ fWz = 0;
+ fs = 0;
+ }
+
+ return;
+}
+
+void AliHLTTPCConfMapPoint::SetAngles()
+{
+ // Calculates the angle phi and the pseudorapidity eta for each cluster.
+ /*
+ Double_t r = TMath::Sqrt(x*x + y*y);
+
+ fPhi = TMath::ATan2(y,x);
+ if(fPhi<0) fPhi = fPhi + 2*TMath::Pi();
+ fEta = 3.*z/(TMath::Abs(z)+2.*r);
+ return;
+ */
+ // Double_t r3dim = TMath::Sqrt(fXv*fXv + fYv*fYv + fZv*fZv);
+ Double_t r3dim = sqrt(fXv*fXv + fYv*fYv + fZv*fZv);
+ //Double_t r2dim = TMath::Sqrt(fXv*fXv + fYv*fYv);
+
+ /*if (r2dim == 0.) {
+ // If r2dim == 0 the pseudorapidity eta cannot be calculated (division by zero)!
+ // This can only happen if the point is lying on the z-axis and this should never be possible.
+ cerr << "The pseudorapidity eta cannot be calculated (division by zero)! Set to 1.e-10." << endl;
+ r2dim = 1.e-10;
+ }
+
+ if (fXv == 0.) {
+ fPhi = (fYv > 0.) ? TMath::Pi() / 2. : - TMath::Pi() / 2.;
+ }
+
+ else {
+ fPhi = (fXv > 0.) ? TMath::ASin(fYv/r2dim) : TMath::Pi() - TMath::ASin(fYv/r2dim);
+ }
+
+ if (fPhi < 0.) {
+ fPhi += 2. * TMath::Pi();
+ }
+ */
+ //fPhi = TMath::ATan2(y,x);
+ fPhi = atan2(fy,fx);
+ //if(fPhi<0) fPhi = fPhi + 2*TMath::Pi();
+
+ //fEta = 0.5 * TMath::Log((r3dim + fZv)/(r3dim - fZv));
+ fEta = 0.5 * log((r3dim + fZv)/(r3dim - fZv));
+ return;
+}
+
+/*
+AliHLTTPCConfMapTrack *AliHLTTPCConfMapPoint::GetTrack(TClonesArray *tracks) const
+{
+ // Returns the pointer to the track to which this hit belongs.
+
+ return (AliHLTTPCConfMapTrack*)tracks->At(this->GetTrackNumber());
+}
+*/
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCConfMapPointH
+#define ALIHLTTPCConfMapPointH
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+
+class AliHLTTPCConfMapPoint {
+
+ private:
+
+ Int_t fHitNumber; //hit number
+ Int_t fTrackNumber; //track number
+ Int_t fNextHitNumber; //next hit number
+ Bool_t fUsed; //flag is used
+ Int_t fPadrow; //padrow
+ Int_t fSector; //sector
+
+ //global coordinates and their errors
+ Double_t fx; //glob x
+ Double_t fy; //glob y
+ Double_t fz; //glob z
+ Double_t fxerr; //glob xerr
+ Double_t fyerr; //glob yerr
+ Double_t fzerr; //glob zerr
+
+ Double_t fWxy; // x-y weight on x-y
+ Double_t fWz; // z weight on z
+ Float_t fs; //track trajectory
+
+ // Interaction point
+ Double_t fXt; // x-value of the interaction point
+ Double_t fYt; // y-value of the interaction point
+ Double_t fZt; // z-value of the interaction point
+
+ Double_t fXterr; // error of mXt
+ Double_t fYterr; // error of mYt
+ Double_t fZterr; // error of mZt
+
+ // conformal mapping coordinates
+ Double_t fXprime; // transformed x
+ Double_t fYprime; // transformed y
+
+ Double_t fXprimeerr; // error of mXprime
+ Double_t fYprimeerr; // error of mYprime
+
+ // coordinates with respect to the vertex
+
+ // cartesian coordinates
+ Double_t fXv; // x with respect to vertex
+ Double_t fYv; // y with respect to vertex
+ Double_t fZv; // z with respect to vertex
+
+ Double_t fXverr; // error of mXv
+ Double_t fYverr; // error of mYv
+ Double_t fZverr; // error of mZv
+
+ // spherical coordinates
+ Double_t fPhi; // angle phi
+ Double_t fEta; // pseudorapidity
+
+ AliHLTTPCConfMapPoint *fNextVolumeHit; //!
+ AliHLTTPCConfMapPoint *fNextRowHit; //!
+ AliHLTTPCConfMapPoint *fNextTrackHit; //! Linked chain of points in a track
+ Short_t fPhiIndex; //phi index
+ Short_t fEtaIndex; //eta index
+ Double_t fXYChi2; //xy chi
+ Double_t fSZChi2; //z chi
+ Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+ static Bool_t fgDontMap; //flag to switch off mapping
+
+ public:
+
+ AliHLTTPCConfMapPoint();
+ virtual ~AliHLTTPCConfMapPoint();
+
+ void Reset();
+ Bool_t ReadHits(AliHLTTPCSpacePointData* hits );
+
+ // getter
+ Double_t GetX() const {return fx;}
+ Double_t GetY() const {return fy;}
+ Double_t GetZ() const {return fz;}
+ Double_t GetXerr() const {return fxerr;}
+ Double_t GetYerr() const {return fyerr;}
+ Double_t GetZerr() const {return fzerr;}
+ Int_t GetPadRow() const {return fPadrow;}
+ Int_t GetSector() const {return fSector;}
+
+ Double_t GetXYWeight() const {return fWxy;}
+ Double_t GetZWeight() const {return fWz;}
+ Float_t GetS() const {return fs;}
+
+ Bool_t GetUsage() const {return fUsed;}
+ Double_t GetPhi() const {return fPhi;}
+ Double_t GetEta() const {return fEta;}
+
+ Double_t GetXprime() const {return fXprime;}
+ Double_t GetYprime() const {return fYprime;}
+ Double_t GetXprimeerr() const {return fXprimeerr;}
+ Double_t GetYprimeerr() const {return fYprimeerr;}
+
+ Double_t GetXt() const {return fXt;}
+ Double_t GetYt() const {return fYt;}
+ Double_t GetZt() const {return fZt;}
+ Double_t GetXterr() const {return fXterr;}
+ Double_t GetYterr() const {return fYterr;}
+ Double_t GetZterr() const {return fZterr;}
+
+ Double_t GetXv() const {return fXv;}
+ Double_t GetYv() const {return fYv;}
+ Double_t GetZv() const {return fZv;}
+ Double_t GetXverr() const {return fXverr;}
+ Double_t GetYverr() const {return fYverr;}
+ Double_t GetZverr() const {return fZverr;}
+
+ Int_t GetHitNumber() const {return fHitNumber;}
+ Int_t GetNextHitNumber() const {return fNextHitNumber;}
+ Int_t GetTrackNumber() const {return fTrackNumber;}
+ //Int_t const *GetMCTrackID() const {return fMCTrackID;}
+
+ AliHLTTPCConfMapPoint* GetNextVolumeHit(){return fNextVolumeHit;}
+ AliHLTTPCConfMapPoint* GetNextRowHit(){return fNextRowHit;}
+ AliHLTTPCConfMapPoint* GetNextTrackHit(){return fNextTrackHit;}
+ Short_t GetPhiIndex() const {return fPhiIndex;}
+ Short_t GetEtaIndex() const {return fEtaIndex;}
+ Double_t GetXYChi2() const {return fXYChi2;}
+ Double_t GetSZChi2() const {return fSZChi2;}
+ //Int_t fMCTrackID[3]; //MClabel of tracks, may overlap
+
+ // setter
+ void SetNextVolumeHit(AliHLTTPCConfMapPoint* p){fNextVolumeHit=p;}
+ void SetNextRowHit(AliHLTTPCConfMapPoint* p){fNextRowHit=p;}
+ void SetNextTrackHit(AliHLTTPCConfMapPoint* p){fNextTrackHit=p;}
+
+ void SetPhiIndex(Short_t p){fPhiIndex=p;}
+ void SetEtaIndex(Short_t p){fEtaIndex=p;}
+ void SetXYChi2(Double_t d) {fXYChi2=d;}
+ void SetSZChi2(Double_t d) {fSZChi2=d;}
+
+ static void SetDontMap(Bool_t b){fgDontMap=b;}
+
+ void SetX(Double_t f){fx=f;}
+ void SetY(Double_t f){fy=f;}
+ void SetZ(Double_t f){fz=f;}
+ void SetXerr(Double_t f){fxerr=f;}
+ void SetYerr(Double_t f){fyerr=f;}
+ void SetZerr(Double_t f){fzerr=f;}
+ void SetPadRow(Int_t f){fPadrow=f;}
+ void SetSector(Int_t f){fSector=f;}
+ void SetMCTrackID(Int_t f,Int_t g,Int_t h){fMCTrackID[0] = f; fMCTrackID[1]=g; fMCTrackID[2]=h;}
+
+ void SetXYWeight(Float_t f){fWxy = f;}
+ void SetZWeight(Float_t f){fWz = f;}
+ void SetS(Float_t f){fs = f;}
+ void SetUsage(Bool_t f){fUsed=f;}
+ void SetPhi(Double_t f ){fPhi = f;}
+ void SetEta(Double_t f){fEta = f;}
+ void SetXprime(Double_t f){fXprime = f;}
+ void SetYprime(Double_t f){fYprime = f;}
+ void SetXprimeerr(Double_t f){fXprimeerr = f;}
+ void SetYprimeerr(Double_t f){fYprimeerr = f;}
+ void SetXt(Double_t f){fXt = f;}
+ void SetYt(Double_t f){fYt = f;}
+ void SetZt(Double_t f){fZt = f;}
+ void SetXterr(Double_t f){fXterr = f;}
+ void SetYterr(Double_t f){fYterr = f;}
+ void SetZterr(Double_t f){fZterr = f;}
+ void SetXv(Double_t f){fXv = f;}
+ void SetYv(Double_t f){fYv = f;}
+ void SetZv(Double_t f){fZv = f;}
+ void SetXverr(Double_t f){fXverr = f;}
+ void SetYverr(Double_t f){fYverr = f;}
+ void SetZverr(Double_t f){fZverr = f;}
+ void SetHitNumber(Int_t f){fHitNumber=f;}
+ void SetTrackNumber(Int_t f){fTrackNumber=f;}
+ void SetNextHitNumber(Int_t f){fNextHitNumber=f;}
+
+ void Setup(AliHLTTPCVertex *vertex);// does the usual setup in the right order
+ void SetAngles(); // calculate spherical angles and set values
+ void SetIntPoint(Double_t inx = 0., Double_t iny = 0.,
+ Double_t inz = 0., Double_t inxerr = 0.,
+ Double_t inyerr = 0., Double_t inzerr = 0.);
+ //-> set interaction point
+ void SetShiftedCoord();// set shifted coordinates
+ void SetAllCoord(const AliHLTTPCConfMapPoint *hit);// set conformal mapping coordinates in respect to given hit
+ void SetConfCoord();// conformal mapping
+
+ ClassDef(AliHLTTPCConfMapPoint, 1) //Conformal mapping hit class.
+};
+
+#endif
--- /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>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapTrack)
+
+
+AliHLTTPCConfMapTrack::AliHLTTPCConfMapTrack()
+{
+ //Constructor
+ fChiSq[0] = 0.;
+ fChiSq[1] = 0.;
+}
+
+AliHLTTPCConfMapTrack::~AliHLTTPCConfMapTrack()
+{
+ //deconstructor
+}
+
+void AliHLTTPCConfMapTrack::DeleteCandidate()
+{
+ //Deletes this track by resetting all its parameters. Does not delete
+ //the object itself.
+
+ AliHLTTPCConfMapPoint *curHit = (AliHLTTPCConfMapPoint*)fFirstHit;
+ AliHLTTPCConfMapPoint *nextHit;
+
+ while(curHit != 0)
+ {
+ nextHit = (AliHLTTPCConfMapPoint*)curHit->GetNextTrackHit();
+ curHit->SetNextTrackHit(0);
+ curHit = nextHit;
+ }
+
+ UInt_t *hit_numbers = GetHitNumbers();
+ for(Int_t i=0; i<GetNHits(); i++)
+ {
+ //fHitNumbers[i] = 0;
+ hit_numbers[i]=0;
+ }
+
+ SetRadius(0.);
+ SetCenterX(0.);
+ SetCenterY(0.);
+
+ ComesFromMainVertex(false);
+
+ SetNHits(0);
+ SetCharge(0);
+ fChiSq[0] = 0.;
+ fChiSq[1] = 0.;
+}
+
+
+void AliHLTTPCConfMapTrack::SetProperties(Bool_t usage)
+{
+ //Set the hits to this track to 'usage'
+ for(StartLoop(); LoopDone(); GetNextHit())
+ {
+ AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)fCurrentHit;
+ p->SetUsage(usage);
+ }
+ return;
+}
+
+void AliHLTTPCConfMapTrack::Reset()
+{
+ //Resets the fit parameters of this track.
+
+ //xy-plane
+ fs11Xy = 0;
+ fs12Xy = 0;
+ fs22Xy = 0;
+ fg1Xy = 0;
+ fg2Xy = 0;
+ fChiSq[0] = 0.;
+
+ //sz-plane
+ fs11Sz = 0;
+ fs12Sz = 0;
+ fs22Sz = 0;
+ fg1Sz = 0;
+ fg2Sz = 0;
+ fChiSq[1] = 0;
+ SetLength(0);
+ SetNHits(0);
+}
+
+void AliHLTTPCConfMapTrack::UpdateParam(AliHLTTPCConfMapPoint *thisHit)
+{
+ //Function to update fit parameters of track
+ //Also, it updates the hit pointers.
+
+
+ //Increment the number of hits assigned to this track:
+
+ //fNHits++;
+ Int_t nhits = GetNHits();
+ nhits++;
+ SetNHits(nhits); //SetNHits(nhits++);
+
+ //Set the hit pointers:
+ //if(fNHits == 1)
+ if(GetNHits()==1)
+ fFirstHit = thisHit;
+ else
+ ((AliHLTTPCConfMapPoint*)fLastHit)->SetNextTrackHit(thisHit);
+ fLastHit = thisHit;
+
+
+ fs11Xy = fs11Xy + thisHit->GetXYWeight() ;
+ fs12Xy = fs12Xy + thisHit->GetXYWeight() * thisHit->GetXprime() ;
+ fs22Xy = fs22Xy + thisHit->GetXYWeight() * pow((thisHit->GetXprime()),2) ;
+ fg1Xy = fg1Xy + thisHit->GetXYWeight() * thisHit->GetYprime() ;
+ fg2Xy = fg2Xy + thisHit->GetXYWeight() * thisHit->GetXprime() * thisHit->GetYprime() ;
+
+ fddXy = fs11Xy * fs22Xy - pow((fs12Xy),2) ;
+ if ( fddXy != 0 )
+ {
+ fa1Xy = ( fg1Xy * fs22Xy - fg2Xy * fs12Xy ) / fddXy ;
+ fa2Xy = ( fg2Xy * fs11Xy - fg1Xy * fs12Xy ) / fddXy ;
+ }
+
+ // Now in the sz plane
+ fs11Sz = fs11Sz + thisHit->GetZWeight() ;
+ fs12Sz = fs12Sz + thisHit->GetZWeight() * thisHit->GetS() ;
+ fs22Sz = fs22Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetS() ;
+ fg1Sz = fg1Sz + thisHit->GetZWeight() * thisHit->GetZ() ;
+ fg2Sz = fg2Sz + thisHit->GetZWeight() * thisHit->GetS() * thisHit->GetZ() ;
+
+
+ fddSz = fs11Sz * fs22Sz - fs12Sz * fs12Sz ;
+ if ( fddSz != 0 ) {
+ fa1Sz = ( fg1Sz * fs22Sz - fg2Sz * fs12Sz ) / fddSz ;
+ fa2Sz = ( fg2Sz * fs11Sz - fg1Sz * fs12Sz ) / fddSz ;
+ }
+}
+
+
+void AliHLTTPCConfMapTrack::Fill(AliHLTTPCVertex *vertex,Double_t max_Dca)
+{
+ //Fill track variables with or without fit.
+
+ //fRadius = sqrt(fa2Xy*fa2Xy+1)/(2*fabs(fa1Xy));
+ Double_t radius = sqrt(fa2Xy*fa2Xy+1)/(2*fabs(fa1Xy));
+ SetRadius(radius);
+
+ //fPt = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * fRadius);
+ Double_t pt = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * GetRadius());
+ SetPt(pt);
+
+ if(GetPt() > max_Dca) //go for fit of helix in real space
+ {
+ AliHLTTPCConfMapFit *fit = new AliHLTTPCConfMapFit(this,vertex);
+ ComesFromMainVertex(AliHLTTPC::DoVertexFit());
+ fit->FitHelix();
+
+ //AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fLastHit;
+ AliHLTTPCConfMapPoint *fHit = (AliHLTTPCConfMapPoint*)fFirstHit;
+ SetLastPoint(fHit->GetX(),fHit->GetY(),fHit->GetZ());
+
+ UpdateToFirstPoint();
+
+ delete fit;
+ }
+ else if(GetPt() == 0)
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapTrack::Fill","Tracks")<<AliHLTTPCLog::kDec<<
+ "Found track with Pt=0!!!"<<ENDLOG;
+ else
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapTrack::Fill","Tracks")<<AliHLTTPCLog::kDec<<
+ "Track with pt<max_Dca :"<<GetPt()<<ENDLOG;
+ }
+}
+
+Int_t AliHLTTPCConfMapTrack::GetMCLabel()
+{
+ //For evaluation study.
+ //Returns the MCtrackID of the belonging clusters.
+ //If MCLabel < 0, means that track is fake.
+
+ return 0;
+ /*
+ Int_t num_of_clusters = GetNumberOfPoints();
+ S *s=new S[num_of_clusters];
+ Int_t i;
+ for (i=0; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
+
+ Int_t lab=123456789;
+ for (i=0; i<num_of_clusters; i++) {
+ AliHLTTPCConfMapPoint *c=(AliHLTTPCConfMapPoint*)fPoints->UncheckedAt(i);
+ lab=fabs(c->fMCTrackID[0]);
+ Int_t j;
+ for (j=0; j<num_of_clusters; j++)
+ if (s[j].lab==lab || s[j].max==0) break;
+ s[j].lab=lab;
+ s[j].max++;
+ }
+
+ Int_t max=0;
+ for (i=0; i<num_of_clusters; i++)
+ if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
+
+ delete[] s;
+
+ for (i=0; i<num_of_clusters; i++) {
+ AliHLTTPCConfMapPoint *c=(AliHLTTPCConfMapPoint*)fPoints->UncheckedAt(i);
+ if (fabs(c->fMCTrackID[1]) == lab ||
+ fabs(c->fMCTrackID[2]) == lab ) max++;
+ }
+
+ //check if more than 10% of the clusters are incorrectly assigned (fake track):
+
+ if (1.-Float_t(max)/num_of_clusters > 0.10)
+ {
+ return -lab;
+ }
+ Int_t tail=Int_t(0.08*174);
+ if (num_of_clusters < tail) return lab;
+
+ max=0;
+ for (i=1; i<=tail; i++) {
+ AliHLTTPCConfMapPoint *c = (AliHLTTPCConfMapPoint*)fPoints->UncheckedAt(num_of_clusters-i);
+ if (lab == fabs(c->fMCTrackID[0]) ||
+ lab == fabs(c->fMCTrackID[1]) ||
+ lab == fabs(c->fMCTrackID[2])) max++;
+ }
+ if (max < Int_t(0.5*tail))
+ {
+ //printf("Wrong innermost clusters\n");
+ return -lab;
+ }
+ return lab;
+ */
+}
+
--- /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 {
+
+ public:
+
+ AliHLTTPCConfMapTrack();
+ virtual ~AliHLTTPCConfMapTrack();
+ void Fill(AliHLTTPCVertex *vertex,Double_t max_Dca);
+ void Reset();
+ void UpdateParam(AliHLTTPCConfMapPoint *hit);
+ void DeleteCandidate();
+
+ void StartLoop() {fCurrentHit = fFirstHit;}
+ void GetNextHit() {fCurrentHit = ((AliHLTTPCConfMapPoint*)fCurrentHit)->GetNextTrackHit();}
+ Int_t LoopDone() const {return fCurrentHit != 0;}
+
+ // setter
+ void SetChiSq1(Double_t f) {fChiSq[0]=f;}
+ void SetChiSq2(Double_t f) {fChiSq[1]=f;}
+ void SetProperties(Bool_t fUsage);
+
+ // getter
+ Double_t const *GetChiSq() const { return fChiSq;}
+ Double_t GetChiSq1() const { return fChiSq[0]; }
+ Double_t GetChiSq2() const { return fChiSq[1]; }
+
+ /*
+ Double_t GetS11Xy() const {return fs11Xy;}
+ Double_t GetS12Xy() const {return fs12Xy;}
+ Double_t GetS22Xy() const {return fs22Xy;}
+ Double_t GetG1Xy() const {return fg1Xy;}
+ Double_t GetG2Xy() const {return fg2Xy;}
+ Double_t GetS11Sz() const {return fs11Sz;}
+ Double_t GetS12Sz() const {return fs12Sz;}
+ Double_t GetS22z() const {return fs22Sz;}
+ Double_t GetG1Sz() const {return fg1Sz;}
+ Double_t GetG2Sz() const { return fg2Sz;}
+ */
+
+ Double_t GetDDXy() const {return fddXy;}
+ Double_t GetA1Xy() const {return fa1Xy;}
+ Double_t GetA2Xy() const {return fa2Xy;}
+ Double_t GetDDSz() const {return fddSz;}
+ Double_t GetA1Sz() const {return fa1Sz;}
+ Double_t GetA2Sz() const {return fa2Sz;}
+
+ AliHLTTPCConfMapPoint* GetFirstHit() const {return fFirstHit;}
+ AliHLTTPCConfMapPoint* GetLastHit() const {return fLastHit;}
+ AliHLTTPCConfMapPoint* GetCurrentHit() const {return fCurrentHit;}
+ Int_t GetMCLabel();
+
+ protected:
+
+ AliHLTTPCConfMapPoint *fCurrentHit; //!
+ AliHLTTPCConfMapPoint *fLastHit; //!
+ AliHLTTPCConfMapPoint *fFirstHit; //!
+
+
+ Double_t fChiSq[2]; //chi squared
+
+ //fit parameters. Bad naming convention, i know...
+ Double_t fs11Xy; //helper
+ Double_t fs12Xy; //helper
+ Double_t fs22Xy; //helper
+ Double_t fg1Xy; //helper
+ Double_t fg2Xy; //helper
+ Double_t fs11Sz; //helper
+ Double_t fs12Sz; //helper
+ Double_t fs22Sz; //helper
+ Double_t fg1Sz; //helper
+ Double_t fg2Sz; //helper
+
+ Double_t fddXy, fa1Xy, fa2Xy ; /*fit par in xy */
+ Double_t fddSz, fa1Sz, fa2Sz ; /*fit par in sz */
+
+ ClassDef(AliHLTTPCConfMapTrack,1) //Conformal mapping track class
+};
+
+#endif
+
--- /dev/null
+// @(#) $Id$
+
+/** \class AliHLTTPCConfMapper
+<pre>
+//_____________________________________________________________
+// AliHLTTPCConfMapper
+//
+// Conformal mapping base class
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+// Copyright © ALICE HLT Group
+</pre>
+*/
+
+#include <sys/time.h>
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCConfMapTrack.h"
+#include "AliHLTTPCConfMapPoint.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCConfMapper.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCConfMapper)
+
+AliHLTTPCConfMapper::AliHLTTPCConfMapper()
+{
+ //Default constructor
+ fVertex = NULL;
+ fTrack = NULL;
+ fHit = NULL;
+ fVolume = NULL;
+ fRow = NULL;
+ fBench = (Bool_t)true;
+ fVertexConstraint = (Bool_t)true;
+ fParamSet[0]=0;
+ fParamSet[1]=0;
+}
+
+
+AliHLTTPCConfMapper::~AliHLTTPCConfMapper()
+{
+ // Destructor.
+ if(fVolume) {
+ delete [] fVolume;
+ }
+ if(fRow) {
+ delete [] fRow;
+ }
+ if(fHit) {
+ delete [] fHit;
+ }
+ if(fTrack) {
+ delete fTrack;
+ }
+}
+
+void AliHLTTPCConfMapper::InitVolumes()
+{
+ //Data organization.
+ //Allocate volumes, set conformal coordinates and pointers.
+
+ //Should be done after setting the track parameters
+
+ fNumRowSegmentPlusOne = AliHLTTPCTransform::GetNRows();//NumRows[0]; //Maximum 32.
+ fNumPhiSegmentPlusOne = fNumPhiSegment+1;
+ fNumEtaSegmentPlusOne = fNumEtaSegment+1;
+ fNumPhiEtaSegmentPlusOne = fNumPhiSegmentPlusOne*fNumEtaSegmentPlusOne;
+ fBounds = fNumRowSegmentPlusOne * fNumPhiSegmentPlusOne * fNumEtaSegmentPlusOne;
+
+ //Allocate volumes:
+ if(fVolume) delete [] fVolume;
+ if(fRow) delete [] fRow;
+
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
+ "Allocating "<<fBounds*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fVolume"<<ENDLOG;
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitVolumes","Memory")<<AliHLTTPCLog::kDec<<
+ "Allocating "<<fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer)<<" Bytes to fRow"<<ENDLOG;
+
+ fVolume = new AliHLTTPCConfMapContainer[fBounds];
+ fRow = new AliHLTTPCConfMapContainer[fNumRowSegmentPlusOne];
+
+ memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
+ memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
+
+ Int_t maxnumoftracks = 2000;
+ Int_t maxnumofhits = 120000;
+
+ if(fHit)
+ delete [] fHit;
+ if(fTrack)
+ delete fTrack;
+
+ fHit = new AliHLTTPCConfMapPoint[maxnumofhits];
+ fTrack = new AliHLTTPCTrackArray("AliHLTTPCConfMapTrack",maxnumoftracks);
+}
+
+void AliHLTTPCConfMapper::InitSector(Int_t sector,Int_t *rowrange,Float_t *etarange)
+{ //sector means slice here
+ //Initialize tracker for tracking in a given sector.
+ //Resets track and hit arrays.
+ //Here it is also possible to specify a subsector, by defining
+ //rowrange[0]=innermost row;
+ //rowrange[1]=outermostrow;
+ //Finally you can specify etaslices to save time (assuming a good seed from TRD...)
+
+ //Define tracking area:
+ if(rowrange)
+ {
+ fRowMin = rowrange[0];
+ fRowMax = rowrange[1];
+ }
+ else //complete sector
+ {
+ fRowMin = 0;
+ fRowMax = AliHLTTPCTransform::GetNRows() - 1;
+ }
+ if(etarange)
+ {
+ fEtaMin = etarange[0];
+ fEtaMax = sector < 18 ? etarange[1] : -etarange[1];
+ }
+ else
+ {
+ fEtaMin = 0;
+ fEtaMax = sector < 18 ? 0.9 : -0.9;
+ }
+
+ //Set the angles to sector 2:
+ fPhiMin = -10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) - 10/todeg;
+ fPhiMax = 10*AliHLTTPCTransform::ToRad();//fParam->GetAngle(sector) + 10/todeg;
+
+ fNTracks=0;
+ fMainVertexTracks = 0;
+ fClustersUnused = 0;
+ fEtaHitsOutOfRange=0;
+ fPhiHitsOutOfRange=0;
+
+ fNumRowSegment = fRowMax - fRowMin; //number of rows to be considered by tracker
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::InitSector","B-field")
+ <<"Tracker initializing with a magnetic field of "<<AliHLTTPCTransform::GetBField()<<ENDLOG;
+
+ fTrack->Reset();
+}
+
+Bool_t AliHLTTPCConfMapper::ReadHits(UInt_t count, AliHLTTPCSpacePointData* hits )
+{
+ //read hits
+ Int_t nhit=(Int_t)count;
+ for (Int_t i=0;i<nhit;i++)
+ {
+ fHit[i].Reset();
+ fHit[i].ReadHits(&(hits[i]));
+ }
+ fClustersUnused += nhit;
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::ReadHits","#hits")
+ <<AliHLTTPCLog::kDec<<"hit_counter: "<<nhit<<" count: "<<count<<ENDLOG;
+
+ return true;
+}
+
+void AliHLTTPCConfMapper::SetPointers()
+{
+ //Check if there are not enough clusters to make a track in this sector
+ //Can happen in pp events.
+
+ if(fClustersUnused < fMinPoints[fVertexConstraint])
+ return;
+
+ //Reset detector volumes
+ memset(fVolume,0,fBounds*sizeof(AliHLTTPCConfMapContainer));
+ memset(fRow,0,fNumRowSegmentPlusOne*sizeof(AliHLTTPCConfMapContainer));
+
+ Float_t phiSlice = (fPhiMax-fPhiMin)/fNumPhiSegment;
+ Float_t etaSlice = (fEtaMax-fEtaMin)/fNumEtaSegment;
+
+ Int_t volumeIndex;
+ Int_t localcounter=0;
+ for(Int_t j=0; j<fClustersUnused; j++)
+ {
+ //AliHLTTPCConfMapPoint *thisHit = (AliHLTTPCConfMapPoint*)fHit->At(j);
+ AliHLTTPCConfMapPoint *thisHit = &(fHit[j]);
+
+ thisHit->Setup(fVertex);
+
+ Int_t localrow = thisHit->GetPadRow();
+
+ if(localrow < fRowMin || localrow > fRowMax)
+ continue;
+
+ //Get indexes:
+ thisHit->SetPhiIndex((Int_t)((thisHit->GetPhi()-fPhiMin)/phiSlice +1));
+
+ if(thisHit->GetPhiIndex()<1 || thisHit->GetPhiIndex()>fNumPhiSegment)
+ {
+ //cout << "Phiindex: " << thisHit->phiIndex << " " << thisHit->GetPhi() << endl;
+ fPhiHitsOutOfRange++;
+ continue;
+ }
+
+ thisHit->SetEtaIndex((Int_t)((thisHit->GetEta()-fEtaMin)/etaSlice + 1));
+ if(thisHit->GetEtaIndex()<1 || thisHit->GetEtaIndex()>fNumEtaSegment)
+ {
+ //cout << "Etaindex: " << thisHit->etaIndex << " " << thisHit->GetEta() << endl;
+ fEtaHitsOutOfRange++;
+ continue;
+ }
+ localcounter++;
+
+ volumeIndex = (localrow-fRowMin)*fNumPhiEtaSegmentPlusOne +
+ thisHit->GetPhiIndex()*fNumEtaSegmentPlusOne+thisHit->GetEtaIndex();
+
+ if(fVolume[volumeIndex].first == NULL)
+ fVolume[volumeIndex].first = (void *)thisHit;
+ else
+ ((AliHLTTPCConfMapPoint *)fVolume[volumeIndex].last)->SetNextVolumeHit(thisHit);
+ fVolume[volumeIndex].last = (void *)thisHit;
+
+
+ //set row pointers
+ if(fRow[(localrow-fRowMin)].first == NULL)
+ fRow[(localrow-fRowMin)].first = (void *)thisHit;
+ else
+ ((AliHLTTPCConfMapPoint *)(fRow[(localrow-fRowMin)].last))->SetNextRowHit(thisHit);
+ fRow[(localrow-fRowMin)].last = (void *)thisHit;
+ }
+
+ if(fClustersUnused>0 && localcounter==0)
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::SetPointers","Parameters")
+ <<AliHLTTPCLog::kDec<<"No points passed to track finder, hits out of range: "
+ <<fEtaHitsOutOfRange+fPhiHitsOutOfRange<<ENDLOG;
+
+ Int_t hits_accepted=fClustersUnused-(fEtaHitsOutOfRange+fPhiHitsOutOfRange);
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::SetPointers","Setup")
+ <<"Setup finished, hits out of range: "<<fEtaHitsOutOfRange+fPhiHitsOutOfRange
+ <<" hits accepted "<<hits_accepted<<ENDLOG;
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking_a()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet[(Int_t)kTRUE])
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+ Double_t initCpuTime,cpuTime;
+ initCpuTime = CpuTime();
+
+ SetPointers();
+ SetVertexConstraint(true);
+ cpuTime = CpuTime() - initCpuTime;
+ if(fBench)
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_a","Timing")
+ <<AliHLTTPCLog::kDec<<"Setup finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking_b()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet[(Int_t)kTRUE])
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+ Double_t initCpuTime,cpuTime;
+ initCpuTime = CpuTime();
+
+ ClusterLoop();
+
+ cpuTime = CpuTime() - initCpuTime;
+ if(fBench)
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking_b","Timing")
+ <<AliHLTTPCLog::kDec<<"Main Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+}
+
+void AliHLTTPCConfMapper::MainVertexTracking()
+{
+ //Tracking with vertex constraint.
+
+ if(!fParamSet[(Int_t)kTRUE])
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::MainVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+ Double_t initCpuTime,cpuTime;
+ initCpuTime = CpuTime();
+
+ SetPointers();
+ SetVertexConstraint(true);
+
+ ClusterLoop();
+
+ cpuTime = CpuTime() - initCpuTime;
+ if(fBench)
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::MainVertexTracking","Timing")<<AliHLTTPCLog::kDec<<
+ "Tracking finished in "<<cpuTime*1000<<" ms"<<ENDLOG;
+
+ return;
+}
+
+void AliHLTTPCConfMapper::NonVertexTracking()
+{
+ //Tracking with no vertex constraint. This should be called after doing MainVertexTracking,
+ //in order to do tracking on the remaining clusters.
+ //The conformal mapping is now done with respect to the first cluster
+ //assosciated with this track.
+
+ if(!fParamSet[(Int_t)kFALSE])
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::NonVertexTracking","Parameters")<<AliHLTTPCLog::kDec<<
+ "Tracking parameters not set!"<<ENDLOG;
+ return;
+ }
+
+ SetVertexConstraint(false);
+ ClusterLoop();
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::NonVertexTracking","ntracks")<<AliHLTTPCLog::kDec<<
+ "Number of nonvertex tracks found: "<<(fNTracks-fMainVertexTracks)<<ENDLOG;
+ return;
+}
+
+void AliHLTTPCConfMapper::MainVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,
+ Double_t maxphi,Double_t maxeta)
+{
+ //Settings for main vertex tracking. The cuts are:
+ //TrackletLength: #hits on segment, before trying to build a track
+ //TrackLength: Minimum hits on a track
+ //RowScopeTracklet: Row search range for segments
+ //RowScopeTrack: Row search range for tracks
+
+ SetTrackletLength(trackletlength,(Bool_t)true);
+ SetRowScopeTracklet(rowscopetracklet, (Bool_t) true);
+ SetRowScopeTrack(rowscopetrack, (Bool_t) true);
+ SetMinPoints(tracklength,(Bool_t)true);
+ fMaxPhi=maxphi;
+ fMaxEta=maxeta;
+ SetParamDone(kTRUE);
+}
+
+void AliHLTTPCConfMapper::NonVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack)
+{
+ //set parameters for non-vertex tracking
+ SetTrackletLength(trackletlength,(Bool_t)false);
+ SetRowScopeTracklet(rowscopetracklet, (Bool_t)false);
+ SetRowScopeTrack(rowscopetrack, (Bool_t)false);
+ SetMinPoints(tracklength,(Bool_t)false);
+ SetParamDone(kFALSE);
+}
+
+void AliHLTTPCConfMapper::SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut,Int_t maxdist,Bool_t vertexconstraint)
+{
+ //Settings for tracks. The cuts are:
+ //HitChi2Cut: Maximum hit chi2
+ //goodHitChi2: Chi2 to stop look for next hit
+ //trackChi2Cut: Maximum track chi2
+ //maxdist: Maximum distance between two clusters when forming segments
+
+ SetHitChi2Cut(hitChi2Cut,vertexconstraint);
+ SetGoodHitChi2(goodHitChi2,vertexconstraint);
+ SetTrackChi2Cut(trackChi2Cut,vertexconstraint);
+ SetMaxDist(maxdist,vertexconstraint);
+}
+
+void AliHLTTPCConfMapper::SetTrackletCuts(Double_t maxangle,Double_t goodDist, Bool_t vc)
+{
+ //Sets cuts of tracklets. Right now this is only:
+ //maxangle: Maximum angle when forming segments (if trackletlength > 2)
+
+ fGoodDist=goodDist;
+ SetMaxAngleTracklet(maxangle, vc);
+}
+
+void AliHLTTPCConfMapper::ClusterLoop()
+{
+ //Loop over hits, starting at outermost padrow, and trying to build segments.
+
+ //Check if there are not enough clusters to make a track in this sector
+ //Can happen in pp events.
+ if(fClustersUnused < fMinPoints[fVertexConstraint])
+ return;
+
+ Int_t rowsegm,lastrow = fRowMin + fMinPoints[fVertexConstraint];
+ AliHLTTPCConfMapPoint *hit;
+
+ //Loop over rows, and try to create tracks from the hits.
+ //Starts at the outermost row, and loops as long as a track can be build, due to length.
+
+ for(rowsegm = fRowMax; rowsegm >= lastrow; rowsegm--)
+ {
+ if(fRow[(rowsegm-fRowMin)].first && ((AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first)->GetPadRow() < fRowMin + 1)
+ break;
+
+ for(hit = (AliHLTTPCConfMapPoint*)fRow[(rowsegm-fRowMin)].first; hit!=0; hit=hit->GetNextRowHit())
+ {
+ if(hit->GetUsage() == true)
+ continue;
+ else
+ CreateTrack(hit);
+ }
+ }
+
+ return;
+}
+
+
+void AliHLTTPCConfMapper::CreateTrack(AliHLTTPCConfMapPoint *hit)
+{
+ //Tries to create a track from the initial hit given by ClusterLoop()
+
+ AliHLTTPCConfMapPoint *closesthit = NULL;
+ AliHLTTPCConfMapTrack *track = NULL;
+
+ Int_t point;
+ Int_t tracks = fNTracks;
+ fNTracks++;
+
+ track = (AliHLTTPCConfMapTrack*)fTrack->NextTrack();
+
+ //reset hit parameters:
+ track->Reset();
+
+ UInt_t *trackhitnumber = track->GetHitNumbers();
+
+ //set conformal coordinates if we are looking for non vertex tracks
+ if(!fVertexConstraint)
+ {
+ hit->SetAllCoord(hit);
+ }
+
+ //fill fit parameters of initial track:
+ track->UpdateParam(hit); //here the number of hits is incremented.
+ trackhitnumber[track->GetNumberOfPoints()-1] = hit->GetHitNumber();
+
+ Double_t dx,dy;
+ //create tracklets:
+
+ for(point=1; point<fTrackletLength[fVertexConstraint]; point++)
+ {
+ if((closesthit = GetNextNeighbor(hit)))
+ {//closest hit exist
+
+ // Calculate track length in sz plane
+ dx = ((AliHLTTPCConfMapPoint*)closesthit)->GetX() - ((AliHLTTPCConfMapPoint*)hit)->GetX();
+ dy = ((AliHLTTPCConfMapPoint*)closesthit)->GetY() - ((AliHLTTPCConfMapPoint*)hit)->GetY();
+ //track->fLength += (Double_t)sqrt ( dx * dx + dy * dy ) ;
+ Double_t length = track->GetLength()+(Double_t)sqrt ( dx * dx + dy * dy );
+ track->SetLength(length);
+
+ //closesthit->SetS(track->fLength);
+ closesthit->SetS(track->GetLength());
+
+ //update fit parameters
+ track->UpdateParam(closesthit);
+ trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
+
+ hit = closesthit;
+ }
+ else
+ {
+ //closest hit does not exist:
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ fNTracks--;
+ point = fTrackletLength[fVertexConstraint];
+ }
+ }
+
+ //tracklet is long enough to be extended to a track
+ if(track->GetNumberOfPoints() == fTrackletLength[fVertexConstraint])
+ {
+
+ track->SetProperties(true);
+
+ if(TrackletAngle(track) > fMaxAngleTracklet[fVertexConstraint])
+ {//proof if the first points seem to be a beginning of a track
+ track->SetProperties(false);
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ fNTracks--;
+ }
+
+ else//good tracklet ->proceed, follow the trackfit
+ {
+ tracks++;
+
+ //define variables to keep the total chi:
+ Double_t xyChi2 = track->GetChiSq1();
+ Double_t szChi2 = track->GetChiSq2();
+
+ for(point = fTrackletLength[fVertexConstraint]; point <= fNumRowSegment; point++)
+ {
+ track->SetChiSq1(fHitChi2Cut[fVertexConstraint]);
+ closesthit = GetNextNeighbor((AliHLTTPCConfMapPoint*)track->GetLastHit(),track);
+
+ if(closesthit)
+ {
+ //keep total chi:
+ Double_t lxyChi2 = track->GetChiSq1()-track->GetChiSq2();
+ xyChi2 += lxyChi2;
+ closesthit->SetXYChi2(lxyChi2);
+
+ //update track length:
+ track->SetLength(closesthit->GetS());
+ szChi2 += track->GetChiSq2();
+ closesthit->SetSZChi2(track->GetChiSq2());
+
+ track->UpdateParam(closesthit);
+ trackhitnumber[track->GetNumberOfPoints()-1] = closesthit->GetHitNumber();
+
+ //add closest hit to track
+ closesthit->SetUsage(true);
+ closesthit->SetTrackNumber(tracks-1);
+
+ }//closesthit
+
+ else
+ {
+ //closest hit does not exist
+ point = fNumRowSegment; //continue with next hit in segment
+ }//else
+
+ }//create tracks
+
+ //store track chi2:
+ track->SetChiSq1(xyChi2);
+ track->SetChiSq2(szChi2);
+ Double_t normalizedchi2 = (track->GetChiSq1()+track->GetChiSq2())/track->GetNumberOfPoints();
+
+ //remove tracks with not enough points already now
+ if(track->GetNumberOfPoints() < fMinPoints[fVertexConstraint] || normalizedchi2 > fTrackChi2Cut[fVertexConstraint])
+ {
+ track->SetProperties(false);
+ fNTracks--;
+ track->DeleteCandidate();
+ fTrack->RemoveLast();
+ tracks--;
+ }
+
+ else
+ {
+ fClustersUnused -= track->GetNumberOfPoints();
+ track->ComesFromMainVertex(fVertexConstraint);
+ //mark track as main vertex track or not
+ track->SetSector(2); //only needed for testing purposes.
+ track->SetRowRange(fRowMin,fRowMax);
+
+ if(fVertexConstraint)
+ fMainVertexTracks++;
+ }
+
+ }//good tracklet
+
+ }
+
+ return;
+}
+
+AliHLTTPCConfMapPoint *AliHLTTPCConfMapper::GetNextNeighbor(AliHLTTPCConfMapPoint *starthit,
+ AliHLTTPCConfMapTrack *track)
+{
+ //When forming segments: Finds closest hit to input hit
+ //When forming tracks: Find closest hit to track fit.
+
+ Double_t dist,closestdist = fMaxDist[fVertexConstraint];
+
+ AliHLTTPCConfMapPoint *hit = NULL;
+ AliHLTTPCConfMapPoint *closesthit = NULL;
+
+ Int_t subrowsegm;
+ Int_t subphisegm;
+ Int_t subetasegm;
+ Int_t volumeIndex;
+ Int_t testhit;
+
+ Int_t maxrow = starthit->GetPadRow()-1;
+ Int_t minrow;
+
+ if(track) //finding hit close to trackfit
+ {
+ minrow = starthit->GetPadRow()-fRowScopeTrack[fVertexConstraint];
+ }
+ else
+ {
+ minrow = starthit->GetPadRow()-fRowScopeTracklet[fVertexConstraint];
+ }
+
+ //make a smart loop
+ Int_t loopeta[25] = {0,0,0,-1,-1,-1,1,1,1, 0,0,-1,-1,1,1,-2,-2,-2,-2,-2,2,2,2,2,2};
+ Int_t loopphi[25] = {0,-1,1,0,-1,1,0,-1,1, -2,2,-2,2,-2,2,-2,-1,0,1,2,-2,-1,0,1,2};
+
+ if(minrow < fRowMin)
+ minrow = fRowMin;
+ if(maxrow < fRowMin)
+ return 0; //reached the last padrow under consideration
+
+ else
+ {
+ //loop over sub rows
+ for(subrowsegm=maxrow; subrowsegm>=minrow; subrowsegm--)
+ {
+ //loop over subsegments, in the order defined above.
+ for(Int_t i=0; i<9; i++)
+ {
+ subphisegm = starthit->GetPhiIndex() + loopphi[i];
+
+ if(subphisegm < 0 || subphisegm >= fNumPhiSegment)
+ continue;
+ /*
+ if(subphisegm<0)
+ subphisegm += fNumPhiSegment;
+
+ else if(subphisegm >=fNumPhiSegment)
+ subphisegm -= fNumPhiSegment;
+ */
+ //loop over sub eta segments
+
+ subetasegm = starthit->GetEtaIndex() + loopeta[i];
+
+ if(subetasegm < 0 || subetasegm >=fNumEtaSegment)
+ continue;//segment exceeds bounds->skip it
+
+ //loop over hits in this sub segment:
+ volumeIndex=(subrowsegm-fRowMin)*fNumPhiEtaSegmentPlusOne +
+ subphisegm*fNumEtaSegmentPlusOne + subetasegm;
+
+ if(volumeIndex<0)
+ {//debugging
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::GetNextNeighbor","Memory")<<AliHLTTPCLog::kDec<<
+ "VolumeIndex error "<<volumeIndex<<ENDLOG;
+ }
+
+ for(hit = (AliHLTTPCConfMapPoint*)fVolume[volumeIndex].first;
+ hit!=0; hit = hit->GetNextVolumeHit())
+ {
+
+ if(!hit->GetUsage())
+ {//hit was not used before
+
+ //set conformal mapping if looking for nonvertex tracks:
+ if(!fVertexConstraint)
+ {
+ hit->SetAllCoord(starthit);
+ }
+
+ if(track)//track search - look for nearest neighbor to extrapolated track
+ {
+ if(!VerifyRange(starthit,hit))
+ continue;
+
+ testhit = EvaluateHit(starthit,hit,track);
+
+ if(testhit == 0)//chi2 not good enough, keep looking
+ continue;
+ else if(testhit==2)//chi2 good enough, return it
+ return hit;
+ else
+ closesthit = hit;//chi2 acceptable, but keep looking
+
+ }//track search
+
+ else //tracklet search, look for nearest neighbor
+ {
+
+ if((dist=CalcDistance(starthit,hit)) < closestdist)
+ {
+ if(!VerifyRange(starthit,hit))
+ continue;
+ closestdist = dist;
+ closesthit = hit;
+
+ //if this hit is good enough, return it:
+ if(closestdist < fGoodDist)
+ return closesthit;
+ }
+ else
+ continue;//sub hit was farther away than a hit before
+
+ }//tracklet search
+
+ }//hit not used before
+
+ else continue; //sub hit was used before
+
+ }//loop over hits in sub segment
+
+ }//loop over sub segments
+
+ }//loop over subrows
+
+ }//else
+
+ //closest hit found:
+ if(closesthit)// && closestdist < mMaxDist)
+ return closesthit;
+ else
+ return 0;
+}
+
+Int_t AliHLTTPCConfMapper::EvaluateHit(AliHLTTPCConfMapPoint *starthit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track)
+{
+ //Check if space point gives a fit with acceptable chi2.
+
+ Double_t temp,dxy,lchi2,dx,dy,slocal,dsz,lszChi2;
+ temp = (track->GetA2Xy()*hit->GetXprime()-hit->GetYprime()+track->GetA1Xy());
+ dxy = temp*temp/(track->GetA2Xy()*track->GetA2Xy() + 1.);
+
+ //Calculate chi2
+ lchi2 = (dxy*hit->GetXYWeight());
+
+ if(lchi2 > track->GetChiSq1())//chi2 was worse than before.
+ return 0;
+
+ //calculate s and the distance hit-line
+ dx = starthit->GetX()-hit->GetX();
+ dy = starthit->GetY()-hit->GetY();
+ //slocal = track->fLength+sqrt(dx*dx+dy*dy);
+ slocal = track->GetLength()+sqrt(dx*dx+dy*dy);
+
+ temp = (track->GetA2Sz()*slocal-hit->GetZ()+track->GetA1Sz());
+ dsz = temp*temp/(track->GetA2Sz()*track->GetA2Sz()+1);
+
+ //calculate chi2
+ lszChi2 = dsz*hit->GetZWeight();
+ lchi2 += lszChi2;
+
+
+ //check whether chi2 is better than previous one:
+ if(lchi2 < track->GetChiSq1())
+ {
+ track->SetChiSq1(lchi2);
+ track->SetChiSq2(lszChi2);
+
+ hit->SetS(slocal);
+
+ //if chi2 good enough, stop here:
+ if(lchi2 < fGoodHitChi2[fVertexConstraint])
+ return 2;
+
+ return 1;
+ }
+
+ return 0;
+
+}
+
+Double_t AliHLTTPCConfMapper::CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
+{
+ //Return distance between two clusters, defined by Pablo
+
+ Double_t phidiff = fabs( hit1->GetPhi() - hit2->GetPhi() );
+ if (phidiff > AliHLTTPCTransform::Pi()) phidiff = AliHLTTPCTransform::TwoPi() - phidiff;
+
+ return AliHLTTPCTransform::ToDeg()*fabs((Float_t)((hit1->GetPadRow() - hit2->GetPadRow()) *
+ (phidiff + fabs( hit1->GetEta() - hit2->GetEta()))));
+}
+
+Bool_t AliHLTTPCConfMapper::VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const
+{
+ //Check if the hit are within reasonable range in phi and eta
+ Double_t dphi,deta;//maxphi=0.1,maxeta=0.1;
+ dphi = fabs(hit1->GetPhi() - hit2->GetPhi());
+ if(dphi > AliHLTTPCTransform::Pi()) dphi = fabs(AliHLTTPCTransform::TwoPi() - dphi);
+ if(dphi > fMaxPhi) return false;
+
+ deta = fabs(hit1->GetEta() - hit2->GetEta());
+ if(deta > fMaxEta) return false;
+
+ return true;
+
+}
+
+Double_t AliHLTTPCConfMapper::TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n) const
+{
+ // Returns the angle 'between' the last three points (started at point number n) on this track.
+
+ if(n > track->GetNumberOfPoints())
+ n = track->GetNumberOfPoints();
+
+ if(n<3)
+ return 0;
+
+ Double_t x1[2];
+ Double_t x2[2];
+ Double_t x3[2];
+ Double_t angle1,angle2;
+ Int_t counter=0;
+ for(track->StartLoop(); track->LoopDone(); track->GetNextHit())
+ {
+ AliHLTTPCConfMapPoint *p = (AliHLTTPCConfMapPoint*)track->GetCurrentHit();
+ if( (n-1) == counter)
+ {
+ x1[0] = p->GetX();
+ x1[1] = p->GetY();
+ }
+ else if( (n-2) == counter)
+ {
+ x2[0] = p->GetX();
+ x2[1] = p->GetY();
+ }
+ else if( (n-3) == counter)
+ {
+ x3[0] = p->GetX();
+ x3[1] = p->GetY();
+ }
+ counter++;
+ }
+
+ angle1 = atan2(x2[1]-x3[1],x2[0]-x3[0]);
+ angle2 = atan2(x1[1]-x2[1],x1[0]-x2[0]);
+
+ return fabs(angle1-angle2);
+
+ /*
+ Double_t x1[2];
+ Double_t x2[2];
+ Double_t angle1,angle2;
+ TObjArray *hits = track->GetHits();
+
+ if (n > track->GetNumberOfPoints()) {
+ n = track->GetNumberOfPoints();
+ }
+
+ if (n<3)
+ return 0;
+
+
+ x1[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetX();
+ x1[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-3))->GetY();
+
+ x2[0] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetX() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetX();
+ x2[1] = ((AliHLTTPCConfMapPoint *)hits->At(n-1))->GetY() - ((AliHLTTPCConfMapPoint *)hits->At(n-2))->GetY();
+
+ angle1 = atan2(x1[1],x1[0]);
+ angle2 = atan2(x2[1],x1[0]);
+ return fabs(angle1-angle2);
+ */
+}
+
+Int_t AliHLTTPCConfMapper::FillTracks()
+{
+ //Fill track parameters. Which basically means do a fit of helix in real space,
+ //which should be done in order to get nice tracks.
+
+ Int_t numoftracks = fNTracks;
+ if(fNTracks == 0)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
+ "No tracks found!!"<<ENDLOG;
+ return 0;
+ }
+
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCConfMapper::FillTracks","fNTracks")<<AliHLTTPCLog::kDec<<
+ "Number of found tracks: "<<fNTracks<<ENDLOG;
+
+ // fTrack->Sort();
+ for(Int_t i=0; i<numoftracks; i++)
+ {
+ AliHLTTPCConfMapTrack *track = (AliHLTTPCConfMapTrack*)fTrack->GetTrack(i);
+ track->Fill(fVertex,fMaxDca);
+ }
+ return 1;
+}
+
+Double_t AliHLTTPCConfMapper::CpuTime()
+{
+ //Return the Cputime in seconds.
+ struct timeval tv;
+ gettimeofday( &tv, NULL );
+ return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCCONFMAPPER_H
+#define ALIHLTTPCCONFMAPPER_H
+
+//
+//Conformal mapping base class
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+
+class AliHLTTPCConfMapPoint;
+class AliHLTTPCConfMapTrack;
+class AliHLTTPCVertex;
+class AliHLTTPCTrackArray;
+class AliHLTTPCSpacePointData;
+
+
+class AliHLTTPCConfMapper {
+
+ public:
+
+ AliHLTTPCConfMapper();
+ // AliHLTTPCConfMapper(AliTPCParam *param,AliHLTTPCVertex *vertex,Bool_t bench=(Bool_t)false);
+ virtual ~AliHLTTPCConfMapper();
+
+ void InitVolumes();
+ void InitSector(Int_t sector,Int_t *rowrange=0,Float_t *etarange=0);
+ void SetVertex(AliHLTTPCVertex *vertex){fVertex = vertex;}
+ void MainVertexTracking_a();
+ void MainVertexTracking_b();
+ void MainVertexTracking();
+ void NonVertexTracking();
+ void MainVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack,Double_t maxphi=0.1,Double_t maxeta=0.1);
+ void NonVertexSettings(Int_t trackletlength, Int_t tracklength,
+ Int_t rowscopetracklet, Int_t rowscopetrack);
+ Bool_t ReadHits(UInt_t count, AliHLTTPCSpacePointData* hits );
+ void ClusterLoop();
+ void CreateTrack(AliHLTTPCConfMapPoint *hit);
+ AliHLTTPCConfMapPoint *GetNextNeighbor(AliHLTTPCConfMapPoint *start_hit,AliHLTTPCConfMapTrack *track=NULL);
+ Int_t EvaluateHit(AliHLTTPCConfMapPoint *start_hit,AliHLTTPCConfMapPoint *hit,AliHLTTPCConfMapTrack *track);
+
+ Double_t CalcDistance(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const;
+ Double_t TrackletAngle(AliHLTTPCConfMapTrack *track,Int_t n=3) const;
+ Bool_t VerifyRange(const AliHLTTPCConfMapPoint *hit1,const AliHLTTPCConfMapPoint *hit2) const;
+ Int_t FillTracks();
+
+ //getters
+ Int_t GetNumberOfTracks() const {return fNTracks;}
+ AliHLTTPCTrackArray *GetTracks() const {return fTrack;}
+ Double_t GetMaxDca() const {return fMaxDca;}
+ AliHLTTPCVertex* GetVertex() const {return fVertex;}
+ Double_t CpuTime();
+
+ //setters
+ void SetTrackCuts(Double_t hitChi2Cut, Double_t goodHitChi2, Double_t trackChi2Cut, Int_t maxdist,Bool_t vertexconstraint);
+ void SetTrackletCuts(Double_t maxangle,Double_t goodDist,Bool_t vc); //Set cut of tracklet for the given vertex_constraint
+ void SetNSegments(Int_t f,Int_t g) {fNumPhiSegment=f,fNumEtaSegment=g;} //Set number of subvolumes (#segments in (phi,eta)
+ void SetMaxDca(Double_t f) {fMaxDca = f;}
+
+ //setter:
+ void SetMinPoints(Int_t f,Bool_t vconstraint) {fMinPoints[(Int_t)vconstraint] = f; }
+ void SetVertexConstraint(Bool_t f) {fVertexConstraint =f;}
+
+ void SetHitChi2Cut(Double_t f,Bool_t vert) {fHitChi2Cut[(Int_t)vert]=f;}
+ void SetGoodHitChi2(Double_t f,Bool_t vert) {fGoodHitChi2[(Int_t)vert]=f;}
+ void SetTrackChi2Cut(Double_t f,Bool_t vert) {fTrackChi2Cut[(Int_t)vert]=f;}
+ void SetMaxDist(Int_t f,Bool_t vert) {fMaxDist[(Int_t)vert]=f;}
+ void SetTrackletLength(Int_t f,Bool_t vert) {fTrackletLength[(Int_t)vert]=f;}
+ void SetRowScopeTrack(Int_t f, Bool_t vc){fRowScopeTrack[(Int_t)vc] = f;}
+ void SetRowScopeTracklet(Int_t f, Bool_t vc){fRowScopeTracklet[(Int_t)vc] = f;}
+ void SetMaxAngleTracklet(Double_t f, Bool_t vc){fMaxAngleTracklet[(Int_t)vc] = f;}
+
+ void SetPointers();
+ void SetParamDone(Bool_t vconstraint) {fParamSet[(Int_t)vconstraint] = kTRUE;}
+
+ private:
+
+ struct AliHLTTPCConfMapContainer
+ {
+ void *first; // first track
+ void *last; // last track
+ };
+
+ Bool_t fBench; //run-time measurements
+ Int_t fNTracks; //number of tracks build.
+
+ AliHLTTPCVertex *fVertex; //!
+ Bool_t fParamSet[2]; //!
+ Bool_t fVertexFinder; //Include vertexfinding or not
+ //(latter case vertex=(0,0,0))
+
+ AliHLTTPCConfMapPoint *fHit; //!
+ AliHLTTPCTrackArray *fTrack; //!
+ Double_t fMaxDca; //cut value for momentum fit
+
+ AliHLTTPCConfMapContainer *fVolume; //! Segment volume
+ AliHLTTPCConfMapContainer *fRow; //! Row volume
+
+ //Number of cells (segments)
+ Int_t fNumRowSegment; // Total number of padrows
+ Int_t fNumPhiSegment; // number of phi segments
+ Int_t fNumEtaSegment; // number of eta segments
+ Int_t fNumRowSegmentPlusOne; // row+1
+ Int_t fNumPhiSegmentPlusOne; // phi+1
+ Int_t fNumEtaSegmentPlusOne; // eta+1
+ Int_t fNumPhiEtaSegmentPlusOne;// phieta+1
+ Int_t fBounds; // bounds
+ Int_t fPhiHitsOutOfRange; // phi hits out of range
+ Int_t fEtaHitsOutOfRange; // eta hits out of range
+
+ //tracking range:
+ Float_t fPhiMin; //MinPhi angle to consider
+ Float_t fPhiMax; //MaxPhi angle to consider
+ Float_t fEtaMin; //MinEta to consider
+ Float_t fEtaMax; //MaxEta to consider
+ Int_t fRowMin; //Minimum row to consider
+ Int_t fRowMax; //Maximum row to consider
+
+ Bool_t fVertexConstraint; //vertex constraint (true or false)
+ Int_t fTrackletLength[2]; //minimal length of tracks
+ Int_t fRowScopeTracklet[2]; //number of row segments to look for the next point of a tracklet
+ Int_t fRowScopeTrack[2]; //number of row segments to look for the next point of a track
+ Int_t fMinPoints[2]; //minimum number of points on one track
+
+ // Cuts
+ Double_t fMaxAngleTracklet[2]; //limit of angle between to pieces of a tracklet
+ Int_t fMaxDist[2]; //maximum distance between two hits
+ Double_t fHitChi2Cut[2]; //Maximum hit chi2
+ Double_t fGoodHitChi2[2]; //Chi2 to stop looking for next hit
+ Double_t fTrackChi2Cut[2]; //Maximum track chi2
+ Double_t fGoodDist; //In segment building, distance consider good enough
+ Double_t fMaxPhi; //Maximum phi
+ Double_t fMaxEta; //Maximum eta
+
+ // Tracking informtion
+ Int_t fMainVertexTracks; //number of tracks coming from the main vertex
+ Int_t fClustersUnused; //number of unused clusters
+
+ ClassDef(AliHLTTPCConfMapper,1) //Base class for conformal mapping tracking
+};
+
+#endif
--- /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 "AliRawReaderRoot.h"
+#include "AliRawReaderDate.h"
+#else
+#include "AliHLTTPCDDLTPCRawStream.h"
+#include "AliHLTTPCDDLRawReaderFile.h"
+#endif
+#include "AliHLTTPCDDLDataFileHandler.h"
+
+#if __GNUC__ == 3
+using namespace std;
+#endif
+
+/** \class AliHLTTPCDDLDataFileHandler
+<pre>
+//_____________________________________________________________
+// AliHLTTPCDDLDataFileHandler
+//
+// This class does converts from the DDL format of offline
+// into the memory I/O handling of the HLT binary files.
+//
+// Examples: see ddl2binary in exa and the general
+// AliHLTTPCMemHandler class description
+//
+</pre>
+*/
+
+ClassImp(AliHLTTPCDDLDataFileHandler)
+
+AliHLTTPCDDLDataFileHandler::AliHLTTPCDDLDataFileHandler()
+{
+ // default constructor
+ fReader=0;
+ fTPCStream=0;
+}
+
+AliHLTTPCDDLDataFileHandler::~AliHLTTPCDDLDataFileHandler()
+{
+ // destructor
+ FreeAll();
+}
+
+void AliHLTTPCDDLDataFileHandler::FreeAll()
+{
+ // frees all heap memory
+ if(fReader) delete fReader;
+ fReader = 0;
+ if(fTPCStream) delete fTPCStream;
+ fTPCStream = 0;
+}
+
+
+#ifdef use_newio
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(AliRawEvent *rawevent)
+{
+ // sets the input of the reader
+ fEvent=-1;
+ fFilename="";
+ if(fReader) delete fReader;
+ fReader=new AliRawReaderRoot(rawevent);
+ if(fTPCStream) delete fTPCStream;
+ fTPCStream=new AliTPCRawStream(fReader);
+
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name,Int_t event)
+{
+ // sets the input of the reader
+ fEvent=event;
+ if(fReader) delete fReader;
+ if(fTPCStream) delete fTPCStream;
+ if(event>=0){
+ fFilename=name;
+ fReader=new AliRawReaderRoot(name,event);
+ } else {
+ fFilename="";
+ fReader=new AliRawReaderDate((void *)name);
+ }
+ fTPCStream=new AliTPCRawStream(fReader);
+
+ return kTRUE;
+}
+#else
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(Char_t *name, Bool_t add)
+{
+ // sets the input of the reader
+ if(fReader){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::SetReaderInput","File Open")
+ <<"Reader ptr is already in use"<<ENDLOG;
+ return kFALSE;
+ }
+
+ fReader=new AliHLTTPCDDLRawReaderFile(name,add);
+ fTPCStream=new AliHLTTPCDDLTPCRawStream(fReader);
+
+ return kTRUE;
+}
+Bool_t AliHLTTPCDDLDataFileHandler::SetReaderInput(AliHLTTPCDDLRawReaderFile *rf)
+{
+ // sets the input of the reader
+ if(fReader){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCRawDataFileHandler::SetReaderInput","File Open")
+ <<"Reader ptr is already in use, delete it first"<<ENDLOG;
+ return kFALSE;
+ }
+
+ //Open the raw data file with given file.
+ fReader = rf;
+ fTPCStream=new AliHLTTPCDDLTPCRawStream(fReader);
+
+ return kTRUE;
+}
+#endif
+
+void AliHLTTPCDDLDataFileHandler::CloseReaderInput()
+{
+ // closes the input of the reader
+ if(!fReader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCRawDataFileHandler::CloseReaderInput","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+
+ delete fReader;
+ delete fTPCStream;
+ fReader = 0;
+ fTPCStream = 0;
+}
+
+#ifdef use_newio
+Bool_t AliHLTTPCDDLDataFileHandler::IsDigit(Int_t /*i*/) const
+{
+ // dummy
+ return kTRUE;
+}
+#endif
+
+#ifndef fast_raw
+AliHLTTPCDigitRowData * AliHLTTPCDDLDataFileHandler::DDLData2Memory(UInt_t &nrow,Int_t event)
+{
+ // transfers the DDL data to the memory
+#ifdef use_newio
+ if((fEvent>=0)&&(event!=fEvent)){
+ fEvent=event;
+ if(fReader) delete fReader;
+ if(fTPCStream) delete fTPCStream;
+ fReader=new AliRawReaderRoot(fFilename,event);
+ fTPCStream=new AliTPCRawStream(fReader);
+ }
+#endif
+ AliHLTTPCDigitRowData *data = 0;
+ nrow=0;
+
+ if(!fReader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCDDLDataFileHandler::DDLData2Memory","File")
+ <<"No Input avalible: no object AliHLTTPCDDLRawReaderFile"<<ENDLOG;
+ return 0;
+ }
+
+ Int_t nrows=fRowMax-fRowMin+1;
+ Int_t ndigitcount=0;
+ Int_t * ndigits = new Int_t[nrows];
+ UShort_t ***charges=new UShort_t**[nrows];
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t lrow=r-fRowMin;
+ charges[lrow]=new UShort_t*[AliHLTTPCTransform::GetNPads(r)];
+ for(Int_t k=0;k<AliHLTTPCTransform::GetNPads(r);k++){
+ charges[lrow][k]=new UShort_t[AliHLTTPCTransform::GetNTimeBins()];
+ for(Int_t j=0;j<AliHLTTPCTransform::GetNTimeBins();j++) charges[lrow][k][j]=0;
+ }
+ }
+
+ Int_t ddlsToSearch=0;
+ Int_t ddls[9]={-1,-1,-1,-1,-1,-1,-1,-1,-1};
+ Int_t ddlid=-1,lddlid=-1;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ ndigits[r-fRowMin] = 0; //now digits on row
+
+ Int_t patch=AliHLTTPCTransform::GetPatch(r);
+ Int_t sector,row;
+ AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+
+ if(sector<36) //taken from AliTPCBuffer160.cxx
+ ddlid=sector*2+patch;
+ else
+ ddlid=70+(sector-36)*4+patch;
+
+ if((lddlid!=ddlid-1)&&(r==30)){ //dont forget the split row on the last ddl
+ ddls[ddlsToSearch++]=ddlid-1;
+ lddlid=ddlid-1;
+ }
+
+ if((lddlid==-1)||(ddlid!=lddlid)){
+ ddls[ddlsToSearch++]=ddlid;
+ lddlid=ddlid;
+ }
+ if((r==90)||(r==139)){ //dont forget the split row on the next ddl
+ ddls[ddlsToSearch++]=ddlid+1;
+ lddlid=ddlid+1;
+ }
+ }
+
+ // for(Int_t i=0;i<ddlsToSearch;i++) cout << ddls[i] <<endl;
+
+ if(ddls[0]>ddls[ddlsToSearch-1]) {
+ Int_t tempddl = ddls[0];
+ ddls[0] = ddls[ddlsToSearch-1];
+ ddls[ddlsToSearch-1] = tempddl;
+ }
+#ifdef use_newio
+ fReader->Reset();
+ fReader->Select(0,ddls[0],ddls[ddlsToSearch-1]);
+ fTPCStream->Reset();
+#else
+ fTPCStream->SetDDLID(ddls[i]); //ddl to read out
+#endif
+ Int_t zerosup = AliHLTTPCTransform::GetZeroSup();
+ Int_t adcsat = AliHLTTPCTransform::GetADCSat();
+ Int_t slice,srow;
+ Int_t lrow=-1;
+
+ while (fTPCStream->Next()){
+
+ if(fTPCStream->IsNewSector() || fTPCStream->IsNewRow()) {
+ Int_t sector=fTPCStream->GetSector();
+ Int_t row=fTPCStream->GetRow();
+ AliHLTTPCTransform::Sector2Slice(slice,srow,sector,row);
+ if(slice!=fSlice){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Slice")
+ <<AliHLTTPCLog::kDec<<"Found slice "<<slice<<", expected "<<fSlice<<ENDLOG;
+ continue;
+ }
+ lrow=srow-fRowMin;
+ }
+
+ //test row criteria (patch boundaries)
+ if((srow<fRowMin)||(srow>fRowMax))continue;
+
+ Int_t pad=fTPCStream->GetPad();
+ if(fTPCStream->IsNewPad()) {
+ if((pad<0)||(pad>=AliHLTTPCTransform::GetNPads(srow))){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Pad")
+ <<AliHLTTPCLog::kDec<<"Pad value out of bounds "<<pad<<" "
+ <<AliHLTTPCTransform::GetNPads(srow)<<ENDLOG;
+ continue;
+ }
+ }
+
+ Int_t time=fTPCStream->GetTime();
+ if((time<0)||(time>=AliHLTTPCTransform::GetNTimeBins())){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Time")
+ <<AliHLTTPCLog::kDec<<"Time out of bounds "<<time<<" "
+ <<AliHLTTPCTransform::GetNTimeBins()<<ENDLOG;
+ continue;
+ }
+
+ //store digit
+ UShort_t dig=fTPCStream->GetSignal();
+ if(dig <= zerosup) continue;
+ if(dig >= adcsat) dig = adcsat;
+
+ ndigits[lrow]++; //for this row only
+ ndigitcount++; //total number of digits to be published
+
+ charges[lrow][pad][time]=dig;
+ }
+
+ Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+ + nrows*sizeof(AliHLTTPCDigitRowData);
+
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCDDLDataFileHandler::DDLDigits2Memory","Digits")
+ <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+
+ data=(AliHLTTPCDigitRowData*) Allocate(size);
+ nrow = (UInt_t)nrows;
+ AliHLTTPCDigitRowData *tempPt = data;
+
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t lrow=r-fRowMin;
+ tempPt->fRow = r;
+ tempPt->fNDigit = ndigits[lrow];
+
+ Int_t localcount=0;
+ for(Int_t pad=0;pad<AliHLTTPCTransform::GetNPads(r);pad++){
+ for(Int_t time=0;time<AliHLTTPCTransform::GetNTimeBins();time++){
+ UShort_t dig=charges[lrow][pad][time];
+ if(!dig) continue;
+
+ if(localcount >= ndigits[lrow])
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLDataFileHandler::DDLDigits2Binary","Memory")
+ <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+ <<ndigits[lrow]<<ENDLOG;
+
+
+ tempPt->fDigitData[localcount].fCharge=dig;
+ tempPt->fDigitData[localcount].fPad=pad;
+ tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+ tempPt->fDigitData[localcount].fTrackID[0] = 0;
+ tempPt->fDigitData[localcount].fTrackID[1] = 0;
+ tempPt->fDigitData[localcount].fTrackID[2] = 0;
+#endif
+ localcount++;
+ }
+ }
+
+ if(localcount != ndigits[lrow])
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCDDLDataFileHandler::DDLDigits2Binary","Memory")
+ <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+ <<ndigits[lrow]<<ENDLOG;
+
+
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliHLTTPCDigitRowData)
+ + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
+ tmp += size;
+ tempPt = (AliHLTTPCDigitRowData*)tmp;
+ }
+
+ //delete charge array
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t lrow=r-fRowMin;
+ for(Int_t k=0;k<AliHLTTPCTransform::GetNPads(r);k++)
+ delete charges[lrow][k];
+ delete charges[lrow];
+ }
+ delete charges;
+ delete [] ndigits;
+
+ return data;
+}
+#else
+AliHLTTPCDigitRowData * AliHLTTPCDDLDataFileHandler::DDLData2Memory(UInt_t &nrow,Int_t event)
+{
+ // transfers the DDL data to the memory
+#ifdef use_newio
+ if((fEvent>=0)&&(event!=fEvent)){
+ fEvent=event;
+ if(fReader) delete fReader;
+ if(fTPCStream) delete fTPCStream;
+ fReader=new AliRawReaderRoot(fFilename,event);
+ fTPCStream=new AliTPCRawStream(fReader);
+ }
+#endif
+ AliHLTTPCDigitRowData *data = 0;
+ nrow=0;
+
+ if(!fReader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCDDLDataFileHandler::DDLData2Memory","File")
+ <<"No Input avalible: no object AliHLTTPCDDLRawReaderFile"<<ENDLOG;
+ return 0;
+ }
+
+ Int_t nrows=fRowMax-fRowMin+1;
+
+ Int_t ddlsToSearch=0;
+ Int_t ddls[9]={-1,-1,-1,-1,-1,-1,-1,-1,-1};
+ Int_t ddlid=-1,lddlid=-1;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+
+ Int_t patch=AliHLTTPCTransform::GetPatch(r);
+ Int_t sector,row;
+ AliHLTTPCTransform::Slice2Sector(fSlice,r,sector,row);
+
+ if(sector<36) //taken from AliTPCBuffer160.cxx
+ ddlid=sector*2+patch;
+ else
+ ddlid=70+(sector-36)*4+patch;
+
+ if((lddlid==-1)||(ddlid!=lddlid)){
+ ddls[ddlsToSearch++]=ddlid;
+ lddlid=ddlid;
+ }
+ }
+
+ // for(Int_t i=0;i<ddlsToSearch;i++) cout << ddls[i] <<endl;
+
+#ifdef use_newio
+ fReader->Reset();
+ fReader->Select(0,ddls[0],ddls[ddlsToSearch-1]);
+ fTPCStream->Reset();
+#else
+ fTPCStream->SetDDLID(ddls[i]); //ddl to read out
+#endif
+
+ nrow = (UInt_t)nrows;
+
+ return data;
+}
+#endif
+
+Bool_t AliHLTTPCDDLDataFileHandler::DDLData2CompBinary(Int_t event)
+{
+ // transfers the DDL data to the memory and converts it
+ // to comp binary
+ Bool_t out = kTRUE;
+ UInt_t ndigits=0;
+ AliHLTTPCDigitRowData *digits=0;
+ digits = DDLData2Memory(ndigits,event);
+ out = Memory2CompBinary(ndigits,digits);
+ Free();
+ return out;
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCDDLDATAFILEHANDLER_H
+#define ALIHLTTPCDDLDATAFILEHANDLER_H
+
+#ifdef use_newio
+#include "../RAW/AliRawEvent.h"
+#include "../RAW/AliRawReader.h"
+#include "../RAW/AliTPCRawStream.h"
+#include <TString.h>
+#else
+#include "AliHLTTPCDDLRawReaderFile.h"
+#include "AliHLTTPCDDLTPCRawStream.h"
+#endif
+#include "AliHLTTPCMemHandler.h"
+
+class AliHLTTPCDDLDataFileHandler:public AliHLTTPCMemHandler{
+
+ public:
+
+ AliHLTTPCDDLDataFileHandler();
+ virtual ~AliHLTTPCDDLDataFileHandler();
+
+#ifdef use_newio
+ Bool_t SetReaderInput(AliRawEvent *rawevent);
+ Bool_t SetReaderInput(Char_t *name,Int_t event=0);
+ Bool_t IsDigit(Int_t i=0) const;
+ AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & nrow,Int_t event=0,Bool_t /*eventmerge*/=kFALSE){return DDLData2Memory(nrow,event);};
+#else
+ Bool_t SetReaderInput(Char_t *name,Bool_t add=kTRUE);
+ Bool_t SetReaderInput(AliHLTTPCDDLRawReaderFile *rf);
+#endif
+
+ void CloseReaderInput();
+ void FreeAll(); //like AliHLTTPCMemHandler::Free() or AliHLTTPCFileHandler::FreeDigitsTree
+
+ AliHLTTPCDigitRowData* DDLData2Memory(UInt_t &nrow,Int_t event=-1);
+ Bool_t DDLData2CompBinary(Int_t event=-1);
+
+ AliTPCRawStream* GetTPCRawStream(){return fTPCStream;}
+
+ private:
+#ifdef use_newio
+ TString fFilename; // IO file name
+ Int_t fEvent; // event number
+ AliRawReader *fReader; // raw reader
+ AliTPCRawStream *fTPCStream;// TPC raw stream
+#else
+ AliHLTTPCDDLRawReaderFile *fReader; // raw reader
+ AliHLTTPCDDLTPCRawStream *fTPCStream; // TPC raw stream
+#endif
+
+ ClassDef(AliHLTTPCDDLDataFileHandler,1) //DDL Data Filehandler class
+};
+#endif
--- /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
{
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,
--- /dev/null
+// @(#) $Id$
+
+#ifndef _ALIHLTTPCDIGITDATA_H_
+#define _ALIHLTTPCDIGITDATA_H_
+
+#include "AliHLTTPCRootTypes.h"
+
+struct AliHLTTPCDigitData
+{
+#ifdef do_mc
+ Int_t fTrackID[3];
+#endif
+ UShort_t fCharge;
+ UChar_t fPad;
+ UShort_t fTime;
+#ifdef IA64
+ UChar_t dummy1;
+ UChar_t dummy2;
+#endif
+};
+typedef struct AliHLTTPCDigitData AliHLTTPCDigitData;
+
+struct AliHLTTPCDigitRowData
+{
+ UInt_t fNDigit;
+ UInt_t fRow;
+#if defined(__HP_aCC) || defined(__DECCXX) || defined(__SUNPRO_CC)
+ AliHLTTPCDigitData fDigitData[1];
+#else
+ AliHLTTPCDigitData fDigitData[0];
+#endif
+};
+typedef struct AliHLTTPCDigitRowData AliHLTTPCDigitRowData;
+
+struct AliHLTTPCRandomDigitData{
+ UChar_t fRow;
+ UShort_t fCharge;
+ UChar_t fPad;
+ UShort_t fTime;
+};
+typedef struct AliHLTTPCRandomDigitData AliHLTTPCRandomDigitData;
+#endif /* _ALIHLTTPCDIGITDATA_H_ */
--- /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();
+#else
+ Char_t name[1024];
+ sprintf(name,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
+ TTree *t=(TTree*)fInAli->Get(name);
+#endif
+ if(t){
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
+ <<"Found Digit Tree -> Use Fast Cluster Finder"<<ENDLOG;
+ return kTRUE;
+ }
+ else{
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandlerNewIO::IsDigit","File Type")
+ <<"No Digit Tree -> Use Cluster Tree"<<ENDLOG;
+ return kFALSE;
+ }
+}
+
+///////////////////////////////////////// Digit IO
+Bool_t AliHLTTPCFileHandler::AliDigits2Binary(Int_t event,Bool_t altro)
+{
+ //save alidigits as binary
+ Bool_t out = kTRUE;
+ UInt_t nrow;
+ AliHLTTPCDigitRowData* data = 0;
+ if(altro)
+ data = AliAltroDigits2Memory(nrow,event);
+ else
+ data = AliDigits2Memory(nrow,event);
+ out = Memory2Binary(nrow,data);
+ Free();
+ return out;
+}
+
+Bool_t AliHLTTPCFileHandler::AliDigits2CompBinary(Int_t event,Bool_t altro)
+{
+ //Convert AliROOT TPC data, into HLT data format.
+ //event specifies the event you want in the aliroot file.
+
+ Bool_t out = kTRUE;
+ UInt_t ndigits=0;
+ AliHLTTPCDigitRowData *digits=0;
+ if(altro)
+ digits = AliAltroDigits2Memory(ndigits,event);
+ else
+ digits = AliDigits2Memory(ndigits,event);
+ out = Memory2CompBinary(ndigits,digits);
+ Free();
+ return out;
+}
+
+Bool_t AliHLTTPCFileHandler::CreateIndex()
+{
+ //create the access index or copy from static index
+ fIndexCreated=kFALSE;
+
+ if(!fgStaticIndexCreated || !fUseStaticIndex) { //we have to create index
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+ <<"Starting to create index, this can take a while."<<ENDLOG;
+
+ for(Int_t n=0; n<fDigitsTree->GetEntries(); n++) {
+ Int_t sector, row;
+ Int_t lslice,lrow;
+ fDigitsTree->GetEvent(n);
+ fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+ if(!AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row)){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::CreateIndex","Slice/Row")
+ <<AliHLTTPCLog::kDec<<"Index could not be created. Wrong values "
+ <<sector<<" "<<row<<ENDLOG;
+ return kFALSE;
+ }
+ if(fIndex[lslice][lrow]==-1) {
+ fIndex[lslice][lrow]=n;
+ }
+ }
+ if(fUseStaticIndex) { // create static index
+ for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+ for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+ fgStaticIndex[i][j]=fIndex[i][j];
+ }
+ fgStaticIndexCreated=kTRUE; //remember that index has been created
+ }
+
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+ <<"Index successfully created."<<ENDLOG;
+
+ } else if(fUseStaticIndex) { //simply copy static index
+ for(Int_t i=0;i<AliHLTTPCTransform::GetNSlice();i++){
+ for(Int_t j=0;j<AliHLTTPCTransform::GetNRows();j++)
+ fIndex[i][j]=fgStaticIndex[i][j];
+ }
+
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::CreateIndex","Index")
+ <<"Index successfully taken from static copy."<<ENDLOG;
+ }
+ fIndexCreated=kTRUE;
+ return kTRUE;
+}
+
+AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliDigits2Memory(UInt_t & nrow,Int_t event)
+{
+ //Read data from AliROOT file into memory, and store it in the HLT data format.
+ //Returns a pointer to the data.
+
+ AliHLTTPCDigitRowData *data = 0;
+ nrow=0;
+
+ if(!fInAli){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
+ <<"No Input avalible: Pointer to fInAli == NULL"<<ENDLOG;
+ return 0;
+ }
+
+#ifndef use_newio
+ if(!fInAli->IsOpen()){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","File")
+ <<"No Input avalible: TFile not opened"<<ENDLOG;
+ return 0;
+ }
+#endif
+
+ if(!fDigitsTree)
+ if(!GetDigitsTree(event)) return 0;
+
+ UShort_t dig;
+ Int_t time,pad,sector,row;
+ Int_t lslice,lrow;
+ Int_t nrows=0;
+ Int_t ndigitcount=0;
+ Int_t entries = (Int_t)fDigitsTree->GetEntries();
+ if(entries==0) {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2Memory","ndigits")
+ <<"No TPC digits (entries==0)!"<<ENDLOG;
+ nrow = (UInt_t)(fRowMax-fRowMin+1);
+ Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
+ data=(AliHLTTPCDigitRowData*) Allocate(size);
+ AliHLTTPCDigitRowData *tempPt = data;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ tempPt->fRow = r;
+ tempPt->fNDigit = 0;
+ tempPt++;
+ }
+ return data;
+ }
+
+ Int_t * ndigits = new Int_t[fRowMax+1];
+ Float_t xyz[3];
+
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t n=fIndex[fSlice][r];
+ if(n!=-1){ //data on that row
+ fDigitsTree->GetEvent(n);
+ fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+
+ if(lrow!=r){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
+ <<AliHLTTPCLog::kDec<<"Rows in slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+ continue;
+ }
+
+ ndigits[lrow] = 0;
+ fDigits->First();
+ do {
+ time=fDigits->CurrentRow();
+ pad=fDigits->CurrentColumn();
+ dig = fDigits->GetDigit(time,pad);
+ if(dig <= fParam->GetZeroSup()) continue;
+ if(dig >= AliHLTTPCTransform::GetADCSat())
+ dig = AliHLTTPCTransform::GetADCSat();
+
+ AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+ // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ // continue; // why 230???
+
+ ndigits[lrow]++; //for this row only
+ ndigitcount++; //total number of digits to be published
+
+ } while (fDigits->Next());
+ //cout << lrow << " " << ndigits[lrow] << " - " << ndigitcount << endl;
+ }
+ nrows++;
+ }
+
+ Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+ + nrows*sizeof(AliHLTTPCDigitRowData);
+
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliDigits2Memory","Digits")
+ <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+
+ data=(AliHLTTPCDigitRowData*) Allocate(size);
+ nrow = (UInt_t)nrows;
+ AliHLTTPCDigitRowData *tempPt = data;
+
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t n=fIndex[fSlice][r];
+ tempPt->fRow = r;
+ tempPt->fNDigit = 0;
+
+ if(n!=-1){//data on that row
+ fDigitsTree->GetEvent(n);
+ fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+ if(lrow!=r){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2Memory","Row")
+ <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+ continue;
+ }
+
+ tempPt->fNDigit = ndigits[lrow];
+
+ Int_t localcount=0;
+ fDigits->First();
+ do {
+ time=fDigits->CurrentRow();
+ pad=fDigits->CurrentColumn();
+ dig = fDigits->GetDigit(time,pad);
+ if (dig <= fParam->GetZeroSup()) continue;
+ if(dig >= AliHLTTPCTransform::GetADCSat())
+ dig = AliHLTTPCTransform::GetADCSat();
+
+ //Exclude data outside cone:
+ AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+ // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ // continue; // why 230???
+
+ if(localcount >= ndigits[lrow])
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliDigits2Binary","Memory")
+ <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+ <<ndigits[lrow]<<ENDLOG;
+
+ tempPt->fDigitData[localcount].fCharge=dig;
+ tempPt->fDigitData[localcount].fPad=pad;
+ tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+ tempPt->fDigitData[localcount].fTrackID[0] = fDigits->GetTrackID(time,pad,0);
+ tempPt->fDigitData[localcount].fTrackID[1] = fDigits->GetTrackID(time,pad,1);
+ tempPt->fDigitData[localcount].fTrackID[2] = fDigits->GetTrackID(time,pad,2);
+#endif
+ localcount++;
+ } while (fDigits->Next());
+ }
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliHLTTPCDigitRowData)
+ + ndigits[lrow]*sizeof(AliHLTTPCDigitData);
+ tmp += size;
+ tempPt = (AliHLTTPCDigitRowData*)tmp;
+ }
+ delete [] ndigits;
+ return data;
+}
+
+AliHLTTPCDigitRowData * AliHLTTPCFileHandler::AliAltroDigits2Memory(UInt_t & nrow,Int_t event,Bool_t eventmerge)
+{
+ //Read data from AliROOT file into memory, and store it in the HLT data format.
+ //Returns a pointer to the data.
+ //This functions filter out single timebins, which is noise. The timebins which
+ //are removed are timebins which have the 4 zero neighbours;
+ //(pad-1,time),(pad+1,time),(pad,time-1),(pad,time+1).
+
+ AliHLTTPCDigitRowData *data = 0;
+ nrow=0;
+
+ if(!fInAli){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
+ <<"No Input avalible: Pointer to TFile == NULL"<<ENDLOG;
+ return 0;
+ }
+#ifndef use_newio
+ if(!fInAli->IsOpen()){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","File")
+ <<"No Input avalible: TFile not opened"<<ENDLOG;
+ return 0;
+ }
+#endif
+ if(eventmerge == kTRUE && event >= 1024)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","TrackIDs")
+ <<"Too many events if you want to merge!"<<ENDLOG;
+ return 0;
+ }
+ delete fDigits;
+ fDigits=0;
+#ifdef use_newio
+ /* Dont understand why we have to do
+ reload the tree, but otherwise the code crashes */
+ fDigitsTree=0;
+ if(!GetDigitsTree(event)) return 0;
+#else
+ if(!fDigitsTree){
+ if(!GetDigitsTree(event)) return 0;
+ }
+#endif
+
+ UShort_t dig;
+ Int_t time,pad,sector,row;
+ Int_t nrows=0;
+ Int_t ndigitcount=0;
+ Int_t entries = (Int_t)fDigitsTree->GetEntries();
+ if(entries==0) {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliAltroDigits2Memory","ndigits")
+ <<"No TPC digits (entries==0)!"<<ENDLOG;
+ nrow = (UInt_t)(fRowMax-fRowMin+1);
+ Int_t size = nrow*sizeof(AliHLTTPCDigitRowData);
+ data=(AliHLTTPCDigitRowData*) Allocate(size);
+ AliHLTTPCDigitRowData *tempPt = data;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ tempPt->fRow = r;
+ tempPt->fNDigit = 0;
+ tempPt++;
+ }
+ return data;
+ }
+ Int_t * ndigits = new Int_t[fRowMax+1];
+ Int_t lslice,lrow;
+ Int_t zerosupval=AliHLTTPCTransform::GetZeroSup();
+ Float_t xyz[3];
+
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t n=fIndex[fSlice][r];
+
+ ndigits[r] = 0;
+
+ if(n!=-1){//data on that row
+ fDigitsTree->GetEvent(n);
+ fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+ //cout << lslice << " " << fSlice << " " << lrow << " " << r << " " << sector << " " << row << endl;
+ if((lslice!=fSlice)||(lrow!=r)){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
+ <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+ continue;
+ }
+
+ fDigits->ExpandBuffer();
+ fDigits->ExpandTrackBuffer();
+ for(Int_t i=0; i<fDigits->GetNCols(); i++){
+ for(Int_t j=0; j<fDigits->GetNRows(); j++){
+ pad=i;
+ time=j;
+ dig = fDigits->GetDigitFast(time,pad);
+ if(dig <= zerosupval) continue;
+ if(dig >= AliHLTTPCTransform::GetADCSat())
+ dig = AliHLTTPCTransform::GetADCSat();
+
+ //Check for single timebins, and remove them because they are noise for sure.
+ if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+
+ //Boundaries:
+ if(i==0) //pad==0
+ {
+ if(j < fDigits->GetNRows()-1 && j > 0)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+ }
+ else if(j > 0)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+ }
+ }
+ if(j==0)
+ {
+ if(i < fDigits->GetNCols()-1 && i > 0)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+ continue;
+ }
+ else if(i > 0)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+ continue;
+ }
+ }
+
+ if(i==fDigits->GetNCols()-1)
+ {
+ if(j>0 && j<fDigits->GetNRows()-1)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ else if(j==0 && j<fDigits->GetNRows()-1)
+ {
+ if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ else
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ }
+
+ if(j==fDigits->GetNRows()-1)
+ {
+ if(i>0 && i<fDigits->GetNCols()-1)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ else if(i==0 && fDigits->GetNCols()-1)
+ {
+ if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ else
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ }
+
+ AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+ // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ // continue;
+
+ ndigits[lrow]++; //for this row only
+ ndigitcount++; //total number of digits to be published
+ }
+ }
+ }
+ nrows++;
+ }
+
+ Int_t size = sizeof(AliHLTTPCDigitData)*ndigitcount
+ + nrows*sizeof(AliHLTTPCDigitRowData);
+
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Digits")
+ <<AliHLTTPCLog::kDec<<"Found "<<ndigitcount<<" Digits"<<ENDLOG;
+
+ data=(AliHLTTPCDigitRowData*) Allocate(size);
+ nrow = (UInt_t)nrows;
+ AliHLTTPCDigitRowData *tempPt = data;
+
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t n=fIndex[fSlice][r];
+ tempPt->fRow = r;
+ tempPt->fNDigit = 0;
+ if(n!=-1){ //no data on that row
+ fDigitsTree->GetEvent(n);
+ fParam->AdjustSectorRow(fDigits->GetID(),sector,row);
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+
+ if(lrow!=r){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliAltroDigits2Memory","Row")
+ <<AliHLTTPCLog::kDec<<"Rows on slice " << fSlice << " dont match "<<lrow<<" "<<r<<ENDLOG;
+ continue;
+ }
+
+ tempPt->fNDigit = ndigits[lrow];
+
+ Int_t localcount=0;
+ fDigits->ExpandBuffer();
+ fDigits->ExpandTrackBuffer();
+ for(Int_t i=0; i<fDigits->GetNCols(); i++){
+ for(Int_t j=0; j<fDigits->GetNRows(); j++){
+ pad=i;
+ time=j;
+ dig = fDigits->GetDigitFast(time,pad);
+ if(dig <= zerosupval) continue;
+ if(dig >= AliHLTTPCTransform::GetADCSat())
+ dig = AliHLTTPCTransform::GetADCSat();
+
+ //Check for single timebins, and remove them because they are noise for sure.
+ if(i>0 && i<fDigits->GetNCols()-1 && j>0 && j<fDigits->GetNRows()-1)
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+
+ //Boundaries:
+ if(i==0) //pad ==0
+ {
+ if(j < fDigits->GetNRows()-1 && j > 0)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+ }
+ else if(j > 0)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval)
+ continue;
+ }
+ }
+ if(j==0)
+ {
+ if(i < fDigits->GetNCols()-1 && i > 0)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+ continue;
+ }
+ else if(i > 0)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval)
+ continue;
+ }
+ }
+
+ if(i == fDigits->GetNCols()-1)
+ {
+ if(j>0 && j<fDigits->GetNRows()-1)
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ else if(j==0 && j<fDigits->GetNRows()-1)
+ {
+ if(fDigits->GetDigitFast(time+1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ else
+ {
+ if(fDigits->GetDigitFast(time-1,pad)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad-1)<=zerosupval)
+ continue;
+ }
+ }
+ if(j==fDigits->GetNRows()-1)
+ {
+ if(i>0 && i<fDigits->GetNCols()-1)
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ else if(i==0 && fDigits->GetNCols()-1)
+ {
+ if(fDigits->GetDigitFast(time,pad+1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ else
+ {
+ if(fDigits->GetDigitFast(time,pad-1)<=zerosupval &&
+ fDigits->GetDigitFast(time-1,pad)<=zerosupval)
+ continue;
+ }
+ }
+
+ AliHLTTPCTransform::Raw2Local(xyz,sector,row,pad,time);
+ // if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2]))
+ // continue;
+
+ if(localcount >= ndigits[lrow])
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCFileHandler::AliAltroDigits2Binary","Memory")
+ <<AliHLTTPCLog::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
+ <<ndigits[lrow]<<ENDLOG;
+
+ tempPt->fDigitData[localcount].fCharge=dig;
+ tempPt->fDigitData[localcount].fPad=pad;
+ tempPt->fDigitData[localcount].fTime=time;
+#ifdef do_mc
+ tempPt->fDigitData[localcount].fTrackID[0] = (fDigits->GetTrackIDFast(time,pad,0)-2);
+ tempPt->fDigitData[localcount].fTrackID[1] = (fDigits->GetTrackIDFast(time,pad,1)-2);
+ tempPt->fDigitData[localcount].fTrackID[2] = (fDigits->GetTrackIDFast(time,pad,2)-2);
+ if(eventmerge == kTRUE) //careful track mc info will be touched
+ {//Event are going to be merged, so event number is stored in the upper 10 bits.
+ tempPt->fDigitData[localcount].fTrackID[0] += 128; //leave some room
+ tempPt->fDigitData[localcount].fTrackID[1] += 128; //for neg. numbers
+ tempPt->fDigitData[localcount].fTrackID[2] += 128;
+ tempPt->fDigitData[localcount].fTrackID[0] += ((event&0x3ff)<<22);
+ tempPt->fDigitData[localcount].fTrackID[1] += ((event&0x3ff)<<22);
+ tempPt->fDigitData[localcount].fTrackID[2] += ((event&0x3ff)<<22);
+ }
+#endif
+ localcount++;
+ }
+ }
+ }
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliHLTTPCDigitRowData)
+ + ndigits[r]*sizeof(AliHLTTPCDigitData);
+ tmp += size;
+ tempPt = (AliHLTTPCDigitRowData*)tmp;
+ }
+ delete [] ndigits;
+ return data;
+}
+
+Bool_t AliHLTTPCFileHandler::GetDigitsTree(Int_t event)
+{
+ //Connects to the TPC digit tree in the AliROOT file.
+#ifdef use_newio
+ AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+ if(!tpcLoader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::GetDigitsTree","File")
+ <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ fInAli->GetEvent(event);
+ tpcLoader->LoadDigits();
+ fDigitsTree = tpcLoader->TreeD();
+#else
+ fInAli->cd();
+ Char_t dname[100];
+ sprintf(dname,"TreeD_%s_%d",AliHLTTPCTransform::GetParamName(),event);
+ fDigitsTree = (TTree*)fInAli->Get(dname);
+#endif
+ if(!fDigitsTree)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::GetDigitsTree","Digits Tree")
+ <<AliHLTTPCLog::kHex<<"Error getting digitstree "<<(void*)fDigitsTree<<ENDLOG;
+ return kFALSE;
+ }
+ fDigitsTree->GetBranch("Segment")->SetAddress(&fDigits);
+
+ if(!fIndexCreated) return CreateIndex();
+ else return kTRUE;
+}
+
+void AliHLTTPCFileHandler::AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *new_digitsfile)
+{
+ //Write the data stored in rowPt, into a new AliROOT file.
+ //The data is stored in the AliROOT format
+ //This is specially a nice thing if you have modified data, and wants to run it
+ //through the offline reconstruction chain.
+ //The arguments is a pointer to the data, and the name of the new AliROOT file.
+ //Remember to pass the original AliROOT file (the one that contains the original
+ //simulated data) to this object, in order to retrieve the MC id's of the digits.
+
+ if(!fInAli)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ <<"No rootfile "<<ENDLOG;
+ return;
+ }
+ if(!fParam)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ <<"No parameter object. Run on rootfile "<<ENDLOG;
+ return;
+ }
+
+#ifdef use_newio
+ //Get the original digitstree:
+ AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+ if(!tpcLoader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+ return;
+ }
+ tpcLoader->LoadDigits();
+ TTree *t=tpcLoader->TreeD();
+
+ AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
+ old_array->Setup(fParam);
+ old_array->SetClass("AliSimDigits");
+
+ Bool_t ok = old_array->ConnectTree(t);
+ if(!ok)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ << "No digits tree object" << ENDLOG;
+ return;
+ }
+
+ tpcLoader->SetDigitsFileName(new_digitsfile);
+ tpcLoader->MakeDigitsContainer();
+
+ //setup a new one, or connect it to the existing one:
+ AliTPCDigitsArray *arr = new AliTPCDigitsArray();
+ arr->SetClass("AliSimDigits");
+ arr->Setup(fParam);
+ arr->MakeTree(tpcLoader->TreeD());
+#else
+
+ //Get the original digitstree:
+ Char_t dname[100];
+ sprintf(dname,"TreeD_%s_0",AliHLTTPCTransform::GetParamName());
+
+ fInAli->cd();
+ AliTPCDigitsArray *old_array = new AliTPCDigitsArray();
+ old_array->Setup(fParam);
+ old_array->SetClass("AliSimDigits");
+
+ Bool_t ok = old_array->ConnectTree(dname);
+ if(!ok)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ <<"No digits tree object." <<ENDLOG;
+ return;
+ }
+
+ Bool_t create=kFALSE;
+ TFile *digFile;
+
+ if(gSystem->AccessPathName(new_digitsfile))
+ {
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCFileHandler::AliDigits2RootFile","File")
+ <<"Creating new file "<<new_digitsfile<<ENDLOG;
+ create = kTRUE;
+ digFile = TFile::Open(new_digitsfile,"RECREATE");
+ fParam->Write(fParam->GetTitle());
+ }
+ else
+ {
+ create = kFALSE;
+ digFile = TFile::Open(new_digitsfile,"UPDATE");
+
+ }
+ if(!digFile->IsOpen())
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
+ <<"Error opening rootfile "<<new_digitsfile<<ENDLOG;
+ return;
+ }
+
+ digFile->cd();
+
+ //setup a new one, or connect it to the existing one:
+ AliTPCDigitsArray *arr = new AliTPCDigitsArray();
+ arr->SetClass("AliSimDigits");
+ arr->Setup(fParam);
+ if(create)
+ arr->MakeTree();
+ else
+ {
+ Bool_t ok = arr->ConnectTree(dname);
+ if(!ok)
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFileHandler::AliDigits2RootFile","Rootfile")
+ <<"No digits tree object in existing file"<<ENDLOG;
+ return;
+ }
+ }
+#endif
+
+ Int_t digcounter=0,trackID[3];
+
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+
+ if((Int_t)rowPt->fRow != i)
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+ <<"Mismatching row numbering "<<(Int_t)rowPt->fRow<<" "<<i<<ENDLOG;
+
+ Int_t sector,row;
+ AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
+
+ AliSimDigits *old_dig = (AliSimDigits*)old_array->LoadRow(sector,row);
+ AliSimDigits * dig = (AliSimDigits*)arr->CreateRow(sector,row);
+ old_dig->ExpandBuffer();
+ old_dig->ExpandTrackBuffer();
+ dig->ExpandBuffer();
+ dig->ExpandTrackBuffer();
+
+ if(!old_dig)
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+ <<"No padrow " << sector << " " << row <<ENDLOG;
+
+ AliHLTTPCDigitData *digPt = rowPt->fDigitData;
+ digcounter=0;
+ for(UInt_t j=0; j<rowPt->fNDigit; j++)
+ {
+ Short_t charge = (Short_t)digPt[j].fCharge;
+ Int_t pad = (Int_t)digPt[j].fPad;
+ Int_t time = (Int_t)digPt[j].fTime;
+
+ if(charge == 0) //Only write the digits that has not been removed
+ {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliDigits2RootFile","Data")
+ <<"Zero charge" <<ENDLOG;
+ continue;
+ }
+
+ digcounter++;
+
+ //Tricks to get and set the correct track id's.
+ for(Int_t t=0; t<3; t++)
+ {
+ Int_t label = old_dig->GetTrackIDFast(time,pad,t);
+ if(label > 1)
+ trackID[t] = label - 2;
+ else if(label==0)
+ trackID[t] = -2;
+ else
+ trackID[t] = -1;
+ }
+
+ dig->SetDigitFast(charge,time,pad);
+
+ for(Int_t t=0; t<3; t++)
+ ((AliSimDigits*)dig)->SetTrackIDFast(trackID[t],time,pad,t);
+
+ }
+ //cout<<"Wrote "<<digcounter<<" on row "<<i<<endl;
+ UpdateRowPointer(rowPt);
+ arr->StoreRow(sector,row);
+ arr->ClearRow(sector,row);
+ old_array->ClearRow(sector,row);
+ }
+
+ char treeName[100];
+ sprintf(treeName,"TreeD_%s_0",fParam->GetTitle());
+
+#ifdef use_newio
+ arr->GetTree()->SetName(treeName);
+ arr->GetTree()->AutoSave();
+ tpcLoader->WriteDigits("OVERWRITE");
+#else
+ digFile->cd();
+ arr->GetTree()->SetName(treeName);
+ arr->GetTree()->AutoSave();
+ digFile->Close();
+#endif
+ delete arr;
+ delete old_array;
+}
+
+///////////////////////////////////////// Point IO
+Bool_t AliHLTTPCFileHandler::AliPoints2Binary(Int_t eventn)
+{
+ //points to binary
+ Bool_t out = kTRUE;
+ UInt_t npoint;
+ AliHLTTPCSpacePointData *data = AliPoints2Memory(npoint,eventn);
+ out = Memory2Binary(npoint,data);
+ Free();
+ return out;
+}
+
+AliHLTTPCSpacePointData * AliHLTTPCFileHandler::AliPoints2Memory(UInt_t & npoint,Int_t eventn)
+{
+ //points to memory
+ AliHLTTPCSpacePointData *data = 0;
+ npoint=0;
+ if(!fInAli){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+ <<"No Input avalible: no object fInAli"<<ENDLOG;
+ return 0;
+ }
+#ifndef use_newio
+ if(!fInAli->IsOpen()){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+ <<"No Input avalible: TFile not opend"<<ENDLOG;
+ return 0;
+ }
+#endif
+
+ TDirectory *savedir = gDirectory;
+#ifdef use_newio
+ AliLoader* tpcLoader = fInAli->GetLoader("TPCLoader");
+ if(!tpcLoader){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+ <<"Pointer to AliLoader for TPC = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ fInAli->GetEvent(eventn);
+ tpcLoader->LoadRecPoints();
+
+ AliTPCClustersArray carray;
+ carray.Setup(fParam);
+ carray.SetClusterType("AliTPCcluster");
+ Bool_t clusterok = carray.ConnectTree(tpcLoader->TreeR());
+#else
+ fInAli->cd();
+
+ Char_t cname[100];
+ sprintf(cname,"TreeC_TPC_%d",eventn);
+ AliTPCClustersArray carray;
+ carray.Setup(fParam);
+ carray.SetClusterType("AliTPCcluster");
+ Bool_t clusterok = carray.ConnectTree(cname);
+#endif
+
+ if(!clusterok) return 0;
+
+ AliTPCClustersRow ** clusterrow =
+ new AliTPCClustersRow*[ (int)carray.GetTree()->GetEntries()];
+ Int_t *rows = new int[ (int)carray.GetTree()->GetEntries()];
+ Int_t *sects = new int[ (int)carray.GetTree()->GetEntries()];
+ Int_t sum=0;
+
+ Int_t lslice,lrow;
+ for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
+ AliSegmentID *s = carray.LoadEntry(i);
+ Int_t sector,row;
+ fParam->AdjustSectorRow(s->GetID(),sector,row);
+ rows[i] = row;
+ sects[i] = sector;
+ clusterrow[i] = 0;
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+ if(fSlice != lslice || lrow<fRowMin || lrow>fRowMax) continue;
+ clusterrow[i] = carray.GetRow(sector,row);
+ if(clusterrow[i])
+ sum+=clusterrow[i]->GetArray()->GetEntriesFast();
+ }
+ UInt_t size = sum*sizeof(AliHLTTPCSpacePointData);
+
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCFileHandler::AliPoints2Memory","File")
+ <<AliHLTTPCLog::kDec<<"Found "<<sum<<" SpacePoints"<<ENDLOG;
+
+ data = (AliHLTTPCSpacePointData *) Allocate(size);
+ npoint = sum;
+ UInt_t n=0;
+ Int_t pat=fPatch;
+ if(fPatch==-1)
+ pat=0;
+ for(Int_t i=0; i<carray.GetTree()->GetEntries(); i++){
+ if(!clusterrow[i]) continue;
+ Int_t row = rows[i];
+ Int_t sector = sects[i];
+ AliHLTTPCTransform::Sector2Slice(lslice,lrow,sector,row);
+ Int_t entries_in_row = clusterrow[i]->GetArray()->GetEntriesFast();
+ for(Int_t j = 0;j<entries_in_row;j++){
+ AliTPCcluster *c = (AliTPCcluster*)(*clusterrow[i])[j];
+ data[n].fZ = c->GetZ();
+ data[n].fY = c->GetY();
+ data[n].fX = fParam->GetPadRowRadii(sector,row);
+ data[n].fCharge = (UInt_t)c->GetQ();
+ data[n].fID = n+((fSlice&0x7f)<<25)+((pat&0x7)<<22);//uli
+ data[n].fPadRow = lrow;
+ data[n].fSigmaY2 = c->GetSigmaY2();
+ data[n].fSigmaZ2 = c->GetSigmaZ2();
+#ifdef do_mc
+ data[n].fTrackID[0] = c->GetLabel(0);
+ data[n].fTrackID[1] = c->GetLabel(1);
+ data[n].fTrackID[2] = c->GetLabel(2);
+#endif
+ if(fMC) fprintf(fMC,"%d %d\n",data[n].fID,c->GetLabel(0));
+ n++;
+ }
+ }
+ for(Int_t i=0;i<carray.GetTree()->GetEntries();i++){
+ Int_t row = rows[i];
+ Int_t sector = sects[i];
+ if(carray.GetRow(sector,row))
+ carray.ClearRow(sector,row);
+ }
+
+ delete [] clusterrow;
+ delete [] rows;
+ delete [] sects;
+ savedir->cd();
+
+ return data;
+}
+
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCFILEHANDLER_H
+#define ALIHLTTPCFILEHANDLER_H
+
+#include "AliHLTTPCMemHandler.h"
+
+class TClonesArray;
+
+#include <AliSimDigits.h>
+#include <AliTPCParam.h>
+#ifdef use_newio
+#include <AliRunLoader.h>
+#endif
+
+#include <TObject.h>
+#include <TFile.h>
+#include <TTree.h>
+
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCTrackArray;
+
+class AliHLTTPCFileHandler:public AliHLTTPCMemHandler{
+
+ protected:
+#ifdef use_newio
+ AliRunLoader *fInAli;//!
+ Bool_t fUseRunLoader; //use runloader
+#else
+ TFile *fInAli;//!
+#endif
+
+ AliTPCParam *fParam;//!
+ AliSimDigits *fDigits;//!
+
+ TTree *fDigitsTree;//!
+ FILE *fMC;//!
+
+ Bool_t fIndexCreated; //is index created
+ Int_t fIndex[36][159]; //stores index over digitstree
+ //for faster access w/o ASVVERSION
+ Bool_t fUseStaticIndex; //take static index
+ static Bool_t fgStaticIndexCreated; //global index created
+ static Int_t fgStaticIndex[36][159]; //global index
+
+ virtual Bool_t SetAliInput();
+ Bool_t GetDigitsTree(Int_t event);
+ Bool_t CreateIndex(); //create the index
+
+ public:
+ AliHLTTPCFileHandler(Bool_t b=kFALSE);
+ ~AliHLTTPCFileHandler();
+
+ void FreeDigitsTree();
+ static void CleanStaticIndex();
+ static Int_t SaveStaticIndex(Char_t *prefix=0,Int_t event=0);
+ static Int_t LoadStaticIndex(Char_t *prefix=0,Int_t event=0);
+
+ Bool_t SetAliInput(Char_t *name);
+ Bool_t SetAliInput(TFile *file);
+#ifdef use_newio
+ Bool_t SetAliInput(AliRunLoader *runLoader);
+#else
+#endif
+ void CloseAliInput();
+ Bool_t IsDigit(Int_t event);
+
+ Bool_t SetMCOutput(Char_t *name);
+ Bool_t SetMCOutput(FILE *file);
+ void CloseMCOutput();
+
+ //Digit IO
+ Bool_t AliDigits2Binary(Int_t event=0,Bool_t altro=kFALSE);
+ AliHLTTPCDigitRowData *AliDigits2Memory(UInt_t & nrow,Int_t event=0); //Allocates Memory
+ AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & nrow,Int_t event=0,Bool_t eventmerge=kFALSE);
+ //Allocates Memory
+ Bool_t AliDigits2CompBinary(Int_t event=0,Bool_t altro=kFALSE);
+ void AliDigits2RootFile(AliHLTTPCDigitRowData *rowPt,Char_t *new_digitsfile);
+
+ //Point IO
+ Bool_t AliPoints2Binary(Int_t eventn=0);
+ AliHLTTPCSpacePointData *AliPoints2Memory(UInt_t & npoint,Int_t eventn=0);//Allocates Memory
+
+ ClassDef(AliHLTTPCFileHandler,1) //Filehandler class
+};
+
+#endif
--- /dev/null
+// @(#) $Id$
+
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+/** \class AliHLTTPCFitter
+<pre>
+//_____________________________________________________________
+// AliHLTTPCFitter
+//
+// Fit class HLT for helix
+</pre>
+*/
+
+#include <math.h>
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCFitter.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCMemHandler.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPC.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCFitter)
+
+
+AliHLTTPCFitter::AliHLTTPCFitter()
+{
+ //constructor
+ fTrack=0;
+ fVertex=0;
+ memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+}
+
+AliHLTTPCFitter::AliHLTTPCFitter(AliHLTTPCVertex *vertex,Bool_t vertexconstraint)
+{
+ //constructor
+ fTrack=0;
+ fVertex = vertex;
+ fVertexConstraint=vertexconstraint;
+ memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
+}
+
+AliHLTTPCFitter::~AliHLTTPCFitter()
+{
+ //destructor
+ for(Int_t i=0; i<36; i++)
+ {
+ for(Int_t j=0; j<6; j++)
+ {
+ if(fClusters[i][j])
+ delete [] fClusters[i][j];
+ }
+ }
+}
+
+void AliHLTTPCFitter::LoadClusters(Char_t *path,Int_t event,Bool_t sp)
+{
+ //load clusters
+ Char_t fname[256];
+ AliHLTTPCMemHandler *clusterfile[36][6];
+ for(Int_t s=0; s<=35; s++)
+ {
+ for(Int_t p=0; p<6; p++)
+ {
+ Int_t patch;
+ if(sp==kTRUE)
+ patch=-1;
+ else
+ patch=p;
+ if(fClusters[s][p])
+ delete fClusters[s][p];
+ fClusters[s][p] = 0;
+ clusterfile[s][p] = new AliHLTTPCMemHandler();
+ sprintf(fname,"%s/points_%d_%d_%d.raw",path,event,s,patch);
+ if(!clusterfile[s][p]->SetBinaryInput(fname))
+ {
+ delete clusterfile[s][p];
+ clusterfile[s][p] = 0;
+ continue;
+ }
+ fClusters[s][p] = (AliHLTTPCSpacePointData*)clusterfile[s][p]->Allocate();
+ clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
+ clusterfile[s][p]->CloseBinaryInput();
+ if(sp==kTRUE)
+ break;
+ }
+ }
+}
+
+void AliHLTTPCFitter::SortTrackClusters(AliHLTTPCTrack *track) const
+{
+ //Sort the internal cluster list in each track with respect to row numbering.
+ //This may be necessary when no conventional track follower has been
+ //applied, in which the cluster list has been maintained in a more
+ //arbitrary fashion.
+
+ Int_t nhits = track->GetNHits();
+ Int_t *ids = (Int_t*)track->GetHitNumbers();
+ Int_t *origids = new Int_t[nhits];
+ Int_t *mk = new Int_t[nhits];
+ Int_t k;
+
+ for(k=0; k<nhits; k++) {origids[k] = ids[k]; mk[k] = -1;}
+
+ Int_t slice,patch,id,padrow,maxrow,maxk;
+ UInt_t pos;
+ for(Int_t j=0; j<nhits; j++)
+ {
+ maxrow=-1;
+ maxk=200;
+ for(k=0; k<nhits; k++)
+ {
+ id=ids[k];
+ if(id < 0) continue;
+ slice = (id>>25) & 0x7f;
+ patch = (id>>22) & 0x7;
+ pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+ padrow = points[pos].fPadRow;
+ if(padrow > maxrow)
+ {
+ maxrow = padrow;
+ maxk=k;
+ }
+ }
+ mk[j]=maxk;
+ ids[maxk]=-1;
+ }
+
+ for(k=0; k<nhits; k++)
+ ids[k] = origids[mk[k]];
+ delete [] origids;
+ delete [] mk;
+}
+
+Int_t AliHLTTPCFitter::FitHelix(AliHLTTPCTrack *track)
+{
+ //fit helix parameters
+ fTrack = track;
+ if(FitCircle())
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems during circle fit"<<ENDLOG;
+ return 1;
+ }
+ if(FitLine())
+ {
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems during line fit"<<ENDLOG;
+ return 1;
+ }
+ return 0;
+}
+
+Int_t AliHLTTPCFitter::FitCircle()
+{
+ //-----------------------------------------------------------------
+ //Fits circle parameters using algorithm
+ //described by ChErnov and Oskov in Computer Physics
+ //Communications.
+ //
+ //Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin
+ //Moved to C by Pablo Yepes
+ //Moved to AliROOT by ASV.
+ //------------------------------------------------------------------
+
+ Double_t wsum = 0.0 ;
+ Double_t xav = 0.0 ;
+ Double_t yav = 0.0 ;
+
+ //
+ // Loop over hits calculating average
+ Double_t * fXYWeight = new Double_t[(fTrack->GetNHits())];
+ UInt_t *hitnum = fTrack->GetHitNumbers();
+ for(Int_t i=0; i<fTrack->GetNHits(); i++)
+ {
+ UInt_t id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+ fXYWeight[i] = 1./ (Double_t)(points[pos].fSigmaY2 + points[pos].fSigmaY2);
+ wsum += fXYWeight[i];
+ xav += fXYWeight[i]*points[pos].fX;
+ yav += fXYWeight[i]*points[pos].fY;
+ }
+ if (fVertexConstraint == kTRUE)
+ {
+ wsum += fVertex->GetXYWeight() ;
+ xav += fVertex->GetX() ;
+ yav += fVertex->GetY() ;
+ }
+
+ xav = xav / wsum ;
+ yav = yav / wsum ;
+//
+// CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
+//
+ Double_t xxav = 0.0 ;
+ Double_t xyav = 0.0 ;
+ Double_t yyav = 0.0 ;
+ Double_t xi, yi ;
+
+ for(Int_t i=0; i<fTrack->GetNHits(); i++)
+ {
+ UInt_t id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+
+ xi = points[pos].fX -xav;
+ yi = points[pos].fY - yav ;
+ xxav += xi * xi * fXYWeight[i];
+ xyav += xi * yi * fXYWeight[i];
+ yyav += yi * yi * fXYWeight[i];
+ }
+
+ if (fVertexConstraint == kTRUE)
+ {
+ xi = fVertex->GetX() - xav ;
+ yi = fVertex->GetY() - yav ;
+ xxav += xi * xi * fVertex->GetXYWeight() ;
+ xyav += xi * yi * fVertex->GetXYWeight() ;
+ yyav += yi * yi * fVertex->GetXYWeight() ;
+ }
+ xxav = xxav / wsum ;
+ xyav = xyav / wsum ;
+ yyav = yyav / wsum ;
+//
+//--> ROTATE COORDINATES SO THAT <XY> = 0
+//
+//--> SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
+//--> & > ==> NEW : (XXAV-YYAV) > 0
+//--> SIGN(S) = SIGN(XYAV) >
+
+ Double_t a = fabs( xxav - yyav ) ;
+ Double_t b = 4.0 * xyav * xyav ;
+
+ Double_t asqpb = a * a + b ;
+ Double_t rasqpb = sqrt ( asqpb) ;
+
+ Double_t splus = 1.0 + a / rasqpb ;
+ Double_t sminus = b / (asqpb * splus) ;
+
+ splus = sqrt (0.5 * splus ) ;
+ sminus = sqrt (0.5 * sminus) ;
+//
+//-> FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
+//
+ Double_t sinrot, cosrot ;
+ if ( xxav <= yyav ) {
+ cosrot = sminus ;
+ sinrot = splus ;
+ }
+ else {
+ cosrot = splus ;
+ sinrot = sminus ;
+ }
+//
+//-> REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
+//
+ if ( xyav < 0.0 ) sinrot = - sinrot ;
+//
+//--> WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
+//--> TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
+//--> OUTWARD FROM THE ORGIN. WE ARE FREE TO CHANGE SIGNS OF BOTH
+//--> COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
+//
+//--> CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
+//
+ if ( cosrot*xav+sinrot*yav < 0.0 ) {
+ cosrot = -cosrot ;
+ sinrot = -sinrot ;
+ }
+//
+//-> NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
+//
+ Double_t rrav = xxav + yyav ;
+ Double_t rscale = sqrt(rrav) ;
+
+ xxav = 0.0 ;
+ yyav = 0.0 ;
+ xyav = 0.0 ;
+ Double_t xrrav = 0.0 ;
+ Double_t yrrav = 0.0 ;
+ Double_t rrrrav = 0.0 ;
+
+ Double_t xixi, yiyi, riri, wiriri, xold, yold ;
+
+ for(Int_t i=0; i<fTrack->GetNHits(); i++)
+ {
+ UInt_t id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+
+ xold = points[pos].fX - xav ;
+ yold = points[pos].fY - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = fXYWeight[i] * riri ;
+
+ xyav += fXYWeight[i] * xi * yi ;
+ xxav += fXYWeight[i] * xixi ;
+ yyav += fXYWeight[i] * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+//
+// Include vertex if required
+//
+ if (fVertexConstraint == kTRUE)
+ {
+ xold = fVertex->GetX() - xav ;
+ yold = fVertex->GetY() - yav ;
+ //
+ //--> ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
+ //
+ xi = ( cosrot * xold + sinrot * yold ) / rscale ;
+ yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
+
+ xixi = xi * xi ;
+ yiyi = yi * yi ;
+ riri = xixi + yiyi ;
+ wiriri = fVertex->GetXYWeight() * riri ;
+
+ xyav += fVertex->GetXYWeight() * xi * yi ;
+ xxav += fVertex->GetXYWeight() * xixi ;
+ yyav += fVertex->GetXYWeight() * yiyi ;
+
+ xrrav += wiriri * xi ;
+ yrrav += wiriri * yi ;
+ rrrrav += wiriri * riri ;
+ }
+ //
+ //
+ //
+ //--> DIVIDE BY WSUM TO MAKE AVERAGES
+ //
+ xxav = xxav / wsum ;
+ yyav = yyav / wsum ;
+ xrrav = xrrav / wsum ;
+ yrrav = yrrav / wsum ;
+ rrrrav = rrrrav / wsum ;
+ xyav = xyav / wsum ;
+
+ Int_t const kntry = 5 ;
+//
+//--> USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
+//--> DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
+//
+ Double_t xrrxrr = xrrav * xrrav ;
+ Double_t yrryrr = yrrav * yrrav ;
+ Double_t rrrrm1 = rrrrav - 1.0 ;
+ Double_t xxyy = xxav * yyav ;
+
+ Double_t c0 = rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
+ Double_t c1 = - rrrrm1 + xrrxrr + yrryrr - 4.0*xxyy ;
+ Double_t c2 = 4.0 + rrrrm1 - 4.0*xxyy ;
+ Double_t c4 = - 4.0 ;
+//
+//--> COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
+//
+ Double_t c2d = 2.0 * c2 ;
+ Double_t c4d = 4.0 * c4 ;
+//
+//--> 0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
+//
+// LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
+ Double_t lamda = 0.0 ;
+ Double_t dlamda = 0.0 ;
+//
+ Double_t chiscl = wsum * rscale * rscale ;
+ Double_t dlamax = 0.001 / chiscl ;
+
+ Double_t p, pd ;
+ for ( int itry = 1 ; itry <= kntry ; itry++ ) {
+ p = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
+ pd = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
+ dlamda = -p / pd ;
+ lamda = lamda + dlamda ;
+ if (fabs(dlamda)< dlamax) break ;
+ }
+
+ //Double_t chi2 = (Double_t)(chiscl * lamda) ;
+ //fTrack->SetChiSq1(chi2);
+ // Double_t dchisq = chiscl * dlamda ;
+ //
+ //--> NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
+ //
+ Double_t h11 = xxav - lamda ;
+ Double_t h14 = xrrav ;
+ Double_t h22 = yyav - lamda ;
+ Double_t h24 = yrrav ;
+ Double_t h34 = 1.0 + 2.0*lamda ;
+ if ( h11 == 0.0 || h22 == 0.0 ){
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCFitter::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
+ "Problems fitting circle"<<ENDLOG;
+ return 1 ;
+ }
+ Double_t rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
+
+ Double_t ratio, kappa, beta ;
+ if ( fabs(h22) > fabs(h24) ) {
+ ratio = h24 / h22 ;
+ rootsq = ratio * ratio + rootsq ;
+ kappa = 1.0 / sqrt(rootsq) ;
+ beta = - ratio * kappa ;
+ }
+ else {
+ ratio = h22 / h24 ;
+ rootsq = 1.0 + ratio * ratio * rootsq ;
+ beta = 1.0 / sqrt(rootsq) ;
+ if ( h24 > 0 ) beta = - beta ;
+ kappa = -ratio * beta ;
+ }
+ Double_t alpha = - (h14/h11) * kappa ;
+//
+//--> transform these into the lab coordinate system
+//--> first get kappa and back to real dimensions
+//
+ Double_t kappa1 = kappa / rscale ;
+ Double_t dbro = 0.5 / kappa1 ;
+//
+//--> next rotate alpha and beta and scale
+//
+ Double_t alphar = (cosrot * alpha - sinrot * beta)* dbro ;
+ Double_t betar = (sinrot * alpha + cosrot * beta)* dbro ;
+//
+//--> then translate by (xav,yav)
+//
+ Double_t acent = (double)(xav - alphar) ;
+ Double_t bcent = (double)(yav - betar ) ;
+ Double_t radius = (double)dbro ;
+//
+// Get charge
+//
+ Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
+ fTrack->SetCharge(q);
+
+ //Set the first point on the track to the space point coordinates of the innermost track
+ //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
+ Double_t x0,y0,psi,pt ;
+ Int_t lastid=fTrack->GetNHits()-1;
+ UInt_t id = hitnum[lastid];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+ x0 = points[pos].fX;
+ y0 = points[pos].fY;
+ fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
+
+ //Set the remaining fit parameters
+ psi = (Double_t)atan2(bcent-y0,acent-x0) ;
+ psi = psi + q * 0.5F * AliHLTTPCTransform::Pi() ;
+ if ( psi < 0 ) psi = psi + 2*AliHLTTPCTransform::Pi();
+
+ pt = (Double_t)(AliHLTTPCTransform::GetBFact() * AliHLTTPCTransform::GetBField() * radius ) ;
+ fTrack->SetPsi(psi);
+ fTrack->SetPt(pt);
+ fTrack->SetRadius(radius);
+ fTrack->SetCenterX(acent);
+ fTrack->SetCenterY(bcent);
+//
+// Get errors from fast fit
+//
+ //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
+//
+ delete [] fXYWeight;
+ return 0 ;
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Fit Line in s-z plane
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliHLTTPCFitter::FitLine ( )
+{
+ //
+ //Initialization
+ //
+ Double_t sum = 0.F ;
+ Double_t ss = 0.F ;
+ Double_t sz = 0.F ;
+ Double_t sss = 0.F ;
+ Double_t ssz = 0.F ;
+ //
+ //find sum , sums ,sumz, sumss
+ //
+ Double_t dx, dy ;
+ Double_t radius = (Double_t)(fTrack->GetPt() / ( AliHLTTPCTransform::GetBFact() * AliHLTTPCTransform::GetBField() ) ) ;
+
+ Double_t * fS = new Double_t[(fTrack->GetNHits())];
+ Double_t *fZWeight = new Double_t[fTrack->GetNHits()];
+ UInt_t *hitnum = fTrack->GetHitNumbers();
+ if (0)//fVertexConstraint==kTRUE)
+ {
+ UInt_t id = hitnum[0];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+
+ dx = points[pos].fX - fVertex->GetX();
+ dy = points[pos].fY - fVertex->GetY();
+ }
+ else
+ {
+ UInt_t id = hitnum[0];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t posf = id&0x3fffff;
+ AliHLTTPCSpacePointData *pointsf = fClusters[slice][patch];
+ id = hitnum[(fTrack->GetNHits()-1)];
+ slice = (id>>25) & 0x7f;
+ patch = (id>>22) & 0x7;
+ UInt_t posl = id&0x3fffff;
+ AliHLTTPCSpacePointData *pointsl = fClusters[slice][patch];
+ dx = pointsf[posf].fX - pointsl[posl].fX;
+ dy = pointsf[posf].fY - pointsl[posl].fY;
+ }
+
+ Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
+ Double_t totals ;
+
+ if ( fabs(localPsi) < 1. )
+ {
+ totals = 2.0 * radius * asin ( localPsi ) ;
+ }
+ else
+ {
+ totals = 2.0 * radius * AliHLTTPCTransform::Pi() ;
+ }
+
+ Double_t dpsi,s;
+
+ for(Int_t i=0; i<fTrack->GetNHits(); i++)
+ {
+ UInt_t id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+
+ fZWeight[i] = 1./(Double_t)(points[pos].fSigmaZ2);
+ if(i>0)
+ {
+ id = hitnum[i-1];
+ slice = (id>>25) & 0x7f;
+ patch = (id>>22) & 0x7;
+ UInt_t lastpos = id&0x3fffff;
+ AliHLTTPCSpacePointData *lastpoints = fClusters[slice][patch];
+ dx = points[pos].fX -lastpoints[lastpos].fX;
+ dy = points[pos].fY -lastpoints[lastpos].fY;
+ dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
+ if(fabs(dpsi) > 1)
+ return 1;
+ fTrack->SetPsierr(dpsi);
+ s = fS[i-1] - 2.0 * radius * (Double_t)asin ( dpsi ) ;
+ fS[i]=s;
+ }
+ else
+ fS[i]=totals;
+
+ sum += fZWeight[i];
+ ss += fZWeight[i] * fS[i];
+ sz += fZWeight[i] * points[pos].fZ;
+ sss += fZWeight[i] * fS[i] * fS[i];
+ ssz += fZWeight[i] * fS[i] * points[pos].fZ;
+
+ }
+
+
+ Double_t chi2,det = sum * sss - ss * ss;
+ if ( fabs(det) < 1e-20)
+ {
+ chi2 = 99999.F ;
+ //fTrack->SetChiSq2(chi2);
+ return 0 ;
+ }
+
+ //Compute the best fitted parameters A,B
+ Double_t tanl,z0,dtanl,dz0;
+
+ tanl = (Double_t)((sum * ssz - ss * sz ) / det );
+ z0 = (Double_t)((sz * sss - ssz * ss ) / det );
+
+ fTrack->SetTgl(tanl);
+ fTrack->SetZ0(z0);
+
+ //calculate chi-square
+ chi2 = 0.;
+ Double_t r1 ;
+
+ for(Int_t i=0; i<fTrack->GetNHits(); i++)
+ {
+ UInt_t id = hitnum[i];
+ Int_t slice = (id>>25) & 0x7f;
+ Int_t patch = (id>>22) & 0x7;
+ UInt_t pos = id&0x3fffff;
+ AliHLTTPCSpacePointData *points = fClusters[slice][patch];
+ r1 = points[pos].fZ - tanl * fS[i] - z0 ;
+ chi2 += (Double_t) ( (Double_t)(fZWeight[i]) * (r1 * r1) );
+ }
+
+ //fTrack->SetChiSq2(chi2);
+ //
+ //calculate estimated variance
+ //varsq=chi/(double(n)-2.)
+ //calculate covariance matrix
+ //siga=sqrt(varsq*sxx/det)
+ //sigb=sqrt(varsq*sum/det)
+ //
+ dtanl = (Double_t) ( sum / det );
+ dz0 = (Double_t) ( sss / det );
+
+ fTrack->SetTglerr(dtanl);
+ fTrack->SetZ0err(dz0);
+ delete [] fZWeight;
+ delete [] fS;
+ return 0 ;
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCFITTER_H
+#define ALIHLTTPCFITTER_H
+
+//_____________________________________________________________
+// AliHLTTPCFitter
+//
+// Fit class HLT
+//
+// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
+
+class AliHLTTPCTrack;
+class AliHLTTPCVertex;
+class AliHLTTPCSpacePointData;
+
+class AliHLTTPCFitter {
+
+ public:
+ AliHLTTPCFitter();
+ AliHLTTPCFitter(AliHLTTPCVertex *vertex,Bool_t vertexconstraint=kTRUE);
+ virtual ~AliHLTTPCFitter();
+
+ void LoadClusters(Char_t *path,Int_t event=0,Bool_t sp=kFALSE);
+ void SortTrackClusters(AliHLTTPCTrack *track) const;
+ Int_t FitHelix(AliHLTTPCTrack *track);
+ Int_t FitCircle();
+ Int_t FitLine();
+ void NoVertex() {fVertexConstraint=kFALSE;}
+
+ private:
+ AliHLTTPCTrack *fTrack; //! actual track
+ AliHLTTPCVertex *fVertex; //! vertex info
+ Bool_t fVertexConstraint; // include vertex constraint
+ AliHLTTPCSpacePointData *fClusters[36][6]; //! clusters
+ UInt_t fNcl[36][6]; // cluster numbers
+
+ ClassDef(AliHLTTPCFitter,1) //HLT fit class
+};
+
+#endif
--- /dev/null
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+/** \class AliHLTTPCGlobalMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCGlobalMerger
+//
+// The HLTTPC Slice merger
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCGlobalMerger)
+
+AliHLTTPCGlobalMerger::AliHLTTPCGlobalMerger()
+{
+ //Default constructor. Use Setup to specify and setup the necessary parameters and arrays.
+ Is2Global(kTRUE);
+ SetParameter(0,0,0,0,0);
+ fNSlices=0;
+ fFirst=0;
+ fLast=0;
+}
+
+
+AliHLTTPCGlobalMerger::~AliHLTTPCGlobalMerger()
+{
+ //Destructor
+}
+
+void AliHLTTPCGlobalMerger::Setup(Int_t first,Int_t last)
+{
+ //Used to setup the arrays and everything
+
+ fNSlices = last-first+1;
+ fFirst = first;
+ fLast = last;
+ InitMerger(last-first+1);
+}
+
+void AliHLTTPCGlobalMerger::InitSlice(Int_t slice)
+{
+ //
+ // Select Sector The following FillTracks call will
+ // fill this Sector
+ //
+ fSlice = slice;
+ fCurrentTracks = fSlice - fFirst;
+}
+
+Double_t AliHLTTPCGlobalMerger::CheckTracks(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack,Int_t slice)
+{
+ //Compare the tracks by propagating the outermost track to the last and first point plane
+ //of the innermost track. This plane is defined by the padrow plane where these points
+ //are.
+
+ if(innertrack->GetCharge()!=outertrack->GetCharge()) return -1;
+
+ Float_t angle = 0;//perpendicular to the padrowplane (in local system)
+ AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+ Double_t dx[2],dy[2],dz[2];
+ Double_t diff =-1;
+ AliHLTTPCTrack *tracks[2];
+ tracks[0] = innertrack;
+ tracks[1] = outertrack;
+ SortGlobalTracks(tracks,2);
+ innertrack = tracks[0];
+ outertrack = tracks[1];
+
+ Float_t point[3];
+
+ point[0]=innertrack->GetLastPointX();
+ point[1]=innertrack->GetLastPointY();
+ point[2]=innertrack->GetLastPointZ();
+ AliHLTTPCTransform::Global2LocHLT(point,slice);
+
+ outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
+ if(!outertrack->IsPoint()) return diff;
+ dx[0] = fabs(outertrack->GetPointX()-innertrack->GetLastPointX());
+ dy[0] = fabs(outertrack->GetPointY()-innertrack->GetLastPointY());
+ dz[0] = fabs(outertrack->GetPointZ()-innertrack->GetLastPointZ());
+
+ point[0]=innertrack->GetFirstPointX();
+ point[1]=innertrack->GetFirstPointY();
+ point[2]=innertrack->GetFirstPointZ();
+ AliHLTTPCTransform::Global2LocHLT(point,slice);
+
+ outertrack->CalculateReferencePoint(angle,point[0]);//local x = global distance to padrowplane
+ if(!outertrack->IsPoint()) return diff;
+ dx[1] = fabs(outertrack->GetPointX()-innertrack->GetFirstPointX());
+ dy[1] = fabs(outertrack->GetPointY()-innertrack->GetFirstPointY());
+ dz[1] = fabs(outertrack->GetPointZ()-innertrack->GetFirstPointZ());
+
+ diff=0;//This was a tough bug to find....
+ for(Int_t i=0; i<2; i++)
+ diff += sqrt(dx[i]*dx[i] + dy[i]*dy[i] + dz[i]*dz[i]);
+ return diff;
+}
+
+void AliHLTTPCGlobalMerger::SlowMerge(Char_t *path)
+{
+ //Tuning of parameters. This matches _all_ tracks between two neighbouring
+ //slices, and merges the ones which are closest in space. The difference
+ //is written to a ntuppel, which can be used as a input for the SetParameters
+ //when using normal Merge function.
+
+
+ void* ntuple=GetNtuple();
+ AliHLTTPCTrack *track[2];
+ AliHLTTPCTrackArray *tout = GetOutTracks();
+ if(fNSlices<2)
+ {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCGlobalMerger::SlowMerge","Slice Number")
+ <<"Need more than one Slice!"<<ENDLOG;
+ return;
+ }
+
+ for(Int_t i=0; i<fNSlices; i++)
+ {
+ //if(fNSlices!=18 && i+1 == fNSlices) continue;
+ Int_t slice = fFirst + i;
+ AliHLTTPCTrackArray *ttt0=GetInTracks(i);
+ Int_t slice2 = i+1;
+ //if(slice2==fNSlices) slice2 =0;
+
+ //Make sure slices are on the same side of the TPC
+ if(slice2 == 18) slice2=0;
+ else if(slice2 == 36) slice2=18;
+ AliHLTTPCTrackArray *ttt1=GetInTracks(slice2);
+ //10 degrees -> the border of the slices in local coordinates
+ Float_t angle = AliHLTTPCTransform::Pi()/18;
+ AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+
+ //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
+ //the calculation of crossing points to be correct.
+ if(slice==17 || slice==35)
+ angle=0;
+ if(i==0)
+ ttt0->QSort();
+ ttt1->QSort();
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
+ {
+ AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ track0->CalculateHelix();
+ track0->CalculateEdgePoint(angle);
+ // if(track0->IsPoint()) AddTrack(tout,track0);
+ }
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
+ {
+ AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ track1->CalculateHelix();
+ track1->CalculateEdgePoint(angle);
+ // if(track1->IsPoint()) AddTrack(tout,track1);
+ }
+ Bool_t merge = kTRUE;
+ while(merge)
+ {
+ Int_t min0=-1,min1=-1;
+ Double_t min=5;
+ Int_t n0=ttt0->GetNTracks(),n1=ttt1->GetNTracks();
+ for(Int_t s0=0;s0<n0;s0++)
+ {
+ AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ if(!track0->IsPoint()) continue;
+ for(Int_t s1=0;s1<n1;s1++)
+ {
+ AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ if(!track1->IsPoint()) continue;
+
+ //Double_t diff = TrackDiff(track0,track1,angle);
+ Double_t diff = CheckTracks(track0,track1,slice);
+ //PrintDiff(track0,track1);
+ if(diff>=0&&diff<min)
+ {
+ min=diff;
+ min0=s0;
+ min1=s1;
+ }
+ }
+ }
+ if(min0>=0&&min1>=0)
+ {
+ AliHLTTPCTrack *track0=ttt0->GetTrack(min0);
+ AliHLTTPCTrack *track1=ttt1->GetTrack(min1);
+ track[0] = track0;
+ track[1] = track1;
+ SortGlobalTracks(track,2);
+ track1->CalculateEdgePoint((angle+AliHLTTPCTransform::Pi()/9));
+ if(track1->IsPoint())//Check if the track will cross the boundary of yet another slice.
+ MultiMerge(ttt1,track,2);
+ else
+ MultiMerge(tout,track,2);
+ track0->CalculateReferencePoint(angle);
+ track1->CalculateReferencePoint(angle);
+ //PrintDiff(track0,track1);
+ FillNtuple(ntuple,track0,track1);
+ ttt0->Remove(min0);
+ ttt1->Remove(min1);
+
+ }
+ else merge = kFALSE;
+ }
+ ttt0->Compress();
+ ttt1->Compress();
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCGlobalMerger::SlowMerge","Result")
+ <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<tout->GetNTracks()<<" at:"
+ <<angle<<ENDLOG;
+ }
+ Char_t fname[1024];
+ sprintf(fname,"%s/merge_parameters.root",path);
+ WriteNtuple(fname,ntuple);
+}
+
+void AliHLTTPCGlobalMerger::Merge()
+{
+ //Normal merging procedure. Matches tracks which are within limits
+ //set by SetParameters. Parameters can be tuned by SlowMerge.
+
+ AliHLTTPCTrack *track[2];
+ AliHLTTPCTrackArray *tout = GetOutTracks();
+ if(fNSlices<2)
+ {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCGlobalMerger::Merge","Slice Number")
+ <<"Need more than one Slice!"<<ENDLOG;
+ return;
+ }
+ for(Int_t i=0; i<fNSlices; i++)
+ {
+ //if(fNSlices!=18 && i+1 == fNSlices) continue;
+ Int_t slice = fFirst + i;
+ AliHLTTPCTrackArray *ttt0=GetInTracks(i);
+ Int_t slice2 = i+1;
+ //if(slice2==fNSlices) slice2 =0;
+
+ //Make sure slices are on the same side of the TPC
+ if(slice2 == 18) slice2=0;
+ else if(slice2 == 36) slice2=18;
+ AliHLTTPCTrackArray *ttt1=GetInTracks(slice2);
+ //10 degrees -> the border of the slices in local coordinates
+ Float_t angle = AliHLTTPCTransform::Pi()/18;
+ AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
+
+ //In the two following cases, the angle is 2*pi, so set it back to 0 in order for
+ //the calculation of crossing points to be correct.
+ if(slice==17 || slice==35)
+ angle=0;
+ if(i==0)
+ ttt0->QSort();
+ ttt1->QSort();
+ Bool_t *ismatched0 = new Bool_t[ttt0->GetNTracks()];
+ Bool_t *ismatched1 = new Bool_t[ttt1->GetNTracks()];
+ Int_t n0=0,n1=0;
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
+ {
+ ismatched0[s0]=kFALSE;
+ AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ track0->CalculateHelix();
+ track0->CalculateEdgePoint(angle);
+ if(track0->IsPoint())
+ {
+ n0++;
+ track0->CalculateReferencePoint(angle);
+ }
+ }
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
+ {
+ ismatched1[s1]=kFALSE;
+ AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ track1->CalculateHelix();
+ track1->CalculateEdgePoint(angle);
+ if(track1->IsPoint())
+ {
+ n1++;
+ track1->CalculateReferencePoint(angle);
+ }
+ }
+ for(Int_t s0=0;s0<ttt0->GetNTracks();s0++)
+ {
+ if(ismatched0[s0]) continue;
+ AliHLTTPCTrack *track0=ttt0->GetCheckedTrack(s0);
+ if(!track0) continue;
+ if(!track0->IsPoint()) continue;
+ for(Int_t s1=0;s1<ttt1->GetNTracks();s1++)
+ {
+ if(ismatched1[s1]) continue;
+ AliHLTTPCTrack *track1=ttt1->GetCheckedTrack(s1);
+ if(!track1) continue;
+ if(!track1->IsPoint()) continue;
+ if(IsRTrack(track0,track1))
+ {
+ track[0] = track0;
+ track[1] = track1;
+ SortGlobalTracks(track,2);
+ Double_t r0 = pow(track[0]->GetLastPointX(),2)+
+ pow(track[0]->GetLastPointY(),2);
+ Double_t r1 = pow(track[1]->GetFirstPointX(),2)+
+ pow(track[1]->GetFirstPointY(),2);
+ if(r0<r1)
+ {
+ MultiMerge(tout,track,2);
+ ismatched0[s0]=kTRUE;
+ ismatched1[s1]=kTRUE;
+ ttt0->Remove(s0);
+ ttt1->Remove(s1);
+ break;
+ /*
+ The track is merged, so we will _not_ look for more matches.
+ Because there could easily be more matches, if a track is being
+ split within the sector....
+ */
+ }
+ }
+ }
+ }
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCGlobalMerger::Merge","Result")
+ <<AliHLTTPCLog::kDec<<"slice0: "<<n0<<" slice1: "<<n1
+ <<" Merged Tracks: "<<tout->GetNTracks()<<ENDLOG;
+ delete [] ismatched0;
+ delete [] ismatched1;
+ }
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_GLOBALMERGER_H
+#define ALIHLTTPC_GLOBALMERGER_H
+
+#ifndef __CINT__
+#include "AliHLTTPCMerger.h"
+#endif
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCGlobalMerger : public AliHLTTPCMerger{
+
+ private:
+ Int_t fNSlices;
+ Int_t fFirst;
+ Int_t fLast;
+
+ Double_t CheckTracks(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack,Int_t slice);
+
+ public:
+ AliHLTTPCGlobalMerger();
+ virtual ~AliHLTTPCGlobalMerger();
+
+ void Setup(Int_t first,Int_t last);
+ void InitSlice(Int_t slice);
+ void SlowMerge(Char_t *path="./");
+ void Merge(); //Loop over tracks from different sectors
+
+ ClassDef(AliHLTTPCGlobalMerger,1) //Slice merger
+};
+
+#endif
#endif
#include "AliHLTTPCGlobalMergerComponent.h"
-#include "AliL3Transform.h"
-#include "AliL3GlobalMerger.h"
-#include "AliL3Vertex.h"
-#include "AliL3VertexData.h"
-#include "AliL3TrackSegmentData.h"
-#include "AliL3TrackArray.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCGlobalMerger.h"
+#include "AliHLTTPCVertex.h"
+#include "AliHLTTPCVertexData.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTrackArray.h"
#include "AliHLTTPCTrackletDataFormat.h"
-#include "AliL3SpacePointData.h"
+#include "AliHLTTPCSpacePointData.h"
#include "AliHLTTPCClusterDataFormat.h"
#include <stdlib.h>
#include <errno.h>
{
if ( fGlobalMerger || fVertex )
return EINPROGRESS;
- fGlobalMerger = new AliL3GlobalMerger();
- fVertex = new AliL3Vertex();
+ fGlobalMerger = new AliHLTTPCGlobalMerger();
+ fVertex = new AliHLTTPCVertex();
SetMergerParameters();
return 0;
}
fVertex->SetZero();
}
else
- fVertex->Read( (AliL3VertexData*)( lastVertexBlock->fPtr ) );
+ fVertex->Read( (AliHLTTPCVertexData*)( lastVertexBlock->fPtr ) );
// Add all tracks into the merger
sdIter = slices.begin();
{
if ( sdIter->fVertexBlock )
{
- fVertex->Read( (AliL3VertexData*)( sdIter->fVertexBlock->fPtr ) );
+ fVertex->Read( (AliHLTTPCVertexData*)( sdIter->fVertexBlock->fPtr ) );
fGlobalMerger->SetVertex( fVertex );
}
inPtr = (AliHLTTPCTrackletData*)( sdIter->fTrackletBlock->fPtr );
#include "AliHLTProcessor.h"
#include "AliHLTTPCDefinitions.h"
-class AliL3GlobalMerger;
-class AliL3Vertex;
+class AliHLTTPCGlobalMerger;
+class AliHLTTPCVertex;
class AliHLTTPCGlobalMergerComponent : public AliHLTProcessor
{
private:
- AliL3GlobalMerger* fGlobalMerger;
- AliL3Vertex* fVertex;
+ AliHLTTPCGlobalMerger* fGlobalMerger;
+ AliHLTTPCVertex* fVertex;
struct SliceData
{
--- /dev/null
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © ALICE HLT Group
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCInterMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+/** \class AliHLTTPCInterMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCInterMerger
+//
+// The HLTTPC track segment merger
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCInterMerger)
+
+AliHLTTPCInterMerger::AliHLTTPCInterMerger()
+{
+ //Default constructor
+ InitMerger(1);
+ Is2Global(kFALSE);
+// SetParameter(2,2,.3,.3,.3);
+ SetParameter(1,0.5,0.0005,0.05,0.1);
+ fRowMax = fRowMin = 0;
+}
+
+
+AliHLTTPCInterMerger::~AliHLTTPCInterMerger(){
+ //Destructor
+
+}
+
+void AliHLTTPCInterMerger::SlowMerge(){
+ Int_t nrow= fRowMax-fRowMin+1;
+ void *ntuple=GetNtuple();
+ AliHLTTPCTrackArray * tracks = GetInTracks(0);
+ const Int_t kNIn =tracks->GetNTracks();
+ AliHLTTPCTrack *tr[2];
+ Bool_t merge = kTRUE;
+ for(Int_t in=0;in<kNIn;in++)
+ tracks->GetCheckedTrack(in)->CalculateHelix();
+ while(merge){
+ Int_t inmin=-1,outmin=-1;
+ Double_t min=10;
+ for(Int_t out=0;out<kNIn;out++){
+ AliHLTTPCTrack *outertrack=tracks->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ if(in==out) continue;
+ AliHLTTPCTrack *innertrack=tracks->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+ Double_t diff = TrackDiff(innertrack,outertrack);
+
+ if(diff>=0&&diff<min){
+ min=diff;
+ inmin=in;
+ outmin=out;
+ }
+ }
+ }
+ if(inmin>=0&&outmin>=0){
+ AliHLTTPCTrack *outertrack=tracks->GetTrack(outmin);
+ AliHLTTPCTrack *innertrack=tracks->GetTrack(inmin);
+ tr[0]=innertrack;
+ tr[1]=outertrack;
+ SortTracks(tr,2);
+ MultiMerge(tracks,tr,2);
+ outertrack->CalculatePoint(tr[0]->GetLastPointX());
+ innertrack->CalculatePoint(tr[0]->GetLastPointX());
+ PrintDiff(innertrack,outertrack);
+ FillNtuple(ntuple,innertrack,outertrack);
+ tracks->Remove(outmin);
+ tracks->Remove(inmin);
+ }
+ else merge = kFALSE;
+ }
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCInterMerger::SlowMerge","Result")
+ <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<tracks->GetNTracks()-kNIn<<ENDLOG;
+
+ char name[256];
+ sprintf(name,"ntuple_i_%d.root",fPatch);
+ WriteNtuple(name,ntuple);
+}
+
+void AliHLTTPCInterMerger::MMerge(){
+ while(Merge());
+ GetOutTracks()->AddTracks(GetInTracks(0));
+}
+
+Int_t AliHLTTPCInterMerger::Merge(){
+ Int_t nrow= fRowMax-fRowMin+1;
+ Double_t xval =AliHLTTPCTransform::Row2X((fRowMax+fRowMin)/2);
+ AliHLTTPCTrackArray * tracks = GetInTracks(0);
+ const Int_t kNIn =tracks->GetNTracks();
+ AliHLTTPCTrack *tr[2];
+ for(Int_t in=0;in<kNIn;in++){
+ AliHLTTPCTrack *t = tracks->GetCheckedTrack(in);
+ if(t){
+ t->CalculateHelix();
+ t->CalculatePoint(xval);
+ }
+ }
+ for(Int_t out=0;out<kNIn;out++){
+ AliHLTTPCTrack *outertrack=tracks->GetCheckedTrack(out);
+ if(!outertrack) continue;
+ for(Int_t in=0;in<kNIn;in++){
+ if(in==out) continue;
+ AliHLTTPCTrack *innertrack=tracks->GetCheckedTrack(in);
+ if(!innertrack) continue;
+ if(outertrack->GetNHits()+innertrack->GetNHits()>nrow) continue;
+
+ if(IsTrack(innertrack,outertrack)){
+ tr[0]=innertrack;
+ tr[1]=outertrack;
+ SortGlobalTracks(tr,2);
+
+ Double_t r0 = pow(tr[0]->GetLastPointX(),2)+
+ pow(tr[0]->GetLastPointY(),2);
+ Double_t r1 = pow(tr[1]->GetFirstPointX(),2)+
+ pow(tr[1]->GetFirstPointY(),2);
+ if(r0<r1){
+ MultiMerge(tracks,tr,2);
+ tracks->Remove(out);
+ tracks->Remove(in);
+ break;
+ }
+ }
+ }
+ }
+ Int_t nmerged = tracks->GetNTracks()-kNIn;
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCInterMerger::Merge","Result")
+ <<AliHLTTPCLog::kDec<<"Merged Tracks: "<<nmerged<<ENDLOG;
+ //add in tracks
+// GetOutTracks()->AddTracks(GetInTracks(0));
+
+ return nmerged;
+}
+
+
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCINTERMERGER_H
+#define ALIHLTTPCINTERMERGER_H
+
+#ifndef __CINT__
+#include "AliHLTTPCMerger.h"
+#endif
+
+#include "AliHLTTPCRootTypes.h"
+
+class AliHLTTPCInterMerger : public AliHLTTPCMerger {
+
+ private:
+ Int_t fPatch;
+ Int_t fRowMin;
+ Int_t fRowMax;
+ public:
+ AliHLTTPCInterMerger();
+ virtual ~AliHLTTPCInterMerger();
+
+ void Init(Int_t *row,Int_t p){fRowMin=row[0];fRowMax=row[1];fPatch=p;}
+ void SlowMerge();
+ Int_t Merge();
+ void MMerge(); //Loop over tracks from different subsectors
+
+ ClassDef(AliHLTTPCInterMerger,1) //Intermerging class
+};
+
+#endif
#pragma link off all classes;
#pragma link off all functions;
+#pragma link C++ class AliHLTTPCBenchmark;
+#pragma link C++ class AliHLTTPCDigitRowData;
+#pragma link C++ class AliHLTTPCDigitData;
+#pragma link C++ class AliHLTTPCSpacePointData;
+#pragma link C++ class AliHLTTPCConfMapper;
+#pragma link C++ class AliHLTTPCConfMapPoint;
+#pragma link C++ class AliHLTTPCVertex;
+#pragma link C++ class AliHLTTPCVertexFinder;
+#pragma link C++ class AliHLTTPCVertexArray;
+#pragma link C++ class AliHLTTPCTrack;
+#pragma link C++ class AliHLTTPCConfMapTrack;
+#pragma link C++ class AliHLTTPCConfMapFit;
+#pragma link C++ class AliHLTTPCTransform;
+#pragma link C++ class AliHLTTPCMerger;
+#pragma link C++ class AliHLTTPCTrackMerger;
+#pragma link C++ class AliHLTTPCGlobalMerger;
+#pragma link C++ class AliHLTTPCInterMerger;
+#pragma link C++ class AliHLTTPC;
+#pragma link C++ class AliHLTTPCTrackArray;
+/* #pragma link C++ class AliHLTTPCLogger; */
+#pragma link C++ class AliHLTTPCMemHandler;
+#pragma link C++ class AliHLTTPCDataCompressorHelper;
+#pragma link C++ class AliHLTTPCDisplay;
+#pragma link C++ class AliHLTTPCClustFinderNew;
+#pragma link C++ class AliHLTTPCFitter;
+/* #pragma link C++ class AliHLTTPCRawDataFileHandler; */
+/* #pragma link C++ class AliHLTTPCTPCBeamTestMemHandler; */
+#pragma link C++ class AliHLTTPCModelTrack;
+
+#ifdef use_aliroot
+#pragma link C++ class AliHLTTPCFileHandler;
+/* #pragma link C++ class AliHLTTPCEvaluate; */
+#ifdef use_reconstruction
+#pragma link C++ class AliHLTReconstructor;
+#pragma link C++ class AliHLTTPCTPCtracker;
+#endif
+#endif
+
+#ifndef macosx
+/* #pragma link C++ class AliHLTTPCTransBit; */
+/* #pragma link C++ class AliHLTTPCTransBitV1; */
+/* #pragma link C++ class AliHLTTPCTransBitV2; */
+/* #pragma link C++ class AliHLTTPCDataHandler; */
+#endif
+/* #pragma link C++ class AliHLTTPCAltroMemHandler; */
+/* #pragma link C++ class AliHLTTPCVHDLClusterFinder; */
+/* #pragma link C++ class AliHLTTPCTPCMapping; */
+/* #pragma link C++ class AliHLTTPCDDLRawReader; */
+/* #pragma link C++ class AliHLTTPCDDLRawReaderFile; */
+/* #pragma link C++ class AliHLTTPCDDLTPCRawStream; */
+#ifndef macosx
+#pragma link C++ class AliHLTTPCDDLDataFileHandler;
+#endif
+
+#ifdef USEFFLOAT
+/* #pragma link C++ class AliHLTTPCFFloat; */
+#endif
+
+
+#ifdef INCLUDE_TPC_HOUGH
+/* #pragma link C++ class AliHLTTPCHough; */
+#pragma link C++ class AliHLTTPCHoughBaseTransformer;
+/* #pragma link C++ class AliHLTTPCHoughTransformer; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerLUT; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerVhdl; */
+/* #pragma link C++ class AliHLTTPCHoughTransformerNew; */
+#pragma link C++ class AliHLTTPCHoughTransformerRow;
+#ifndef macosx
+#pragma link C++ class AliHLTTPCHoughTrack;
+/* #pragma link C++ class AliHLTTPCHoughKalmanTrack; */
+#endif
+/* #pragma link C++ class AliHLTTPCHoughMaxFinder; */
+/* #pragma link C++ class AliHLTTPCHoughEval; */
+#pragma link C++ class AliHLTTPCHistogram;
+/* #pragma link C++ class AliHLTTPCHistogram1D; */
+/* #pragma link C++ class AliHLTTPCHoughMerger; */
+/* #pragma link C++ class AliHLTTPCHoughIntMerger; */
+/* #pragma link C++ class AliHLTTPCHoughGlobalMerger; */
+/* #pragma link C++ class AliHLTTPCHoughDisplay; */
+/* #pragma link C++ class AliHLTTPCHoughClusterTransformer; */
+#pragma link C++ class AliHLTTPCHistogramAdaptive;
+#ifndef macosx
+/* #pragma link C++ class AliHLTTPCHoughTest; */
+#endif
+
+#ifdef use_aliroot
+/* #pragma link C++ class AliHLTTPCHoughTransformerGlobal; */
+#endif
+#endif // INCLUDE_TPC_HOUGH
+
#pragma link C++ class AliHLTTPCDefinitions;
#pragma link C++ class AliHLTTPCRawDataUnpackerComponent;
#pragma link C++ class AliHLTTPCClusterFinderComponent;
--- /dev/null
+// $Id$
+
+#ifndef use_logging
+
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCLogging.h"
+
+AliHLTTPCLog::TLogLevel AliHLTTPCLog::fgLevel=AliHLTTPCLog::kNone;
+
+#endif
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCLOG_H
+#define ALIHLTTPCLOG_H
+
+class AliHLTTPCLog {
+ public:
+ enum TLogLevel { kNone = 0, kDebug= 0x01, kInformational = 0x02, kWarning = 0x04, kError = 0x08 , kFatal = 0x10, kPrimary = 0x80, kAll = 0x9F };
+ enum TLogCmd { kEnd, kPrec, kHex, kDec };
+ static TLogLevel fgLevel;
+};
+
+#if __GNUC__ == 3
+#define LOG( lvl, origin, keyword ) \
+ if (lvl>=AliHLTTPCLog::fgLevel) std::cerr<<"["<<origin<<": "<<keyword<<"] "
+#define ENDLOG std::endl
+#else
+#define LOG( lvl, origin, keyword ) \
+ if (lvl>=AliHLTTPCLog::fgLevel) cerr<<"["<<origin<<": "<<keyword<<"] "
+#define ENDLOG endl
+#endif /* __GNUC__ */
+#endif /* ALIHLTTPCLOG_H */
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPCLOGGING_H
+#define ALIHLTTPCLOGGING_H
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+
+#ifdef use_logging
+#include <MLUCLog.hpp>
+#include <MLUCLogServer.hpp>
+
+typedef MLUCLog AliHLTTPCLog;
+typedef MLUCLogServer AliHLTTPCLogServer;
+typedef MLUCDevNullLogServer AliHLTTPCDevNullLogServer;
+typedef MLUCStdoutLogServer AliHLTTPCStdoutLogServer;
+typedef MLUCStderrLogServer AliHLTTPCStderrLogServer;
+typedef MLUCStreamLogServer AliHLTTPCStreamLogServer;
+
+#else
+
+#include "AliHLTTPCLog.h"
+#endif /* use_logging */
+#endif /* ALIHLTTPCLOGGING_H */
--- /dev/null
+// @(#) $Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+//*-- Copyright © ALICE HLT Group
+
+/** \class AliHLTTPCMemHandler
+<pre>
+//_____________________________________________________________
+// AliHLTTPCMemHandler
+//
+// The HLT Binary File handler
+//
+// This class does all the memory I/O handling of HLT binary files.
+//
+// Examples:
+// ---------
+//
+// 1) Reading a binary file:
+//
+// AliHLTTPCMemHandler file;
+// file.SetBinaryInput(filename);
+// file.Init(slice,patch);
+//
+// UInt_t nrowss;
+// AliHLTTPCDigitRowData *data = file.CompBinary2Memory(nrows);
+//
+// for(int i=0; i<nrows; i++)
+// {
+//
+// AliHLTTPCDigitData *dataPt = (AliHLTTPCDigitData*)data->fDigitData;
+// for(int j=0; j<data->fNDigit; j++)
+// {
+// pad = dataPt[j].fPad;
+// time = dataPt[j].fTime;
+// charge = dataPt[j].fCharge;
+// }
+//
+// file.UpdateRowPointer(data);
+//
+// }
+// file.CloseBinaryInput();
+// ________________________
+//
+// 2) Writing a binary file:
+//
+// //First of all you need to store the data in memory,
+// //and have a pointer to it of type AliHLTTPCDigitRowData.
+// //E.g. if you just want to write the data you read in example 1)
+// //into a new file, you can do the following:
+//
+// AliHLTTPCMemHandler newfile;
+// newfile.Init(slice,patch);
+// newfile.SetBinaryOutput(newfilename);
+// newfile.Memory2CompBinary((UInt_t)NumberOfRowsInPatch,(AliHLTTPCDigitRowData*)data);
+// newfile.CloseBinaryOutput();
+//
+//
+// Compressed file format:
+// -----------------------
+//
+// The data is RLE encoded and currently using _10_ bit range for the ADC-values.
+</pre>
+*/
+
+#include "AliHLTTPCRootTypes.h"
+#include "AliHLTTPCStandardIncludes.h"
+#include "AliHLTTPCDigitData.h"
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCSpacePointData.h"
+#include "AliHLTTPCTrackArray.h"
+#include "AliHLTTPCMemHandler.h"
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCMemHandler)
+
+AliHLTTPCMemHandler::AliHLTTPCMemHandler()
+{
+ //Constructor
+ fPt = 0;
+ fSize =0;
+ fInBinary = 0;
+ fOutBinary = 0;
+ fNRandom = 0;
+ Init(0,0);
+ fIsRandom = kFALSE;
+ fRandomDigits = 0;
+ fDPt =0;
+ fNGenerate = 0;
+ fNUsed = 0;
+ fNDigits = 0;
+ ResetROI();
+}
+
+
+AliHLTTPCMemHandler::~AliHLTTPCMemHandler()
+{
+ //Destructor
+ if(fPt) delete[] fPt;
+ if(fRandomDigits) delete [] fRandomDigits;
+ if(fDPt) delete [] fDPt;
+}
+
+void AliHLTTPCMemHandler::Init(Int_t s,Int_t p, Int_t *r)
+{
+ //init handler
+ fSlice=s;fPatch=p;
+ if(r) {
+ fRowMin=r[0];
+ fRowMax=r[1];
+ }else{
+ fRowMin=AliHLTTPCTransform::GetFirstRow(p);
+ fRowMax=AliHLTTPCTransform::GetLastRow(p);
+ }
+ ResetROI();
+}
+
+void AliHLTTPCMemHandler::ResetROI()
+{
+ //Resets the Look-up table for Region of Interest mode.
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ fEtaMinTimeBin[i] = 0;
+ fEtaMaxTimeBin[i] = AliHLTTPCTransform::GetNTimeBins()-1;
+ }
+}
+
+void AliHLTTPCMemHandler::SetROI(Float_t *eta,Int_t */*slice*/)
+{
+ // Init the Look-up table for the Region of Interest mode.
+ // Here you can specify a certain etaregion, - all data
+ // outside this region will be discarded:
+ // eta[0] = mimium eta
+ // eta[1] = maximum eta
+ // slice[0] = mimumum slice
+ // slice[1] = maximum slice
+
+
+ if(eta[1]==0)
+ {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetROI","Eta Values")
+ <<"Bad ROI parameters. IDIOT! "<<ENDLOG;
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ fEtaMinTimeBin[i]=0;
+ fEtaMaxTimeBin[i]=0;
+ }
+ return;
+ }
+
+ for(Int_t i=fRowMin; i<=fRowMax; i++)
+ {
+ Int_t sector,row;
+ Float_t xyz[3];
+
+ Float_t thetamax = 2*atan(exp(-1.*eta[1]));
+
+ xyz[0] = AliHLTTPCTransform::Row2X(i);
+ xyz[1]=0;
+ xyz[2] = xyz[0]/tan(thetamax);
+ AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
+ AliHLTTPCTransform::Local2Raw(xyz,sector,row);
+
+ fEtaMinTimeBin[i] = (Int_t)xyz[2];
+
+ if(eta[0]==0)
+ fEtaMaxTimeBin[i] = 445;
+ else
+ {
+ Float_t thetamin = 2*atan(exp(-1.*eta[0]));
+ xyz[0] = AliHLTTPCTransform::Row2X(i);
+ xyz[1] = AliHLTTPCTransform::GetMaxY(i);
+ Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
+ xyz[2] = radii/tan(thetamin);
+ AliHLTTPCTransform::Local2Raw(xyz,sector,row);
+ fEtaMaxTimeBin[i] = (Int_t)xyz[2];
+ }
+ }
+
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryInput(char *name)
+{
+ //Set the input binary file.
+ fInBinary = fopen(name,"r");
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
+ <<"Error opening file "<<name<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryInput(FILE *file)
+{
+ //Set the input binary file.
+ fInBinary = file;
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+void AliHLTTPCMemHandler::CloseBinaryInput()
+{
+ //Close the input file.
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryInput","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ fclose(fInBinary);
+ fInBinary =0;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryOutput(char *name)
+{
+ //Set the binary output file.
+ fOutBinary = fopen(name,"w");
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::SetBinaryOutput(FILE *file)
+{
+ //Set the binary output file.
+ fOutBinary = file;
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
+ <<"Pointer to File = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+void AliHLTTPCMemHandler::CloseBinaryOutput()
+{
+ //close binary
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryOutPut","File Close")
+ <<"Nothing to Close"<<ENDLOG;
+ return;
+ }
+ fclose(fOutBinary);
+ fOutBinary =0;
+}
+
+UInt_t AliHLTTPCMemHandler::GetFileSize()
+{
+ //Returns the file size in bytes of the input file.
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetFileSize","File")
+ <<"No Input File"<<ENDLOG;
+ return 0;
+ }
+ fseek(fInBinary,0,SEEK_END);
+ UInt_t size = (UInt_t) ftell(fInBinary);
+ rewind(fInBinary);
+ return size;
+}
+
+Byte_t *AliHLTTPCMemHandler::Allocate()
+{
+ //Allocate
+ return Allocate(GetFileSize());
+}
+
+Byte_t *AliHLTTPCMemHandler::Allocate(AliHLTTPCTrackArray *array)
+{
+ //Allocate memory for tracks in memory. Used by TrackArray2Binary()
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ return Allocate(array->GetOutSize());
+}
+
+Byte_t *AliHLTTPCMemHandler::Allocate(UInt_t size)
+{
+ //Allocate memory of size in bytes.
+ if(fPt){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
+ <<"Delete Memory"<<ENDLOG;
+ Free();
+ }
+ fPt = new Byte_t[size];
+ fSize = size;
+ memset(fPt,0,fSize);
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Allocate","Memory")
+ <<AliHLTTPCLog::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
+ return fPt;
+}
+
+void AliHLTTPCMemHandler::Free()
+{
+ //Clear the memory, if allocated.
+ if(!fPt){
+ // LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMemHandler::Free","Memory")
+ // <<"No Memory allocated - can't Free"<<ENDLOG;
+ return;
+ }
+ delete[] fPt;
+ fPt = 0;
+ fSize =0;
+}
+
+///////////////////////////////////////// Random
+void AliHLTTPCMemHandler::SetRandomSeed()
+{
+ //If you are adding random data to the original data.
+ time_t *tp=0;
+ SetRandomSeed(time(tp));
+}
+
+void AliHLTTPCMemHandler::SetRandomCluster(Int_t maxnumber)
+{
+ //If you are adding random data to the original data.
+
+ fIsRandom = kTRUE;
+ fNRandom = maxnumber;
+ fNDigits = 0;
+ if(fRandomDigits) delete [] fRandomDigits;
+ fRandomDigits = new AliHLTTPCRandomDigitData[fNRandom*9];
+ if(fDPt) delete [] fDPt;
+ fDPt = new AliHLTTPCRandomDigitData *[fNRandom*9];
+}
+
+void AliHLTTPCMemHandler::QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last)
+{
+
+ // Sort array of AliHLTTPCRandomDigitData pointers using a quicksort algorithm.
+ // Uses CompareDigits() to compare objects.
+ // Thanks to Root!
+
+ static AliHLTTPCRandomDigitData *tmp;
+ static int i; // "static" to save stack space
+ int j;
+
+ while (last - first > 1) {
+ i = first;
+ j = last;
+ for (;;) {
+ while (++i < last && CompareDigits(a[i], a[first]) < 0)
+ ;
+ while (--j > first && CompareDigits(a[j], a[first]) > 0)
+ ;
+ if (i >= j)
+ break;
+
+ tmp = a[i];
+ a[i] = a[j];
+ a[j] = tmp;
+ }
+ if (j == first) {
+ ++first;
+ continue;
+ }
+ tmp = a[first];
+ a[first] = a[j];
+ a[j] = tmp;
+
+ if (j - first < last - (j + 1)) {
+ QSort(a, first, j);
+ first = j + 1; // QSort(j + 1, last);
+ } else {
+ QSort(a, j + 1, last);
+ last = j; // QSort(first, j);
+ }
+ }
+}
+
+UInt_t AliHLTTPCMemHandler::GetRandomSize() const
+{
+ //get random size
+ Int_t nrandom = 0;
+ for(Int_t r=fRowMin;r<=fRowMax;r++){
+ Int_t npad=AliHLTTPCTransform::GetNPads(r);
+ nrandom += Int_t (fNGenerate * ((Double_t) npad/141.));
+ }
+ return 9 * nrandom * sizeof(AliHLTTPCDigitData);
+}
+
+void AliHLTTPCMemHandler::Generate(Int_t row)
+{
+ //Generate random data on row, if you didn't
+ //ask for this, nothing happens here.
+
+ if(!fIsRandom) return;
+ ResetRandom();
+ fNDigits = 0;
+ Int_t npad=AliHLTTPCTransform::GetNPads(row);
+ Int_t ntime = fEtaMaxTimeBin[row] - fEtaMinTimeBin[row];
+ Int_t nrandom = Int_t (fNGenerate * ((Double_t) npad/141.) *
+ (Double_t) ntime/(Double_t) AliHLTTPCTransform::GetNTimeBins() );
+
+ for(Int_t n=0;n<nrandom;n++){
+ Int_t pad = (int)((float)rand()/RAND_MAX*npad);
+ Int_t time =(int)((float)rand()/RAND_MAX*ntime+fEtaMinTimeBin[row] );
+ Int_t charge = (int)((float)rand()/RAND_MAX*AliHLTTPCTransform::GetADCSat());
+ DigitizePoint(row,pad,time,charge);
+ }
+ QSort(fDPt,0,fNDigits);
+}
+
+
+void AliHLTTPCMemHandler::DigitizePoint(Int_t row, Int_t pad,
+ Int_t time,Int_t charge)
+{
+ //Making one single random cluster.
+ for(Int_t j=-1;j<2;j++){
+ for(Int_t k=-1;k<2;k++){
+ Int_t dcharge = charge;
+ if(j) dcharge /=2;
+ if(k) dcharge /=2;
+ if(dcharge<10) continue;
+ Int_t dpad = j + pad;
+ Int_t dtime = k + time;
+
+ if(dpad<0||dpad>=AliHLTTPCTransform::GetNPads(row)) continue;
+ if(dtime<0||dtime>=AliHLTTPCTransform::GetNTimeBins()) continue;
+
+ fRandomDigits[fNDigits].fCharge = dcharge;
+ fRandomDigits[fNDigits].fRow = row;
+ fRandomDigits[fNDigits].fPad = dpad;
+ fRandomDigits[fNDigits].fTime = dtime;
+ fDPt[fNDigits] = &fRandomDigits[fNDigits];
+ fNDigits++;
+ }
+ }
+}
+
+///////////////////////////////////////// Digit IO
+Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t nrow,AliHLTTPCDigitRowData *data)
+{
+ //Write data to the outputfile as is. No run-length encoding is done.
+
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ AliHLTTPCDigitRowData *rowPt = data;
+ Int_t outsize = 0;
+ for(UInt_t i=0;i<nrow;i++){
+ Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit
+ + sizeof(AliHLTTPCDigitRowData);
+ outsize += size;
+ fwrite(rowPt,size,1,fOutBinary);
+ Byte_t *bytePt =(Byte_t *) rowPt;
+ bytePt += size;
+ rowPt = (AliHLTTPCDigitRowData *) bytePt;
+ }
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+ <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+ <<nrow<<" Rows)"<<ENDLOG;
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & nrow,AliHLTTPCDigitRowData *data)
+{
+ //Read inputfile into memory as is, and store it in data.
+ // No run-length encoding is assumed.
+
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ rewind(fInBinary);
+ AliHLTTPCDigitRowData *rowPt = data;
+ UInt_t rowcount = 0;
+ Int_t outsize =0;
+ while(!feof(fInBinary)){
+ Byte_t *bytePt =(Byte_t *) rowPt;
+
+ if(fread(rowPt,sizeof(AliHLTTPCDigitRowData),1,fInBinary)!=1) break;
+
+ bytePt += sizeof(AliHLTTPCDigitRowData);
+ outsize += sizeof(AliHLTTPCDigitRowData);
+
+ Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit;
+
+ //if(fread(bytePt,size,1,fInBinary)!=1) break;
+ fread(bytePt,size,1,fInBinary);
+ bytePt += size;
+ outsize += size;
+ rowPt = (AliHLTTPCDigitRowData *) bytePt;
+ rowcount++;
+ }
+ nrow= rowcount;
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+ <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
+ <<rowcount<<" Rows)"<<ENDLOG;
+ return kTRUE;
+}
+
+void AliHLTTPCMemHandler::AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
+ UInt_t /*row*/,UShort_t pad,UShort_t time,UShort_t charge) const
+{
+ //add some data
+ data[ndata].fPad = pad;
+ data[ndata].fTime = time;
+ data[ndata].fCharge = charge;
+ ndata++;
+}
+
+void AliHLTTPCMemHandler::AddRandom(AliHLTTPCDigitData *data, UInt_t & ndata)
+{
+ //add some random data
+ data[ndata].fPad = fDPt[fNUsed]->fPad;
+ data[ndata].fTime = fDPt[fNUsed]->fTime;
+ data[ndata].fCharge = fDPt[fNUsed]->fCharge;
+ ndata++;
+ fNUsed++;
+}
+
+void AliHLTTPCMemHandler::MergeDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
+ UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
+{
+ //merge random data
+ data[ndata].fPad = pad;
+ data[ndata].fTime = time;
+ data[ndata].fCharge = charge;
+ while(ComparePoints(row,pad,time)==0){
+ Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge;
+ if(charge>=AliHLTTPCTransform::GetADCSat()) ch = AliHLTTPCTransform::GetADCSat();
+ data[ndata].fCharge = ch;
+ fNUsed++;
+ }
+ ndata++;
+}
+
+void AliHLTTPCMemHandler::AddDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
+ UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
+{
+ //add data random
+ Int_t action;
+ while((action=ComparePoints(row,pad,time))==1){
+ AddRandom(data,ndata);
+ }
+ if(action==0){
+ MergeDataRandom(data,ndata,row,pad,time,charge);
+ }
+ if(action<0){
+ AddData(data,ndata,row,pad,time,charge);
+ }
+}
+
+void AliHLTTPCMemHandler::Write(UInt_t *comp, UInt_t & index,
+ UInt_t & subindex, UShort_t value) const
+{
+ //write compressed data
+ UInt_t shift[3] = {0,10,20};
+ if(subindex==0) comp[index] =0; //clean up memory
+ comp[index] |= (value&0x03ff)<<shift[subindex];
+ if(subindex == 2){
+ subindex = 0;
+ index++;
+ }
+ else subindex++;
+}
+
+UShort_t AliHLTTPCMemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const
+{
+ //read compressed data
+ UInt_t shift[3] = {0,10,20};
+ UShort_t value = (comp[index]>>shift[subindex])&0x03ff;
+ if(subindex == 2){
+ subindex = 0;
+ index++;
+ }
+ else subindex++;
+
+ return value;
+}
+
+UShort_t AliHLTTPCMemHandler::Test(UInt_t *comp,
+ UInt_t index, UInt_t subindex) const
+{
+ //supi dupi test
+ UInt_t shift[3] = {0,10,20};
+ return (comp[index]>>shift[subindex])&0x03ff;
+}
+
+Int_t AliHLTTPCMemHandler::Memory2CompMemory(UInt_t nrow,
+ AliHLTTPCDigitRowData *data,UInt_t *comp)
+{
+ //Performs run-length encoding on data stored in memory pointed to by data.
+ //The compressed data is written to comp.
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
+ <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ AliHLTTPCDigitRowData *rowPt = data;
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UShort_t value = rowPt->fRow;
+ Write(comp,index,subindex,value);
+ UShort_t maxpad=0;
+ UShort_t npad=0;
+ Int_t ddd[1000];
+ for(Int_t d=0;d<200;d++) ddd[d]=0;
+ for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
+ if(rowPt->fDigitData[dig].fPad <200){
+ ddd[rowPt->fDigitData[dig].fPad]++;
+ }
+ }
+ for(Int_t d=0;d<200;d++){
+ if(ddd[d]){
+ npad++;
+ maxpad =d;
+ }
+ }
+ Write(comp,index,subindex,npad);
+ UInt_t digit=0;
+ for(UShort_t pad=0;pad <= maxpad;pad++){
+ if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
+ continue;
+ Write(comp,index,subindex,pad);
+// write zero if time != 0
+ if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+ if(rowPt->fDigitData[digit].fTime>0){
+ Write(comp,index,subindex,0);
+ Write(comp,index,subindex,rowPt->fDigitData[digit].fTime);
+ }
+ }
+ while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+ UShort_t charge = rowPt->fDigitData[digit].fCharge;
+ if(charge>=1023){
+ charge=1023;
+ }
+ Write(comp,index,subindex,charge);
+ if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
+ if(rowPt->fDigitData[digit].fTime +1 !=
+ rowPt->fDigitData[digit+1].fTime){
+ Write(comp,index,subindex,0);
+ UShort_t nzero = rowPt->fDigitData[digit+1].fTime -
+ (rowPt->fDigitData[digit].fTime +1);
+ Write(comp,index,subindex,nzero);
+ }
+ }
+ digit++;
+ }
+ Write(comp,index,subindex,0);
+ Write(comp,index,subindex,0);
+ }
+
+ Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+ sizeof(AliHLTTPCDigitRowData);
+ Byte_t *bytePt =(Byte_t *) rowPt;
+ bytePt += size;
+ rowPt = (AliHLTTPCDigitRowData *) bytePt;
+ }
+ while(subindex)
+ Write(comp,index,subindex,0);
+ return index * sizeof(UInt_t);
+}
+
+Int_t AliHLTTPCMemHandler::CompMemory2Memory(UInt_t nrow,
+ AliHLTTPCDigitRowData *data,UInt_t *comp)
+{
+ //Uncompress the run-length encoded data in memory pointed to by comp, and
+ // store it in data.
+
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2Memory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2Memory","Memory")
+ <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ Int_t outsize=0;
+
+ AliHLTTPCDigitRowData *rowPt = data;
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UInt_t ndigit=0;
+ UInt_t row =Read(comp,index,subindex);
+ rowPt->fRow=row;
+ Generate(row);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ UShort_t charge;
+ UShort_t time =0;
+ UShort_t pad = Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if( (time = Read(comp,index,subindex)) == 0 ){
+ continue;
+ }
+ }
+ for(;;){
+ while( (charge=Read(comp,index,subindex)) != 0){
+ if(time>=fEtaMinTimeBin[row]&&time<=fEtaMaxTimeBin[row])
+ //AddData(rowPt->fDigitData,ndigit,row,pad,time,charge);
+ //seems we are using this function... but dont know why
+ AddDataRandom(rowPt->fDigitData,ndigit,row,pad,time,charge);
+ time++;
+ }
+ UShort_t tshift = Read(comp,index,subindex);
+ if(tshift == 0) break;
+ time += tshift;
+ }
+ }
+ rowPt->fNDigit = ndigit;
+ Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+ sizeof(AliHLTTPCDigitRowData);
+ Byte_t *bytePt =(Byte_t *) rowPt;
+ bytePt += size;
+ outsize += size;
+ rowPt = (AliHLTTPCDigitRowData *) bytePt;
+ }
+ return outsize;
+}
+
+UInt_t AliHLTTPCMemHandler::GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const
+{
+ //Return the size of RLE data, after compressing data.
+
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetCompMemorySize","Memory")
+ <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ AliHLTTPCDigitRowData *rowPt = data;
+ UInt_t index=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ index++;
+ UShort_t maxpad=0;
+ UShort_t npad=0;
+ Int_t ddd[1000];
+ for(Int_t d=0;d<200;d++) ddd[d]=0;
+ for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
+ if(rowPt->fDigitData[dig].fPad <200){
+ ddd[rowPt->fDigitData[dig].fPad]++;
+ }
+ }
+ for(Int_t d=0;d<200;d++){
+ if(ddd[d]){
+ npad++;
+ maxpad =d;
+ }
+ }
+ index++;
+ UInt_t digit=0;
+ for(UShort_t pad=0;pad <= maxpad;pad++){
+ if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
+ continue;
+ index++;
+ // write zero if time != 0
+ if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+ if(rowPt->fDigitData[digit].fTime>0){
+ index++;
+ index++;
+ }
+ }
+ while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
+ index++;
+ if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
+ if(rowPt->fDigitData[digit].fTime +1 !=
+ rowPt->fDigitData[digit+1].fTime){
+ index++;
+ index++;
+ }
+ }
+ digit++;
+ }
+ index++;
+ index++;
+ }
+
+ Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
+ sizeof(AliHLTTPCDigitRowData);
+ Byte_t *bytePt =(Byte_t *) rowPt;
+ bytePt += size;
+ rowPt = (AliHLTTPCDigitRowData *) bytePt;
+ }
+ while(index%3)
+ index++;
+ return (index/3) * sizeof(UInt_t);
+}
+
+UInt_t AliHLTTPCMemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const
+{
+ //get memory size
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetMemorySize","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ Int_t outsize=0;
+
+ UInt_t index=0;
+ UInt_t subindex=0;
+
+ for(UInt_t i=0;i<nrow;i++){
+ UInt_t ndigit=0;
+ Read(comp,index,subindex);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if(Read(comp,index,subindex)== 0) continue;
+ }
+ for(;;){
+ while(Read(comp,index,subindex)!=0) ndigit++;
+ if(Read(comp,index,subindex)==0) break;
+ }
+ }
+ Int_t size = sizeof(AliHLTTPCDigitData) * ndigit+
+ sizeof(AliHLTTPCDigitRowData);
+ outsize += size;
+ }
+
+ return outsize;
+}
+
+UInt_t AliHLTTPCMemHandler::GetNRow(UInt_t *comp,UInt_t size)
+{
+ //get number of rows
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetNRow","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return 0;
+ }
+ size = size /4;
+ UInt_t nrow=0;
+ UInt_t index=0;
+ UInt_t subindex=0;
+ while(index<size-1){ //don't start with last word
+ nrow++;
+ UInt_t ndigit=0;
+ Read(comp,index,subindex);
+ UShort_t npad = Read(comp,index,subindex);
+ for(UShort_t p=0;p<npad;p++){
+ Read(comp,index,subindex);
+ if(Test(comp,index,subindex)==0){
+ Read(comp,index,subindex);
+ if(Read(comp,index,subindex)==0)continue;
+ }
+ for(;;){
+ while(Read(comp,index,subindex)!=0) ndigit++;
+ if(Read(comp,index,subindex)==0) break;
+ }
+ }
+ }
+ if(index==size-1){ //last word
+ if(subindex<2){
+ if(Read(comp,index,subindex)!=0) nrow++;
+ }
+ }
+ return nrow;
+}
+
+Bool_t AliHLTTPCMemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
+ UInt_t size)
+{
+ //Write the RLE data in comp to the output file.
+
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(size==0)
+ size=GetMemorySize(nrow,comp);
+ if(!size){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
+ <<"Memory size = 0 "<<ENDLOG;
+ return kFALSE;
+ }
+ UInt_t length = size/sizeof(UInt_t);
+ fwrite(&length,sizeof(UInt_t),1,fOutBinary);
+ fwrite(comp,size,1,fOutBinary);
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp)
+{
+ //Read the RLE data from file, and store it in comp. No unpacking yet.
+
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompBinary2CompMemory","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!comp){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompBinary2CompMemory","Memory")
+ <<"Pointer to compressed data = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ rewind(fInBinary);
+ UInt_t length;
+ if(fread(&length,sizeof(UInt_t),1,fInBinary)!=1) return kFALSE;
+ UInt_t size = length*sizeof(UInt_t);
+ if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
+ // now find the number of dig
+ nrow = GetNRow(comp,size);
+ return kTRUE;
+}
+
+AliHLTTPCDigitRowData *AliHLTTPCMemHandler::CompBinary2Memory(UInt_t & nrow)
+{
+ // Read the RLE inputfile, unpack it and return the pointer to it.
+ AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
+ handler->SetBinaryInput(fInBinary);
+ UInt_t *comp =(UInt_t *)handler->Allocate();
+ handler->CompBinary2CompMemory(nrow,comp);
+ UInt_t size = GetMemorySize(nrow,comp);
+ AliHLTTPCDigitRowData *data = (AliHLTTPCDigitRowData *)Allocate(size);
+ CompMemory2Memory(nrow,data,comp);
+ handler->Free();
+ delete handler;
+ return data;
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data)
+{
+ //Perform RLE on the data, and write it to the output file.
+ Bool_t out = kTRUE;
+ AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
+ UInt_t size = GetCompMemorySize(nrow,data);
+ UInt_t *comp =(UInt_t *)handler->Allocate(size);
+ Memory2CompMemory(nrow,data,comp);
+ CompMemory2CompBinary(nrow,comp,size);
+ handler->Free();
+ delete handler;
+ return out;
+}
+
+
+///////////////////////////////////////// Point IO
+Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data)
+{
+ //Writing spacepoints stored in data to the outputfile.
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ UInt_t size = npoint*sizeof(AliHLTTPCSpacePointData);
+ fwrite(data,size,1,fOutBinary);
+
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice)
+{
+ //Transform the space points in data, to global coordinates in slice.
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Transform","Memory")
+ <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ for(UInt_t i=0;i<npoint;i++){
+ Float_t xyz[3];
+ xyz[0] = data[i].fX;
+ xyz[1] = data[i].fY;
+ xyz[2] = data[i].fZ;
+ AliHLTTPCTransform::Local2Global(xyz,slice);
+ data[i].fX = xyz[0];
+ data[i].fY = xyz[1];
+ data[i].fZ = xyz[2];
+ }
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & npoint,AliHLTTPCSpacePointData *data)
+{
+ //Read the space points in inputfile, and store it in data.
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ Int_t size = GetFileSize();
+ npoint = size/sizeof(AliHLTTPCSpacePointData);
+ if(size==0) {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<"File Size == 0"<<ENDLOG;
+ return kFALSE;
+ }
+
+ if(fread(data,size,1,fInBinary)!=1){
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<"File Read Error "<<ENDLOG;
+ return kFALSE;
+ }
+ if(size%sizeof(AliHLTTPCSpacePointData)){
+ LOG(AliHLTTPCLog::kFatal,"AliHLTTPCMemHandler::Binary2Memory","File Size")
+ <<"File Size wrong "<<ENDLOG;
+ return kFALSE;
+ }
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<AliHLTTPCLog::kDec<<"Wrote "<<size<<" Bytes to Memory"<<ENDLOG;
+ return kTRUE;
+}
+
+///////////////////////////////////////// Track IO
+Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t ntrack,AliHLTTPCTrackSegmentData *data)
+{
+ //Write the tracks stored in data, to outputfile.
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
+ <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliHLTTPCTrackSegmentData *trackPt = data;
+ for(UInt_t i=0;i<ntrack;i++){
+ Int_t size=sizeof(AliHLTTPCTrackSegmentData)+trackPt->fNPoints*sizeof(UInt_t);
+ fwrite(trackPt,size,1,fOutBinary);
+ Byte_t *bytePt = (Byte_t*) trackPt;
+ bytePt += size;
+ trackPt = (AliHLTTPCTrackSegmentData*) bytePt;
+ }
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","File")
+ <<AliHLTTPCLog::kDec<<"Wrote "<<ntrack<<" Tracks to File"<<ENDLOG;
+
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data)
+{
+ //Read the tracks in inputfile, and store it in data.
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2Memory","Memory")
+ <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ ntrack=0;
+ AliHLTTPCTrackSegmentData *trackPt = data;
+ rewind(fInBinary);
+
+ while(!feof(fInBinary)){
+ if(fread(trackPt,sizeof(AliHLTTPCTrackSegmentData),1,fInBinary)!=1) break;
+ Int_t size=trackPt->fNPoints*sizeof(UInt_t);
+ if(fread(trackPt->fPointIDs,size,1,fInBinary)!=1) break;
+ Byte_t *bytePt = (Byte_t*) trackPt;
+ bytePt += sizeof(AliHLTTPCTrackSegmentData)+size;
+ trackPt = (AliHLTTPCTrackSegmentData*) bytePt;
+ ntrack++;
+ }
+ LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Binary2Memory","File")
+ <<AliHLTTPCLog::kDec<<"Wrote "<<ntrack<<" Tracks to Memory"<<ENDLOG;
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::TrackArray2Binary(AliHLTTPCTrackArray *array)
+{
+ //Write the trackarray to the outputfile.
+ if(!fOutBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Binary","File")
+ <<"No Output File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Binary","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliHLTTPCTrackSegmentData *data = (AliHLTTPCTrackSegmentData *)Allocate(array);
+
+ UInt_t ntrack;
+ TrackArray2Memory(ntrack,data,array);
+ Memory2Binary(ntrack,data);
+ Free();
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Binary2TrackArray(AliHLTTPCTrackArray *array)
+{
+ //Read the tracks in inputfile, and fill it in trackarray.
+ //array should already be constructed.
+ if(!fInBinary){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2TrackArray","File")
+ <<"No Input File"<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Binary2TrackArray","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ AliHLTTPCTrackSegmentData *data = (AliHLTTPCTrackSegmentData *)Allocate();
+ UInt_t ntrack;
+ Binary2Memory(ntrack,data);
+ Memory2TrackArray(ntrack,data,array);
+ Free();
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::TrackArray2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const
+{
+ //Fill the trackarray into the AliTrackSegmentData structures before writing to outputfile.
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Memory","Memory")
+ <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::TrackArray2Memory","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+
+ array->WriteTracks(ntrack,data);
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const
+{
+ //Fill the tracks in data into trackarray.
+
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ array->FillTracks(ntrack,data);
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMemHandler::Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array,Int_t slice) const
+{
+ //Fill the tracks in data into trackarray, and rotate the tracks to global coordinates.
+
+ if(!data){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliHLTTPCTrackSegmentData = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ if(!array){
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2TrackArray","Memory")
+ <<"Pointer to AliHLTTPCTrackArray = 0x0 "<<ENDLOG;
+ return kFALSE;
+ }
+ array->FillTracks(ntrack,data,slice);
+ return kTRUE;
+}
+
+void AliHLTTPCMemHandler::UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt)
+{
+ //Update the data pointer to the next padrow in memory.
+
+ Byte_t *tmp = (Byte_t*)tempPt;
+ Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
+ tmp += size;
+ tempPt = (AliHLTTPCDigitRowData*)tmp;
+}
+
+Int_t AliHLTTPCMemHandler::ComparePoints(UInt_t /*row*/,UShort_t pad,UShort_t time) const
+{
+ //compare two points
+ if(fNUsed>=fNDigits) return -2;
+
+ if(pad==fDPt[fNUsed]->fPad&&time==fDPt[fNUsed]->fTime) return 0;
+
+ if(pad<fDPt[fNUsed]->fPad) return -1;
+ if(pad==fDPt[fNUsed]->fPad&&time<fDPt[fNUsed]->fTime) return -1;
+
+ return 1;
+}
+
+Int_t AliHLTTPCMemHandler::CompareDigits(AliHLTTPCRandomDigitData *a,AliHLTTPCRandomDigitData *b) const
+{
+ //compare two digits
+ if(a->fPad==b->fPad && a->fTime == b->fTime) return 0;
+
+ if(a->fPad<b->fPad) return -1;
+ if(a->fPad==b->fPad && a->fTime<b->fTime) return -1;
+
+ return 1;
+}
--- /dev/null
+// @(#) $Id$
+
+#ifndef ALIHLTTPC_MEMHANDLER_H
+#define ALIHLTTPC_MEMHANDLER_H
+
+//_____________________________________________________________
+// AliHLTTPCMemHandler
+//
+// The HLT Binary File handler
+//
+// This class does all the memory I/O handling of HLT binary files.
+//
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>,
+// Anders Vestbo <mailto:vestbo$fi.uib.no>,
+// Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
+// *-- Copyright © ALICE HLT Group
+
+class AliHLTTPCDigitData;
+class AliHLTTPCSpacePointData;
+class AliHLTTPCDigitRowData;
+class AliHLTTPCTrackSegmentData;
+class AliHLTTPCTrackArray;
+class AliHLTTPCRandomPointData;
+class AliHLTTPCRandomDigitData;
+
+#ifdef use_newio
+class AliRunLoader;
+class AliRawEvent;
+#endif
+class AliTPCRawStream;
+
+class AliHLTTPCMemHandler {
+
+ public:
+ AliHLTTPCMemHandler();
+ virtual ~AliHLTTPCMemHandler();
+ AliHLTTPCMemHandler(const AliHLTTPCMemHandler& /*m*/){};
+ AliHLTTPCMemHandler& operator=(const AliHLTTPCMemHandler& /*&m*/)
+ {return (*this);}
+
+ void Reset(){CloseBinaryInput();CloseBinaryOutput();Free();}
+ void Init(Int_t s,Int_t p, Int_t *r=0);
+
+ Bool_t SetBinaryInput(char *name);
+ Bool_t SetBinaryInput(FILE *file);
+ void CloseBinaryInput();
+
+ Bool_t SetBinaryOutput(char *name);
+ Bool_t SetBinaryOutput(FILE *file);
+ void CloseBinaryOutput();
+
+ //Random cluster
+ void SetRandomCluster(Int_t maxnumber);
+ void SetRandomSeed(UInt_t seed){srand(seed);}
+ void SetRandomSeed();
+
+ void ResetRandom(){fNDigits = 0; fNUsed = 0;}
+ void Generate(Int_t row);
+ void SetNGenerate(Int_t number){(number>fNRandom)?fNGenerate=fNRandom:fNGenerate = number;}
+
+ void SetROI(Float_t *eta,Int_t *slice);
+ void ResetROI();
+
+ //Digit IO
+ Bool_t Memory2Binary(UInt_t nrow,AliHLTTPCDigitRowData *data);
+ Bool_t Binary2Memory(UInt_t & nrow,AliHLTTPCDigitRowData *data);
+
+ Int_t Memory2CompMemory(UInt_t nrow,AliHLTTPCDigitRowData *data,UInt_t *comp);
+ Int_t CompMemory2Memory(UInt_t nrow,AliHLTTPCDigitRowData *data,UInt_t *comp);
+ Bool_t CompMemory2CompBinary(UInt_t nrow,UInt_t *comp, UInt_t size=0);
+ Bool_t CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp);
+
+ virtual AliHLTTPCDigitRowData *CompBinary2Memory(UInt_t & nrow);
+ virtual Bool_t Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data);
+
+ UInt_t GetNRow(UInt_t *comp,UInt_t size);
+
+ //Point IO
+ Bool_t Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data);
+ Bool_t Binary2Memory(UInt_t & npoint,AliHLTTPCSpacePointData *data);
+ Bool_t Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice);
+ static void UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt);
+
+ //Track IO
+ Bool_t Memory2Binary(UInt_t ntrack,AliHLTTPCTrackSegmentData *data);
+ Bool_t Binary2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data);
+ Bool_t TrackArray2Binary(AliHLTTPCTrackArray *array);
+ Bool_t Binary2TrackArray(AliHLTTPCTrackArray *array);
+ Bool_t TrackArray2Memory(UInt_t & ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const;
+ Bool_t Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array) const;
+ Bool_t Memory2TrackArray(UInt_t ntrack,AliHLTTPCTrackSegmentData *data,AliHLTTPCTrackArray *array,Int_t slice) const;
+
+ //Memory Allocation
+ UInt_t GetAllocatedSize() const {return fSize;}
+ UInt_t GetFileSize();
+ UInt_t GetMemorySize(UInt_t nrow,UInt_t *comp) const;
+ UInt_t GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const;
+ UInt_t GetRandomSize() const;
+
+ Byte_t *Allocate(UInt_t size);
+ Byte_t *Allocate(); // allocate size of Binary Input File
+ Byte_t *Allocate(AliHLTTPCTrackArray *array);
+ Byte_t *GetDataPointer(UInt_t &size) {size = fSize; return fPt;}
+ FILE *GetFilePointer() {return fInBinary;}
+ void Free();
+
+ //Getters:
+ Int_t GetRowMin() const {return fRowMin;}
+ Int_t GetRowMax() const {return fRowMax;}
+ Int_t GetSlice() const {return fSlice;}
+ Int_t GetPatch() const {return fPatch;}
+
+ //virtual functions:
+ virtual void FreeDigitsTree() {fDummy=0; return;}
+ virtual Bool_t SetAliInput(char */*name*/){fDummy=0; return 0;}
+#ifdef use_newio
+ virtual Bool_t SetAliInput(AliRunLoader */*runloader*/){fDummy=0; return 0;}
+#endif
+ virtual void CloseAliInput(){fDummy=0; return;}
+ virtual Bool_t IsDigit(Int_t /*i*/=0){fDummy=0; return 0;}
+ virtual Bool_t SetMCOutput(char */*name*/){fDummy=0; return 0;}
+ virtual Bool_t SetMCOutput(FILE */*file*/){fDummy=0; return 0;}
+ virtual void CloseMCOutput(){fDummy=0; return;}
+ virtual Bool_t AliDigits2Binary(Int_t /*event*/=0,Bool_t /*altro*/=kFALSE){fDummy=0; return 0;}
+ virtual Bool_t AliDigits2CompBinary(Int_t /*event*/=0,Bool_t /*altro*/=kFALSE){fDummy=0; return 0;}
+ virtual AliHLTTPCDigitRowData *AliDigits2Memory(UInt_t & /*nrow*/,Int_t /*event*/=0){fDummy=0; return 0;}
+ virtual AliHLTTPCDigitRowData *AliAltroDigits2Memory(UInt_t & /*nrow*/,Int_t /*event*/=0,Bool_t /*eventmerge*/=kFALSE){fDummy=0; return 0;}
+ virtual void AliDigits2RootFile(AliHLTTPCDigitRowData */*rowPt*/,Char_t */*new_digitsfile*/){fDummy=0; return;}
+ virtual Bool_t AliPoints2Binary(Int_t /*eventn*/=0){fDummy=0; return 0;}
+ virtual AliHLTTPCSpacePointData *AliPoints2Memory(UInt_t & /*npoint*/,Int_t /*eventn*/=0){fDummy=0; return 0;}
+
+ //AliHLTTPCRawDataFileHandler
+ virtual Bool_t SetRawInput(Char_t */*name*/){fDummy=0; return 0;}
+ virtual Bool_t SetRawInput(ifstream */*file*/){fDummy=0; return 0;}
+ virtual void CloseRawInput(){}
+ virtual Int_t ReadRawInput(){fDummy=0; return 0;}
+ virtual Short_t** GetRawData(Int_t &/*channels*/, Int_t & /*timebins*/){fDummy=0; return 0;}
+
+ virtual Bool_t SetRawOutput(Char_t */*name*/){fDummy=0; return 0;}
+ virtual Bool_t SetRawOutput(ofstream */*file*/){fDummy=0; return 0;}
+ virtual void CloseRawOutput(){}
+ virtual Bool_t SaveRawOutput(){fDummy=0; return 0;}
+
+ virtual Bool_t SetMappingFile(Char_t */*name*/){fDummy=0; return 0;}
+ virtual Bool_t SetMappingFile(FILE */*file*/){fDummy=0; return 0;}
+ virtual void CloseMappingFile(){}
+ virtual Int_t ReadMappingFile(){fDummy=0; return 0;}
+
+ virtual Bool_t SetRawPedestalsInput(Char_t */*name*/){fDummy=0; return 0;}
+ virtual Bool_t SetRawPedestalsInput(ifstream */*file*/){fDummy=0; return 0;}
+ virtual void CloseRawPedestalsInput(){}
+ virtual Int_t ReadRawPedestalsInput(){fDummy=0; return 0;}
+
+ virtual AliHLTTPCDigitRowData* RawData2Memory(UInt_t &/*nrow*/,Int_t /*event*/=-1){fDummy=0; return 0;}
+ virtual Bool_t RawData2CompMemory(Int_t /*event*/=-1){fDummy=0; return 0;}
+
+ //AliHLTTPCDDLDataFileHandler
+#ifdef use_newio
+ virtual Bool_t SetReaderInput(AliRawEvent */*rawevent*/){fDummy=0; return 0;}
+ virtual Bool_t SetReaderInput(Char_t */*name*/,Int_t /*event*/=0){fDummy=0; return 0;}
+#else
+ virtual Bool_t SetReaderInput(Char_t */*name*/,Bool_t /*add*/=kTRUE){fDummy=0; return 0;}
+#endif
+ virtual void CloseReaderInput(){};
+
+ virtual AliHLTTPCDigitRowData* DDLData2Memory(UInt_t &/*nrow*/,Int_t /*event*/=-1){fDummy=0; return 0;}
+ virtual Bool_t DDLData2CompBinary(Int_t /*event*/=-1){fDummy=0; return 0;}
+
+ virtual AliTPCRawStream* GetTPCRawStream(){fDummy=0; return 0;}
+
+ protected:
+ Int_t fRowMin; //min row
+ Int_t fRowMax; //max row
+ Int_t fSlice; //slice
+ Int_t fPatch; //patch
+
+ Int_t fEtaMinTimeBin[159]; //for ROI in eta only
+ Int_t fEtaMaxTimeBin[159]; //for ROI in eta only
+
+ FILE *fInBinary;//!
+ FILE *fOutBinary;//!
+
+ private:
+
+ Byte_t *fPt;//!
+ UInt_t fSize; //size of allocated data structure
+
+ Bool_t fIsRandom; //random data generated
+ Int_t fNRandom; //count random digits
+ Int_t fNGenerate; //count generated digits
+ Int_t fNUsed; //count used digits
+ Int_t fNDigits; //count digits from digitstree
+
+ AliHLTTPCRandomDigitData **fDPt;//!
+ AliHLTTPCRandomDigitData *fRandomDigits;//!
+
+ Int_t fDummy; // to fool the virtual const problem
+ // of the coding conventions tool
+
+ void Write(UInt_t *comp, UInt_t & index, UInt_t & subindex, UShort_t value) const;
+ UShort_t Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const;
+ UShort_t Test(UInt_t *comp, UInt_t index, UInt_t subindex) const;
+
+ void DigitizePoint(Int_t row,Int_t pad, Int_t time,Int_t charge);
+ void QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last);
+ Int_t ComparePoints(UInt_t row,UShort_t pad,UShort_t time) const ;
+ Int_t CompareDigits(AliHLTTPCRandomDigitData *a,AliHLTTPCRandomDigitData *b) const;
+ void AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge) const;
+ void AddRandom(AliHLTTPCDigitData *data,UInt_t & ndata);
+ void MergeDataRandom(AliHLTTPCDigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+ void AddDataRandom(AliHLTTPCDigitData *data,UInt_t & ndata,
+ UInt_t row,UShort_t pad,UShort_t time,UShort_t charge);
+
+
+ ClassDef(AliHLTTPCMemHandler,1) // Memory handler class
+};
+#endif
--- /dev/null
+//$Id$
+
+// Author: Uli Frankenfeld <mailto:franken@fi.uib.no>
+//*-- Copyright © Uli
+
+#include "AliHLTTPCStandardIncludes.h"
+
+#include "AliHLTTPCLogging.h"
+#include "AliHLTTPCMerger.h"
+#include "AliHLTTPCTrack.h"
+#include "AliHLTTPCTrackSegmentData.h"
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCTrackArray.h"
+
+#ifdef use_root //use root ntuple for slow merge
+#include <TNtuple.h>
+#include <TTree.h>
+#include <TFile.h>
+#endif
+
+/** \class AliHLTTPCMerger
+<pre>
+//_____________________________________________________________
+// AliHLTTPCMerger
+//
+// The HLTTPC merger base class
+//
+</pre>
+*/
+
+#if __GNUC__ >= 3
+using namespace std;
+#endif
+
+ClassImp(AliHLTTPCMerger)
+
+AliHLTTPCMerger::AliHLTTPCMerger()
+{
+ //Default constructor
+ fInTrack=0;
+ fOutTrack=0;
+ fCurrentTracks=0;
+ fNIn=0;
+}
+
+AliHLTTPCMerger::~AliHLTTPCMerger()
+{
+ //Destructor
+ DeleteArray();
+}
+
+void AliHLTTPCMerger::InitMerger(Int_t ntrackarrays,Char_t *tracktype)
+{
+ //Used to setup all arrays
+
+ if(strcmp(tracktype,"AliHLTTPCTrack")==0) fTrackType='t';
+ else if(strcmp(tracktype,"AliHLTTPCConfMapTrack")==0) fTrackType='c';
+#ifdef INCLUDE_TPC_HOUGH
+ else if(strcmp(tracktype,"AliHLTTPCHoughTrack")==0) fTrackType='h';
+#endif
+ else
+ LOG(AliHLTTPCLog::kError,"AliHLTTPCMerger::AliHLTTPCMerger","Track types")
+ <<"Unknown tracktype"<<ENDLOG;
+ SetArray(ntrackarrays);
+ fCurrentTracks=0;
+
+}
+
+void AliHLTTPCMerger::DeleteArray()
+{
+ //delete arrays
+ for(Int_t i=0; i<fNIn;i++)
+ {
+ if(!fInTrack[i]) continue;
+ delete fInTrack[i];
+ fInTrack[i]=0;
+ }
+ if(fInTrack)
+ delete[] fInTrack;
+ if(fOutTrack)
+ delete fOutTrack;
+ fInTrack=0;
+ fOutTrack=0;
+}
+
+void AliHLTTPCMerger::SetArray(Int_t nin)
+{
+ //set arrays
+ DeleteArray();//Make sure arrays are cleaned
+
+ fNIn = nin;
+ fInTrack = new AliHLTTPCTrackArray*[fNIn];
+ for(Int_t i=0; i<fNIn;i++)
+ {
+#ifdef INCLUDE_TPC_HOUGH
+ if(fTrackType=='h')
+ fInTrack[i] = new AliHLTTPCTrackArray("AliHLTTPCHoughTrack");
+ else
+#endif
+ fInTrack[i] = new AliHLTTPCTrackArray("AliHLTTPCTrack");
+
+ }
+#ifdef INCLUDE_TPC_HOUGH
+ if(fTrackType=='h')
+ fOutTrack= new AliHLTTPCTrackArray("AliHLTTPCHoughTrack");
+ else
+#endif
+ fOutTrack= new AliHLTTPCTrackArray("AliHLTTPCTrack");
+}
+
+void AliHLTTPCMerger::Reset()
+{
+ //reset
+ for(Int_t i=0; i<fNIn;i++)
+ {
+ fInTrack[i]->Reset();
+ }
+ fOutTrack->Reset();
+}
+
+void AliHLTTPCMerger::FillTracks(Int_t ntracks, AliHLTTPCTrackSegmentData* tr)
+{
+ //Read tracks from shared memory (or memory)
+ AliHLTTPCTrackArray *destination = GetInTracks(fCurrentTracks);
+ if(Is2Global())
+ destination->FillTracks(ntracks, tr, fSlice);
+ else
+ destination->FillTracks(ntracks, tr);
+}
+
+void AliHLTTPCMerger::AddAllTracks()
+{
+ //add all tracks
+ for(Int_t i=0; i<GetNIn();i++)
+ {
+ AliHLTTPCTrackArray *in = GetInTracks(i);
+ AliHLTTPCTrackArray *out = GetOutTracks();
+ out->AddTracks(in);
+ }
+}
+
+void AliHLTTPCMerger::SortGlobalTracks(AliHLTTPCTrack **tracks, Int_t ntrack)
+{
+ //sort global tracks
+ AliHLTTPCTrack **tmp = new AliHLTTPCTrack*[ntrack];
+ for(Int_t i=0;i<ntrack;i++) tmp[i] = tracks[i];
+ Int_t *t = new Int_t[ntrack];
+ for(Int_t i=0;i<ntrack;i++) t[i]=-1;
+
+ for(Int_t j=0;j<ntrack;j++)
+ {
+ Double_t minr=300;
+ Int_t mini=0;
+ for(Int_t i=0;i<ntrack;i++)
+ {
+ if(!tracks[i]) continue;
+ Double_t rr=pow(tracks[i]->GetFirstPointX(),2)+pow(tracks[i]->GetFirstPointY(),2);
+ Double_t r=sqrt(rr);
+ if(r<minr){
+ minr=r;
+ mini=i;
+ }
+ }
+ t[j]=mini;
+ tracks[mini]=0;
+ }
+ for(Int_t i=0;i<ntrack;i++) tracks[i] = tmp[t[i]];
+ delete[] t;
+ delete[] tmp;
+}
+
+void AliHLTTPCMerger::SortTracks(AliHLTTPCTrack **tracks, Int_t ntrack) const
+{
+ //sort tracks
+ AliHLTTPCTrack **tmp = new AliHLTTPCTrack*[ntrack];
+ for(Int_t i=0;i<ntrack;i++) tmp[i] = tracks[i];
+ Int_t *t = new Int_t[ntrack];
+ for(Int_t i=0;i<ntrack;i++) t[i]=-1;
+
+ for(Int_t j=0;j<ntrack;j++)
+ {
+ Double_t minx=300;
+ Int_t mini=0;
+ for(Int_t i=0;i<ntrack;i++)
+ {
+ if(!tracks[i]) continue;
+ if(tracks[i]->GetFirstPointX()<minx)
+ {
+ minx=tracks[i]->GetFirstPointX();
+ mini=i;
+ }
+ }
+ t[j]=mini;
+ tracks[mini]=0;
+ }
+ for(Int_t i=0;i<ntrack;i++) tracks[i] = tmp[t[i]];
+ delete[] t;
+ delete[] tmp;
+}
+
+void AliHLTTPCMerger::AddTrack(AliHLTTPCTrackArray *mergedtrack,AliHLTTPCTrack *track)
+{
+ // add tracks
+ AliHLTTPCTrack *t[1];
+ t[0] = track;
+ MultiMerge(mergedtrack,t,1);
+}
+
+AliHLTTPCTrack * AliHLTTPCMerger::MergeTracks(AliHLTTPCTrackArray *mergedtrack,AliHLTTPCTrack *t0,AliHLTTPCTrack *t1)
+{
+ //merge tracks
+ AliHLTTPCTrack *t[2];
+ t[0] = t0;
+ t[1] = t1;
+ SortTracks(t,2);
+ return MultiMerge(mergedtrack,t,2);
+}
+
+AliHLTTPCTrack * AliHLTTPCMerger::MultiMerge(AliHLTTPCTrackArray *mergedtracks,AliHLTTPCTrack **tracks, Int_t ntrack)
+{
+ //multi merge the tracks
+ //check npoints
+ Int_t nps = 0;
+ for(Int_t i=0;i<ntrack;i++)
+ {
+ nps+=tracks[i]->GetNHits();
+ }
+ if(nps>AliHLTTPCTransform::GetNRows())
+ {
+ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMerger::MultiMerge","Adding Points")
+ <<AliHLTTPCLog::kDec<<"Too many Points: "<<nps<<ENDLOG;
+ return 0;
+ }
+
+ //create new track
+ AliHLTTPCTrack *newtrack = mergedtracks->NextTrack();
+ //copy points
+ UInt_t * nn = new UInt_t[AliHLTTPCTransform::GetNRows()];
+ nps = 0;
+
+ // for(Int_t i=0;i<ntrack;i++){
+ for(Int_t i=ntrack-1;i>=0;i--)
+ {
+ memcpy(&nn[nps],tracks[i]->GetHitNumbers(),tracks[i]->GetNHits()*sizeof(UInt_t));
+ nps+=tracks[i]->GetNHits();
+ }
+ AliHLTTPCTrack *tpf=tracks[0];
+ AliHLTTPCTrack *tpl=tracks[ntrack-1];
+ AliHLTTPCTrack *best = tpf;
+ if(tpf->GetNHits()<tpl->GetNHits() && Is2Global())
+ best = tpl;//Best means = most points and therefore best fit (in global case)
+
+ newtrack->SetNHits(nps);
+ newtrack->SetHits(nps,nn);
+ newtrack->SetFirstPoint(tpf->GetFirstPointX(),tpf->GetFirstPointY(),tpf->GetFirstPointZ());
+ newtrack->SetLastPoint(tpl->GetLastPointX(),tpl->GetLastPointY(),tpl->GetLastPointZ());
+ newtrack->SetPt(best->GetPt());
+ newtrack->SetPsi(best->GetPsi());
+ newtrack->SetTgl(best->GetTgl());
+ newtrack->SetCharge(tpf->GetCharge());
+ delete [] nn;
+ return newtrack;
+}
+
+void* AliHLTTPCMerger::GetNtuple(char *varlist) const
+{
+ //get ntuple
+#ifdef use_root
+ TNtuple* nt = new TNtuple("ntuple","ntuple",varlist);
+ return (void*) nt;
+#else
+ return 0;
+#endif
+}
+
+void* AliHLTTPCMerger::GetNtuple() const
+{
+ //get ntuple
+#ifdef use_root
+ TNtuple* nt = new TNtuple("ntuple","ntuple",
+ "dx:dy:dz:dk:dpsi:dtgl:dq:disx:disy:disz:dis:n0:n1:diff:drx:dry:drz");
+ return (void*) nt;
+#else
+ return 0;
+#endif
+}
+
+Bool_t AliHLTTPCMerger::WriteNtuple(char *filename, void* nt) const
+{
+ //write ntuple
+#ifdef use_root
+ TNtuple *ntuple=(TNtuple *) nt;
+ TFile *f = new TFile(filename,"RECREATE");
+ ntuple->Write();
+ f->Close();
+ delete ntuple;
+ return kTRUE;
+#else
+ return kFALSE;
+#endif
+}
+
+void AliHLTTPCMerger::FillNtuple(void *nt,AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+ //fill ntuple
+ Float_t data[17];
+ if(outertrack->IsPoint()&&innertrack->IsPoint())
+ {
+ data[0] =Float_t(innertrack->GetPointX()-outertrack->GetPointX());
+ data[1] =Float_t(innertrack->GetPointY()-outertrack->GetPointY());
+ data[2] =Float_t(innertrack->GetPointZ()-outertrack->GetPointZ());
+ data[3] =Float_t(innertrack->GetKappa()-outertrack->GetKappa());
+ Double_t psi= innertrack->GetPointPsi() - outertrack->GetPointPsi();
+ if(psi>AliHLTTPCTransform::Pi()) psi-=AliHLTTPCTransform::TwoPi();
+ else if(psi<-AliHLTTPCTransform::Pi()) psi+=AliHLTTPCTransform::TwoPi();
+ data[4] =Float_t(psi);
+ data[5] =Float_t(innertrack->GetTgl()-outertrack->GetTgl());
+ data[6] =Float_t(innertrack->GetCharge()-outertrack->GetCharge());
+ data[7] =Float_t(innertrack->GetLastPointX()-outertrack->GetFirstPointX());
+ data[8] =Float_t(innertrack->GetLastPointY()-outertrack->GetFirstPointY());
+ data[9] =Float_t(innertrack->GetLastPointZ()-outertrack->GetFirstPointZ());
+ data[10] =sqrt(pow(data[7],2)+pow(data[8],2)+pow(data[9],2));
+ data[11]= outertrack->GetNHits();
+ data[12]= innertrack->GetNHits();
+ data[13] = Float_t(TrackDiff(innertrack,outertrack));
+ data[14]=0;
+ data[15]=0;
+ data[16]=0;
+#ifdef use_root
+ TNtuple *ntuple = (TNtuple *) nt;
+ ntuple->Fill(data);
+#endif
+ }
+}
+
+void AliHLTTPCMerger::FillNtuple(void *nt,Float_t *data) const
+{
+ //fill ntuple
+#ifdef use_root
+ TNtuple *ntuple = (TNtuple *) nt;
+ ntuple->Fill(data);
+#endif
+}
+
+Double_t AliHLTTPCMerger::GetAngle(Double_t a1,Double_t a2)
+{
+ //get angle
+ Double_t da = a1 - a2 + 4*AliHLTTPCTransform::Pi();
+ da = fmod(da,AliHLTTPCTransform::TwoPi());
+ if(da>AliHLTTPCTransform::Pi()) da = AliHLTTPCTransform::TwoPi()-da;
+ return da;
+}
+
+void AliHLTTPCMerger::SetParameter(Double_t maxy, Double_t maxz, Double_t maxkappa, Double_t maxpsi, Double_t maxtgl)
+{
+ //set parameters for merger
+ fMaxY = maxy;
+ fMaxZ = maxz;
+ fMaxKappa = maxkappa;
+ fMaxPsi = maxpsi;
+ fMaxTgl = maxtgl;
+}
+
+Bool_t AliHLTTPCMerger::IsTrack(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+ //is track to be merged
+ if(innertrack->GetCharge()!=outertrack->GetCharge()) return kFALSE;
+ if( (!innertrack->IsPoint()) || (!outertrack->IsPoint()) ) return kFALSE;
+ if(innertrack->GetNHits()+outertrack->GetNHits()>AliHLTTPCTransform::GetNRows()) return kFALSE;
+
+ if(fabs(innertrack->GetPointY()-outertrack->GetPointY()) >fMaxY) return kFALSE;
+ if(fabs(innertrack->GetPointZ()-outertrack->GetPointZ()) >fMaxZ) return kFALSE;
+ if(fabs(innertrack->GetKappa()-outertrack->GetKappa()) >fMaxKappa) return kFALSE;
+ if(GetAngle(innertrack->GetPointPsi(),outertrack->GetPointPsi()) >fMaxPsi) return kFALSE;
+ if(fabs(innertrack->GetTgl()-outertrack->GetTgl()) >fMaxTgl) return kFALSE;
+ //if no rejection up to this point: merge!!
+ return kTRUE;
+}
+
+Bool_t AliHLTTPCMerger::IsRTrack(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+ //same as IsTrack
+ return IsTrack(innertrack,outertrack);
+}
+
+Double_t AliHLTTPCMerger::TrackDiff(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+ //return track difference
+ Double_t diff =-1;
+ Double_t x[4],y[4],z[4],dy[4],dz[4];
+ AliHLTTPCTrack *tracks[2];
+
+ tracks[0] = innertrack;
+ tracks[1] = outertrack;
+ SortGlobalTracks(tracks,2);
+ innertrack = tracks[0];
+ outertrack = tracks[1];
+
+ x[0] = innertrack->GetFirstPointX();
+ x[1] = innertrack->GetLastPointX();
+ x[2] = outertrack->GetFirstPointX();
+ x[3] = outertrack->GetLastPointX();
+
+ y[0] = innertrack->GetFirstPointY();
+ y[1] = innertrack->GetLastPointY();
+ y[2] = outertrack->GetFirstPointY();
+ y[3] = outertrack->GetLastPointY();
+
+ z[0] = innertrack->GetFirstPointZ();
+ z[1] = innertrack->GetLastPointZ();
+ z[2] = outertrack->GetFirstPointZ();
+ z[3] = outertrack->GetLastPointZ();
+
+
+ outertrack->CalculatePoint(x[0]);
+ if(!outertrack->IsPoint()) return diff;
+ dy[0] = fabs(y[0] - outertrack->GetPointY());
+ dz[0] = fabs(z[0] - outertrack->GetPointZ());
+
+ outertrack->CalculatePoint(x[1]);
+ if(!outertrack->IsPoint()) return diff;
+ dy[1] = fabs(y[1] - outertrack->GetPointY());
+ dz[1] = fabs(z[1] - outertrack->GetPointZ());
+
+ innertrack->CalculatePoint(x[2]);
+ if(!innertrack->IsPoint()) return diff;
+ dy[2] = fabs(y[2] - innertrack->GetPointY());
+ dz[2] = fabs(z[2] - innertrack->GetPointZ());
+
+ innertrack->CalculatePoint(x[3]);
+ if(!innertrack->IsPoint()) return diff;
+ dy[3] = fabs(y[3] - innertrack->GetPointY());
+ dz[3] = fabs(z[3] - innertrack->GetPointZ());
+
+ diff=0;
+ for(Int_t i=0;i<4;i++)
+ diff+=sqrt(dy[i]*dy[i]+dz[i]*dz[i]);
+ return diff;
+}
+
+void AliHLTTPCMerger::PrintDiff(AliHLTTPCTrack *innertrack,AliHLTTPCTrack *outertrack)
+{
+ // print difference
+ if(!innertrack->IsPoint()||!outertrack->IsPoint())
+ {
+ LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMerger::PrintDiff","No Points")<<ENDLOG;
+ //cerr<<"AliHLTTPCMerger::PrintDiff: No Points"<<endl;
+ //cerr<<"---------------------------"<<endl;
+ return;
+ }
+
+ Double_t dx = innertrack->GetPointX()-outertrack->GetPointX();
+ Double_t dy = innertrack->GetPointY()-outertrack->GetPointY();
+ Double_t dz = innertrack->GetPointZ()-outertrack->GetPointZ();
+ Double_t dk = innertrack->GetKappa()-outertrack->GetKappa();
+ Double_t dpsi= innertrack->GetPointPsi() - outertrack->GetPointPsi();
+ if(dpsi>AliHLTTPCTransform::Pi()) dpsi-=AliHLTTPCTransform::TwoPi();
+ else if(dpsi<-AliHLTTPCTransform::Pi())dpsi+=AliHLTTPCTransform::TwoPi();
+ //Double_t dpsi = GetAngle(innertrack->GetPointPsi(),outertrack->GetPointPsi());