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