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