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