L3 becomes HLT
[u/mrichter/AliRoot.git] / HLT / src / AliLevel3.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliHLTStandardIncludes.h"
7
8 #ifndef no_root
9 #include <TFile.h>
10 #include <TDirectory.h>
11 #include <TClonesArray.h>
12 #include <TStopwatch.h>
13 #include <Riostream.h>
14 #endif
15
16 #ifdef use_newio
17 #include <AliRunLoader.h>
18 #endif
19
20 #include "AliHLTLogging.h"
21 #include "AliLevel3.h"
22 #include "AliHLTConfMapper.h"
23 #include "AliHLTVertex.h"
24 #include "AliHLTVertexFinder.h"
25 #include "AliHLTTrackMerger.h"
26 #include "AliHLTGlobalMerger.h"
27 #include "AliHLTInterMerger.h"
28 #include "AliHLTConfMapPoint.h"
29 #include "AliHLTConfMapTrack.h"
30 #include "AliHLTTransform.h"
31 #include "AliHLTClustFinderNew.h"
32 #include "AliHLTDigitData.h"
33 #include "AliHLTTrackArray.h"
34 #include "AliHLTMemHandler.h"
35 #include "AliHLTFitter.h"
36 #ifdef use_aliroot
37 #include "AliHLTFileHandler.h"
38 #endif
39 #include "AliHLTBenchmark.h"
40 #include "AliHLTDigitData.h"
41 #include "AliHLTTrackSegmentData.h"
42 #include "AliHLTSpacePointData.h"
43 #include "AliHLTVertexData.h"
44 #include "AliHLTDDLDataFileHandler.h"
45
46 /** \class AliLevel3
47 <pre>
48 //_____________________________________________________________
49 //
50 //  AliLevel3
51 //
52 //  Interface class for Level3 tracker.
53 //  For example how to use, see exa/runtracker.C (root)
54 //  or programs/runtracker.cxx (standalone program).
55 //Begin_Html 
56 //<img src="tpcsectorsnb.gif">
57 //End_Html
58 </pre>
59 */
60
61 ClassImp(AliLevel3)
62
63 Bool_t AliLevel3::fgDoVertexFit = kTRUE;//Include the vertex in the final track fit
64
65 AliLevel3::AliLevel3()
66 {
67   //Default constructor. Should also be used when input is from binary files.
68   //In that case the path to where the binary files are located has to be
69   //passed to the AliLevel::Init function.
70   
71   fVertexFinder=0;
72   fVertex=0;
73   fTracker=0;
74   fTrackMerger=0;
75   fInterMerger=0;
76   fFileHandler=0;
77   fGlobalMerger=0;
78   fInputFile=0;
79 #ifdef use_newio
80   fRunLoader=0;
81 #endif
82 }
83
84 AliLevel3::AliLevel3(Char_t *infile)
85 {
86   //Constructor to use for when input is anything else but binary files,
87   //meaning rootfiles or raw files.
88   
89   fVertexFinder=0;
90   fVertex=0;
91   fTracker=0;
92   fTrackMerger=0;
93   fInterMerger=0;
94   fFileHandler=0;
95   fGlobalMerger=0;
96   fInputFile = infile;
97 #ifdef use_newio
98   fRunLoader=0;
99 #endif
100 }
101
102 #ifdef use_newio
103 AliLevel3::AliLevel3(AliRunLoader *rl)
104 {
105   //Constructor to use when input is aliroot runloader
106   fVertexFinder=0;
107   fVertex=0;
108   fTracker=0;
109   fTrackMerger=0;
110   fInterMerger=0;
111   fFileHandler=0;
112   fGlobalMerger=0;
113   fInputFile=0;
114   fRunLoader = rl;
115 }
116 #endif
117
118 void AliLevel3::Init(Char_t *path,EFileType filetype,Int_t npatches)
119 {
120   //Init the whole standard tracker chain
121 #ifndef use_newio
122   if (filetype==kRunLoader){
123     LOG(AliHLTLog::kError,"AliLevel3::Init","Files")
124         <<"You have not supplied the input rootfile; if you want "
125         <<"to run with RunLoader use -Duse_newio for compiling!"<<ENDLOG;
126   }
127 #endif
128
129   if((filetype!=kBinary) && (filetype!=kDate) 
130        && (filetype!=kRunLoader)&& !fInputFile)
131     {
132       LOG(AliHLTLog::kError,"AliLevel3::Init","Files")
133         <<"You have not supplied the input rootfile; use the appropriate ctor!"<<ENDLOG;
134       return;
135     }
136 #if use_newio
137   if((filetype==kRunLoader) && !fRunLoader)
138     {
139       LOG(AliHLTLog::kError,"AliLevel3::Init","Files")
140         <<"You have not supplied the input runloader; use the appropriate ctor!"<<ENDLOG;
141       return;
142     }
143 #endif
144   
145   fWriteOut = kFALSE;
146   fPileUp = kFALSE;
147   fNoCF=kFALSE;
148   fUseBinary = (filetype==kBinary);
149   SetPath(path);
150   
151   fDoRoi = kFALSE;
152   fDoNonVertex = kFALSE;
153   fFindVertex = kFALSE;
154   SetClusterFinderParam();
155
156   fEta[0] = 0.;
157   fEta[1] = 1.1;
158
159   fEvent=0;
160 #ifdef use_aliroot /*just to be sure*/
161   AliHLTFileHandler::CleanStaticIndex();
162 #endif
163
164   switch(npatches){
165   case 0:
166     fNPatch = 1;
167     fRow[0][0] = AliHLTTransform::GetFirstRow(3);
168     fRow[0][1] = AliHLTTransform::GetLastRow(5);
169     break;
170   case 1:
171     fNPatch = 1;        //number of patches change row in process
172     fRow[0][0] = 0;
173     fRow[0][1] = AliHLTTransform::GetLastRow(-1);
174     break;
175   case 2:
176     fNPatch = 2;        //number of patches change row in process
177     fRow[0][0] = 0;     // first row
178     fRow[0][1] = AliHLTTransform::GetLastRow(1);
179     fRow[1][0] = AliHLTTransform::GetFirstRow(2);
180     fRow[1][1] = AliHLTTransform::GetLastRow(5);
181     break;
182   default: 
183     fNPatch = 6;        
184     fRow[0][0] = AliHLTTransform::GetFirstRow(0);
185     fRow[0][1] = AliHLTTransform::GetLastRow(0);
186     fRow[1][0] = AliHLTTransform::GetFirstRow(1);
187     fRow[1][1] = AliHLTTransform::GetLastRow(1);
188     fRow[2][0] = AliHLTTransform::GetFirstRow(2);
189     fRow[2][1] = AliHLTTransform::GetLastRow(2);
190     fRow[3][0] = AliHLTTransform::GetFirstRow(3);
191     fRow[3][1] = AliHLTTransform::GetLastRow(3);
192     fRow[4][0] = AliHLTTransform::GetFirstRow(4);
193     fRow[4][1] = AliHLTTransform::GetLastRow(4);
194     fRow[5][0] = AliHLTTransform::GetFirstRow(5);
195     fRow[5][1] = AliHLTTransform::GetLastRow(5);
196   }
197
198   fVertexFinder = new AliHLTVertexFinder();
199   fVertex = new AliHLTVertex();
200   fTracker = new AliHLTConfMapper();
201   fTrackMerger = new AliHLTTrackMerger(fNPatch);
202   fInterMerger = new AliHLTInterMerger();
203   fGlobalMerger = new AliHLTGlobalMerger();
204   SetMergerParameters();//Set default merger parameters
205 #ifdef use_aliroot
206   if(filetype==kRoot){
207     fFileHandler = new AliHLTFileHandler(kTRUE); //static version
208     fFileHandler->SetAliInput(fInputFile);
209   }else if(filetype==kRaw){
210     fFileHandler = new AliHLTDDLDataFileHandler();
211     fFileHandler->SetReaderInput(fInputFile);
212   }else if(filetype==kDate){
213     fFileHandler = new AliHLTDDLDataFileHandler();
214     fFileHandler->SetReaderInput(fInputFile,-1);
215   }
216 #if use_newio
217   else if(filetype==kRunLoader){
218     fFileHandler = new AliHLTFileHandler(kTRUE); //static version
219     fFileHandler->SetAliInput(fRunLoader);
220   }
221 #endif
222   else{
223     fFileHandler = new AliHLTMemHandler();
224   }
225 #else
226   if(filetype==kRaw){
227     fFileHandler = new AliHLTDDLDataFileHandler();
228     fFileHandler->SetReaderInput(fInputFile);
229   }else{
230     fFileHandler = new AliHLTMemHandler();
231   }
232 #endif
233   fBenchmark = new AliHLTBenchmark();
234 }
235
236 void AliLevel3::DoBench(char* name)
237
238   //dobench
239   fBenchmark->Analyze(name);
240   delete fBenchmark;
241   fBenchmark = new AliHLTBenchmark();
242 }
243
244 void AliLevel3::DoMc(char* file)
245
246   //domc
247 #ifdef use_aliroot
248   if(!fFileHandler->IsDigit(fEvent))
249     fFileHandler->SetMCOutput(file);
250 #endif
251 }
252
253 AliLevel3::~AliLevel3()
254 {
255   //Destructor
256   if(fVertexFinder) delete fVertexFinder;
257   if(fVertex) delete fVertex;
258   if(fTracker) delete fTracker;
259   if(fTrackMerger) delete fTrackMerger;
260   if(fInterMerger) delete fInterMerger;
261   if(fFileHandler) delete fFileHandler;
262   if(fGlobalMerger) delete fGlobalMerger;
263 }
264
265 void AliLevel3::SetClusterFinderParam(Float_t fXYError, Float_t fZError, Bool_t deconv)
266
267   //set cluster finder parameter
268   fXYClusterError=fXYError;
269   fZClusterError=fZError;
270   fClusterDeconv=deconv;
271 }
272
273 void AliLevel3::SetTrackerParam(Int_t phi_segments, Int_t eta_segments,
274                                 Int_t trackletlength, Int_t tracklength,
275                                 Int_t rowscopetracklet, Int_t rowscopetrack,
276                                 Double_t min_pt_fit, Double_t maxangle,
277                                 Double_t goodDist, Double_t hitChi2Cut,
278                                 Double_t goodHitChi2, Double_t trackChi2Cut,
279                                 Int_t maxdist,Double_t maxphi,Double_t maxeta,
280                                Bool_t vertexconstraint)
281 {
282   //Set parameters input to the tracker
283   //If no arguments are given, default parameters will be used
284   
285   fTracker->SetNSegments(phi_segments,eta_segments);
286   fTracker->SetMaxDca(min_pt_fit);
287   fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexconstraint);
288   fTracker->SetTrackletCuts(maxangle,goodDist,vertexconstraint);
289   if(vertexconstraint)
290     fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack,maxphi,maxeta);
291   else
292     fTracker->NonVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
293   fTracker->InitVolumes();
294 }
295
296 void AliLevel3::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
297 {
298   //set global merger parameter
299   fGlobalMerger->SetParameter(maxy,maxz,maxkappa,maxpsi,maxtgl);
300 }
301
302 void AliLevel3::ProcessEvent(Int_t first,Int_t last,Int_t event)
303 {
304   //Do tracking on all slices in region [first,last]
305   //Slices numbering in TPC goes from 0-35, which means that one slice
306   //corresponds to inner+outer sector.E.g. slice 2 corresponds to
307   //inner=2 + outer=38.
308
309   fGlobalMerger->Setup(first,last);
310 #ifdef use_aliroot
311   if(fEvent!=event) AliHLTFileHandler::CleanStaticIndex();
312 #endif
313   fEvent=event;
314   for(Int_t i=first; i<=last; i++){
315     ProcessSlice(i);
316     fGlobalMerger->SetVertex(fVertex);
317     fGlobalMerger->InitSlice(i);
318     fGlobalMerger->FillTracks(fNTrackData,fTrackData);
319     fFileHandler->Free();   //free the memory
320     fNTrackData=0;
321     fTrackData=0;
322   }
323   fBenchmark->Start("Global track merger");
324   //fGlobalMerger->AddAllTracks();
325   fGlobalMerger->Merge();
326   //fGlobalMerger->SlowMerge(fWriteOutPath);
327   fBenchmark->Stop("Global track merger");
328   
329   FitGlobalTracks();
330   
331   if(fWriteOut) WriteResults(); 
332   fFileHandler->FreeDigitsTree();
333 }
334
335 void AliLevel3::ProcessSlice(Int_t slice)
336 {
337   //process slice
338   char name[256];
339   Bool_t UseCF = kFALSE;
340 #ifdef use_aliroot
341   UseCF = fFileHandler->IsDigit(fEvent);
342 #endif
343   if(fUseBinary)
344     UseCF = kTRUE;   //In case you are not using aliroot
345   if(fNoCF == kTRUE) //In case you don't want to run with cluster finder
346     UseCF = kFALSE;
347
348   const Int_t kmaxpoints=120000;
349   const Int_t kpointsize = kmaxpoints * sizeof(AliHLTSpacePointData);
350   AliHLTMemHandler *memory = new AliHLTMemHandler();
351
352   fTrackMerger->Reset();
353   fTrackMerger->SetRows(fRow[0]);
354   
355   for(Int_t patch=fNPatch-1;patch>=0;patch--){
356     fFileHandler->Init(slice,patch,&fRow[patch][0]);
357     UInt_t npoints=0;
358     AliHLTSpacePointData *points =0;
359     UInt_t ndigits=0;
360     AliHLTDigitRowData *digits =0;
361     if(UseCF){
362       if(fUseBinary){
363         if(!fDoRoi){ 
364           if(1){     //Binary to Memory
365             fFileHandler->Free();
366             if(fNPatch == 1)
367               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
368             else
369               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
370             if(!fFileHandler->SetBinaryInput(name)) return;
371             if(fPileUp)
372               { //Read binary files which are not RLE
373                 digits = (AliHLTDigitRowData*)fFileHandler->Allocate();
374                 fFileHandler->Binary2Memory(ndigits,digits); 
375               }
376             else //Read RLE binary files
377               digits= (AliHLTDigitRowData *)fFileHandler->CompBinary2Memory(ndigits);
378
379             fFileHandler->CloseBinaryInput(); 
380           }
381
382           if(0){     //Binary to Memory with Benchmark 
383             fFileHandler->Free();
384             if(fNPatch == 1)
385               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
386             else
387               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
388             if(!memory->SetBinaryInput(name)) return;
389             UInt_t compsize=memory->GetFileSize();
390             UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
391             memory->CompBinary2CompMemory(ndigits,comp);
392             memory->CloseBinaryInput();
393             UInt_t datasize=memory->GetMemorySize(ndigits,comp);
394             digits=(AliHLTDigitRowData *)fFileHandler->Allocate(datasize);
395             fBenchmark->Start("Unpacker"); 
396             fFileHandler->CompMemory2Memory(ndigits,digits,comp); 
397             fBenchmark->Stop("Unpacker");
398             memory->Free();
399           }
400   
401           if(0){     //Binary to Memory with Random
402             fFileHandler->Free();
403             fFileHandler->ResetRandom();
404             fFileHandler->SetRandomCluster(100);
405             fFileHandler->SetNGenerate(100);
406             if(fNPatch == 1)
407               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
408             else
409               sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
410             if(!memory->SetBinaryInput(name)) return;
411             UInt_t compsize=memory->GetFileSize();
412             UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
413             memory->CompBinary2CompMemory(ndigits,comp);
414             memory->CloseBinaryInput();
415             UInt_t dsize=memory->GetMemorySize(ndigits,comp);
416             UInt_t rsize=fFileHandler->GetRandomSize();       
417             digits=(AliHLTDigitRowData*)fFileHandler->Allocate(dsize+rsize);
418             fBenchmark->Start("Unpacker");
419             fFileHandler->CompMemory2Memory(ndigits,digits,comp); 
420             fBenchmark->Stop("Unpacker");
421             memory->Free();
422           }
423         }
424
425         else{     //Binary to Memory with Roi
426           fFileHandler->Free();
427           Int_t sli[2]={0,0};
428           fFileHandler->SetROI(fEta,sli);
429           if(fNPatch==1)
430             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
431           else
432             sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
433           if(!memory->SetBinaryInput(name)) return;
434           UInt_t compsize=memory->GetFileSize();
435           UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
436           memory->CompBinary2CompMemory(ndigits,comp);
437           memory->CloseBinaryInput();
438           UInt_t datasize=memory->GetMemorySize(ndigits,comp);
439           digits=(AliHLTDigitRowData *)fFileHandler->Allocate(datasize);
440           fBenchmark->Start("Unpacker"); 
441           datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp); 
442           fBenchmark->Stop("Unpacker"); 
443           memory->Free();
444         }
445       }//end UseBinary
446       else{
447 #ifdef use_aliroot
448         fBenchmark->Start("Dummy Unpacker");
449         if(fNPatch==1)
450           sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,-1);
451         else
452           sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,patch);
453         fBenchmark->Stop("Dummy Unpacker");
454
455         if(0){   //Ali to Binary
456           fFileHandler->SetBinaryOutput(name);
457           fFileHandler->AliDigits2CompBinary();
458           fFileHandler->CloseBinaryOutput();
459         }
460   
461         if(1){   //Ali to Memory
462           digits=(AliHLTDigitRowData *)fFileHandler->AliAltroDigits2Memory(ndigits,fEvent);
463           if(0){ //Memory to Binary
464             fFileHandler->SetBinaryOutput(name);
465             fFileHandler->Memory2CompBinary(ndigits,digits);
466             fFileHandler->CloseBinaryOutput();
467           }
468         }
469 #endif
470       }//end else UseBinary
471
472       points = (AliHLTSpacePointData *) memory->Allocate(kpointsize);
473       fClusterFinder = new AliHLTClustFinderNew();
474       fClusterFinder->InitSlice(slice,patch,fRow[patch][0],fRow[patch][1],kmaxpoints);
475       fClusterFinder->SetDeconv(fClusterDeconv);
476       fClusterFinder->SetXYError(fXYClusterError);
477       fClusterFinder->SetZError(fZClusterError);
478       if((fXYClusterError>0)&&(fZClusterError>0))
479         fClusterFinder->SetCalcErr(kFALSE);
480       fClusterFinder->SetOutputArray(points);
481       fBenchmark->Start("Cluster finder");
482       fClusterFinder->Read(ndigits,digits);
483       fClusterFinder->ProcessDigits();
484       fBenchmark->Stop("Cluster finder");
485       npoints = fClusterFinder->GetNumberOfClusters();
486       delete fClusterFinder;
487       fClusterFinder = 0;
488       fFileHandler->Free();
489       LOG(AliHLTLog::kInformational,"AliLevel3::ProcessSlice","Cluster Finder")
490         <<AliHLTLog::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
491     }//end UseCF
492     else{// if not use Clusterfinder
493       if(fUseBinary){//Binary to Memory
494         memory->Free();
495         if(fNPatch==1)
496           sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,-1);
497         else
498           sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,patch);
499         if(!memory->SetBinaryInput(name)) return;
500         points = (AliHLTSpacePointData *) memory->Allocate();
501         memory->Binary2Memory(npoints,points);
502         memory->CloseBinaryInput();
503         LOG(AliHLTLog::kInformational,"AliLevel3::ProcessSlice","Read Cluster")
504         <<AliHLTLog::kDec<<"Found "<<npoints<<" Points in File"<<ENDLOG;
505       }
506 #ifdef use_aliroot
507       else{
508         points = fFileHandler->AliPoints2Memory(npoints);
509       }
510 #endif
511       fBenchmark->Start("Dummy Unpacker");
512       fBenchmark->Stop("Dummy Unpacker");
513       fBenchmark->Start("Dummy CF");
514       fBenchmark->Stop("Dummy CF");
515     }
516    
517     if(patch == fNPatch-1){
518       // Vertex
519       if(fFindVertex){
520       // Vertex Finder
521       
522         fBenchmark->Start("Vertex Finder Read");
523         fVertexFinder->Reset();
524         fVertexFinder->Read(npoints,points);
525         fBenchmark->Stop("Vertex Finder Read"); 
526         fBenchmark->Start("Vertex Finder");
527         fVertexFinder->Analyze();
528         AliHLTVertexData vertex[1];
529         fVertexFinder->Write(vertex);
530         fVertex->Read(vertex);
531         fBenchmark->Stop("Vertex Finder"); 
532       }
533       else{
534         //use 0,0,0 for vertex
535         fVertex->SetZero();
536       }
537       fTrackMerger->SetVertex(fVertex);
538     }
539
540     fTracker->InitSector(slice,fRow[patch],fEta);
541     fTracker->SetVertex(fVertex);
542     fBenchmark->Start("Tracker setup"); 
543     fTracker->ReadHits(npoints,points);
544     fTracker->MainVertexTracking_a();
545     fBenchmark->Stop("Tracker setup");
546     fBenchmark->Start("Track follower");
547     fTracker->MainVertexTracking_b();
548     fBenchmark->Stop("Track follower");
549     if(fDoNonVertex)
550       fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
551     fBenchmark->Start("Sector track fitting");
552     fTracker->FillTracks();
553     fBenchmark->Stop("Sector track fitting");
554
555     if(fWriteOut) 
556        WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
557
558     //free memory
559     if(UseCF)
560       memory->Free();
561     else
562       fFileHandler->Free();
563
564     UInt_t ntracks0 =0;
565     AliHLTTrackSegmentData *trackdata0  = 
566          (AliHLTTrackSegmentData *) memory->Allocate(fTracker->GetTracks());
567     memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
568
569     //write tracks
570     if(fWriteOut){
571       if(fNPatch==1)
572         sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
573       else
574         sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
575       memory->SetBinaryOutput(name);
576       memory->Memory2Binary(ntracks0,trackdata0);
577       memory->CloseBinaryOutput();
578     }
579
580     fInterMerger->Reset();
581     fInterMerger->Init(fRow[patch],patch);
582
583     fInterMerger->FillTracks(ntracks0,trackdata0);
584     
585     //fBenchmark->Start("Inter Merger");
586     // fInterMerger->Merge();
587     //    fInterMerger->SlowMerge();
588     
589     //fBenchmark->Stop("Inter Merger");
590     /*
591     //write inter merged tracks
592     if(fWriteOut){
593       sprintf(name,"%stracks_im_%d_%d.raw",fWriteOutPath,slice,patch);
594       WriteTracks(name,fInterMerger,'i'); //write output of intermerger
595       }
596     */
597     memory->Free();
598     
599     UInt_t ntracks1 =0;
600     AliHLTTrackSegmentData *trackdata1 =
601       (AliHLTTrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
602     memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
603
604     fTrackMerger->InitSector(slice,patch);
605     fTrackMerger->FillTracks(ntracks1,trackdata1);
606
607     memory->Free();
608   }
609   //fBenchmark->Start("Patch Merger");
610   //fTrackMerger->SlowMerge();
611   fTrackMerger->AddAllTracks();
612   //fTrackMerger->Merge();
613   //fBenchmark->Stop("Patch Merger");
614   /*
615   //write merged tracks
616   if(fWriteOut){
617     sprintf(name,"%stracks_tm_%d.raw",fWriteOutPath,slice);
618     WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
619   }
620   */
621   fTrackData = (AliHLTTrackSegmentData *) 
622                          fFileHandler->Allocate(fTrackMerger->GetOutTracks());
623
624   fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
625                                                 fTrackMerger->GetOutTracks());
626
627   delete memory;
628 }
629
630 void AliLevel3::FitGlobalTracks()
631
632   //fit global tracks
633   AliHLTFitter *fitter = new AliHLTFitter(fVertex,AliLevel3::DoVertexFit());
634   if(fNPatch==1)
635     fitter->LoadClusters(fWriteOutPath,fEvent,kTRUE);
636   else
637     fitter->LoadClusters(fWriteOutPath,fEvent,kFALSE);
638   
639   fBenchmark->Start("Global track fitter");
640   AliHLTTrackArray *tracks = fGlobalMerger->GetOutTracks();
641   for(Int_t i=0; i<tracks->GetNTracks(); i++)
642     {
643       AliHLTTrack *tr = tracks->GetCheckedTrack(i);
644       if(!tr) continue;
645       fitter->FitHelix(tr);
646       tr->UpdateToFirstPoint();
647     }
648   fBenchmark->Stop("Global track fitter");
649   delete fitter;
650 }
651
652 void AliLevel3::WriteSpacePoints(UInt_t npoints,AliHLTSpacePointData *points,
653                                  Int_t slice,Int_t patch) const
654
655   //write space points
656   char name[256];
657   if(fNPatch==1)
658     sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
659   else
660     sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
661   AliHLTMemHandler * memory = new AliHLTMemHandler();
662   memory->SetBinaryOutput(name);
663   memory->Transform(npoints,points,slice);
664   memory->Memory2Binary(npoints,points);
665   memory->CloseBinaryOutput();
666   delete  memory;
667 }
668
669 Int_t AliLevel3::WriteTracks(char *filename,AliHLTMerger *merger,char opt) const
670
671   //write tracks
672   AliHLTMemHandler *memory = new AliHLTMemHandler();
673   memory->SetBinaryOutput(filename);
674   if(opt=='a'||opt=='i'){  //add intracks
675     for(Int_t i=0;i<merger->GetNIn();i++){
676       AliHLTTrackArray *tr=merger->GetInTracks(i);
677       memory->TrackArray2Binary(tr);
678     }
679   }
680
681   if(opt=='o'||opt=='a'){
682     AliHLTTrackArray *tr=merger->GetOutTracks();
683     memory->TrackArray2Binary(tr);
684   }
685
686   memory->CloseBinaryOutput();
687   delete memory;
688   return 1;
689 }
690
691 void AliLevel3::WriteResults()
692 {
693   //Write the resulting tracks to outputfile
694   Char_t fname[256];
695   sprintf(fname,"%s/tracks_%d.raw",fWriteOutPath,fEvent);
696   WriteTracks(fname,fGlobalMerger,'a');
697   //WriteTracks("tracks.raw",fGlobalMerger,'a');
698   sprintf(fname,"%s/tracks_gl_%d.raw",fWriteOutPath,fEvent);
699   WriteTracks(fname,fGlobalMerger,'o');
700   //WriteTracks("tracks_gl.raw",fGlobalMerger,'o');
701 }