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