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