3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliHLTTPCStandardIncludes.h"
10 #include <TDirectory.h>
11 #include <TClonesArray.h>
12 #include <TStopwatch.h>
16 #include <AliRunLoader.h>
19 #include "AliHLTTPCLogging.h"
20 #include "AliHLTTPC.h"
21 #include "AliHLTTPCConfMapper.h"
22 #include "AliHLTTPCVertex.h"
23 #include "AliHLTTPCVertexFinder.h"
24 #include "AliHLTTPCTrackMerger.h"
25 #include "AliHLTTPCGlobalMerger.h"
26 #include "AliHLTTPCInterMerger.h"
27 #include "AliHLTTPCConfMapPoint.h"
28 #include "AliHLTTPCConfMapTrack.h"
29 #include "AliHLTTPCTransform.h"
30 #include "AliHLTTPCClusterFinder.h"
31 #include "AliHLTTPCDigitReaderUnpacked.h"
32 #include "AliHLTTPCDigitData.h"
33 #include "AliHLTTPCTrackArray.h"
34 #include "AliHLTTPCMemHandler.h"
35 #include "AliHLTTPCFitter.h"
37 #include "AliHLTTPCFileHandler.h"
39 #include "AliHLTTPCBenchmark.h"
40 #include "AliHLTTPCDigitData.h"
41 #include "AliHLTTPCTrackSegmentData.h"
42 #include "AliHLTTPCSpacePointData.h"
43 #include "AliHLTTPCVertexData.h"
44 #include "AliHLTTPCDDLDataFileHandler.h"
48 //_____________________________________________________________
52 // Interface class for HLTTPC tracker.
53 // For example how to use, see exa/runtracker.C (root)
54 // or programs/runtracker.cxx (standalone program).
56 //<img src="tpcsectorsnb.gif">
63 Bool_t AliHLTTPC::fgDoVertexFit = kTRUE;//Include the vertex in the final track fit
65 AliHLTTPC::AliHLTTPC()
67 //Default constructor. Should also be used when input is from binary files.
68 //In that case the path to where the binary files are located has to be
69 //passed to the AliLevel::Init function.
84 AliHLTTPC::AliHLTTPC(Char_t *infile)
86 //Constructor to use for when input is anything else but binary files,
87 //meaning rootfiles or raw files.
103 AliHLTTPC::AliHLTTPC(AliRunLoader *rl)
105 //Constructor to use when input is aliroot runloader
118 void AliHLTTPC::Init(Char_t *path,EFileType filetype,Int_t npatches)
120 //Init the whole standard tracker chain
122 if (filetype==kRunLoader){
123 LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
124 <<"You have not supplied the input rootfile; if you want "
125 <<"to run with RunLoader use -Duse_newio for compiling!"<<ENDLOG;
129 if((filetype!=kBinary) && (filetype!=kDate)
130 && (filetype!=kRunLoader)&& !fInputFile)
132 LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
133 <<"You have not supplied the input rootfile; use the appropriate ctor!"<<ENDLOG;
137 if((filetype==kRunLoader) && !fRunLoader)
139 LOG(AliHLTTPCLog::kError,"AliHLTTPC::Init","Files")
140 <<"You have not supplied the input runloader; use the appropriate ctor!"<<ENDLOG;
148 fUseBinary = (filetype==kBinary);
152 fDoNonVertex = kFALSE;
153 fFindVertex = kFALSE;
154 SetClusterFinderParam();
160 #ifdef use_aliroot /*just to be sure*/
161 AliHLTTPCFileHandler::CleanStaticIndex();
167 fRow[0][0] = AliHLTTPCTransform::GetFirstRow(3);
168 fRow[0][1] = AliHLTTPCTransform::GetLastRow(5);
171 fNPatch = 1; //number of patches change row in process
173 fRow[0][1] = AliHLTTPCTransform::GetLastRow(-1);
176 fNPatch = 2; //number of patches change row in process
177 fRow[0][0] = 0; // first row
178 fRow[0][1] = AliHLTTPCTransform::GetLastRow(1);
179 fRow[1][0] = AliHLTTPCTransform::GetFirstRow(2);
180 fRow[1][1] = AliHLTTPCTransform::GetLastRow(5);
184 fRow[0][0] = AliHLTTPCTransform::GetFirstRow(0);
185 fRow[0][1] = AliHLTTPCTransform::GetLastRow(0);
186 fRow[1][0] = AliHLTTPCTransform::GetFirstRow(1);
187 fRow[1][1] = AliHLTTPCTransform::GetLastRow(1);
188 fRow[2][0] = AliHLTTPCTransform::GetFirstRow(2);
189 fRow[2][1] = AliHLTTPCTransform::GetLastRow(2);
190 fRow[3][0] = AliHLTTPCTransform::GetFirstRow(3);
191 fRow[3][1] = AliHLTTPCTransform::GetLastRow(3);
192 fRow[4][0] = AliHLTTPCTransform::GetFirstRow(4);
193 fRow[4][1] = AliHLTTPCTransform::GetLastRow(4);
194 fRow[5][0] = AliHLTTPCTransform::GetFirstRow(5);
195 fRow[5][1] = AliHLTTPCTransform::GetLastRow(5);
198 fVertexFinder = new AliHLTTPCVertexFinder();
199 fVertex = new AliHLTTPCVertex();
200 fTracker = new AliHLTTPCConfMapper();
201 fTrackMerger = new AliHLTTPCTrackMerger(fNPatch);
202 fInterMerger = new AliHLTTPCInterMerger();
203 fGlobalMerger = new AliHLTTPCGlobalMerger();
204 SetMergerParameters();//Set default merger parameters
207 fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
208 fFileHandler->SetAliInput(fInputFile);
209 }else if(filetype==kRaw){
210 fFileHandler = new AliHLTTPCDDLDataFileHandler();
211 fFileHandler->SetReaderInput(fInputFile);
212 }else if(filetype==kDate){
213 fFileHandler = new AliHLTTPCDDLDataFileHandler();
214 fFileHandler->SetReaderInput(fInputFile,-1);
217 else if(filetype==kRunLoader){
218 fFileHandler = new AliHLTTPCFileHandler(kTRUE); //static version
219 fFileHandler->SetAliInput(fRunLoader);
223 fFileHandler = new AliHLTTPCMemHandler();
227 fFileHandler = new AliHLTTPCDDLDataFileHandler();
228 fFileHandler->SetReaderInput(fInputFile);
230 fFileHandler = new AliHLTTPCMemHandler();
233 fBenchmark = new AliHLTTPCBenchmark();
236 void AliHLTTPC::DoBench(char* name)
239 fBenchmark->Analyze(name);
241 fBenchmark = new AliHLTTPCBenchmark();
244 void AliHLTTPC::DoMc(char* file)
248 if(!fFileHandler->IsDigit(fEvent))
249 fFileHandler->SetMCOutput(file);
253 AliHLTTPC::~AliHLTTPC()
256 if(fVertexFinder) delete fVertexFinder;
257 if(fVertex) delete fVertex;
258 if(fTracker) delete fTracker;
259 if(fTrackMerger) delete fTrackMerger;
260 if(fInterMerger) delete fInterMerger;
261 if(fFileHandler) delete fFileHandler;
262 if(fGlobalMerger) delete fGlobalMerger;
265 void AliHLTTPC::SetClusterFinderParam(Float_t fXYError, Float_t fZError, Bool_t deconv)
267 //set cluster finder parameter
268 fXYClusterError=fXYError;
269 fZClusterError=fZError;
270 fClusterDeconv=deconv;
273 void AliHLTTPC::SetTrackerParam(Int_t phi_segments, Int_t eta_segments,
274 Int_t trackletlength, Int_t tracklength,
275 Int_t rowscopetracklet, Int_t rowscopetrack,
276 Double_t min_pt_fit, Double_t maxangle,
277 Double_t goodDist, Double_t hitChi2Cut,
278 Double_t goodHitChi2, Double_t trackChi2Cut,
279 Int_t maxdist,Double_t maxphi,Double_t maxeta,
280 Bool_t vertexconstraint)
282 //Set parameters input to the tracker
283 //If no arguments are given, default parameters will be used
285 fTracker->SetNSegments(phi_segments,eta_segments);
286 fTracker->SetMaxDca(min_pt_fit);
287 fTracker->SetTrackCuts(hitChi2Cut,goodHitChi2,trackChi2Cut,maxdist,vertexconstraint);
288 fTracker->SetTrackletCuts(maxangle,goodDist,vertexconstraint);
290 fTracker->MainVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack,maxphi,maxeta);
292 fTracker->NonVertexSettings(trackletlength,tracklength,rowscopetracklet,rowscopetrack);
293 fTracker->InitVolumes();
296 void AliHLTTPC::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
298 //set global merger parameter
299 fGlobalMerger->SetParameter(maxy,maxz,maxkappa,maxpsi,maxtgl);
302 void AliHLTTPC::ProcessEvent(Int_t first,Int_t last,Int_t event)
304 //Do tracking on all slices in region [first,last]
305 //Slices numbering in TPC goes from 0-35, which means that one slice
306 //corresponds to inner+outer sector.E.g. slice 2 corresponds to
307 //inner=2 + outer=38.
309 fGlobalMerger->Setup(first,last);
311 if(fEvent!=event) AliHLTTPCFileHandler::CleanStaticIndex();
314 for(Int_t i=first; i<=last; i++){
316 fGlobalMerger->SetVertex(fVertex);
317 fGlobalMerger->InitSlice(i);
318 fGlobalMerger->FillTracks(fNTrackData,fTrackData);
319 fFileHandler->Free(); //free the memory
323 fBenchmark->Start("Global track merger");
324 //fGlobalMerger->AddAllTracks();
325 fGlobalMerger->Merge();
326 //fGlobalMerger->SlowMerge(fWriteOutPath);
327 fBenchmark->Stop("Global track merger");
331 if(fWriteOut) WriteResults();
332 fFileHandler->FreeDigitsTree();
335 void AliHLTTPC::ProcessSlice(Int_t slice)
339 Bool_t UseCF = kFALSE;
341 UseCF = fFileHandler->IsDigit(fEvent);
344 UseCF = kTRUE; //In case you are not using aliroot
345 if(fNoCF == kTRUE) //In case you don't want to run with cluster finder
348 const Int_t kmaxpoints=120000;
349 const Int_t kpointsize = kmaxpoints * sizeof(AliHLTTPCSpacePointData);
350 AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
352 fTrackMerger->Reset();
353 fTrackMerger->SetRows(fRow[0]);
355 for(Int_t patch=fNPatch-1;patch>=0;patch--){
356 fFileHandler->Init(slice,patch,&fRow[patch][0]);
358 AliHLTTPCSpacePointData *points =0;
360 AliHLTTPCDigitRowData *digits =0;
361 UInt_t digitSize = 0;
365 if(1){ //Binary to Memory
366 fFileHandler->Free();
368 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
370 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
371 if(!fFileHandler->SetBinaryInput(name)) return;
373 { //Read binary files which are not RLE
374 digits = (AliHLTTPCDigitRowData*)fFileHandler->Allocate();
375 fFileHandler->Binary2Memory(ndigits,digits, digitSize );
376 digitSize = fFileHandler->GetFileSize();
378 else //Read RLE binary files
380 digits= (AliHLTTPCDigitRowData *)fFileHandler->CompBinary2Memory(ndigits, digitSize);
383 fFileHandler->CloseBinaryInput();
386 if(0){ //Binary to Memory with Benchmark
387 fFileHandler->Free();
389 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
391 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
392 if(!memory->SetBinaryInput(name)) return;
393 UInt_t compsize=memory->GetFileSize();
394 UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
395 memory->CompBinary2CompMemory(ndigits,comp);
396 memory->CloseBinaryInput();
397 UInt_t datasize=memory->GetMemorySize(ndigits,comp);
398 digits=(AliHLTTPCDigitRowData *)fFileHandler->Allocate(datasize);
399 fBenchmark->Start("Unpacker");
400 fFileHandler->CompMemory2Memory(ndigits,digits,comp,digitSize);
401 fBenchmark->Stop("Unpacker");
405 if(0){ //Binary to Memory with Random
406 fFileHandler->Free();
407 fFileHandler->ResetRandom();
408 fFileHandler->SetRandomCluster(100);
409 fFileHandler->SetNGenerate(100);
411 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
413 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
414 if(!memory->SetBinaryInput(name)) return;
415 UInt_t compsize=memory->GetFileSize();
416 UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
417 memory->CompBinary2CompMemory(ndigits,comp);
418 memory->CloseBinaryInput();
419 UInt_t dsize=memory->GetMemorySize(ndigits,comp);
420 UInt_t rsize=fFileHandler->GetRandomSize();
421 digits=(AliHLTTPCDigitRowData*)fFileHandler->Allocate(dsize+rsize);
422 fBenchmark->Start("Unpacker");
423 fFileHandler->CompMemory2Memory(ndigits,digits,comp,digitSize);
424 fBenchmark->Stop("Unpacker");
429 else{ //Binary to Memory with Roi
430 fFileHandler->Free();
432 fFileHandler->SetROI(fEta,sli);
434 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,-1);
436 sprintf(name,"%sdigits_%d_%d_%d.raw",fPath,fEvent,slice,patch);
437 if(!memory->SetBinaryInput(name)) return;
438 UInt_t compsize=memory->GetFileSize();
439 UInt_t *comp=(UInt_t *)memory->Allocate(compsize);
440 memory->CompBinary2CompMemory(ndigits,comp);
441 memory->CloseBinaryInput();
442 UInt_t datasize=memory->GetMemorySize(ndigits,comp);
443 digits=(AliHLTTPCDigitRowData *)fFileHandler->Allocate(datasize);
444 fBenchmark->Start("Unpacker");
445 datasize = fFileHandler->CompMemory2Memory(ndigits,digits,comp,digitSize);
446 fBenchmark->Stop("Unpacker");
452 fBenchmark->Start("Dummy Unpacker");
454 sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,-1);
456 sprintf(name,"digits_%d_%d_%d.raw",fEvent,slice,patch);
457 fBenchmark->Stop("Dummy Unpacker");
459 if(0){ //Ali to Binary
460 fFileHandler->SetBinaryOutput(name);
461 fFileHandler->AliDigits2CompBinary();
462 fFileHandler->CloseBinaryOutput();
465 if(1){ //Ali to Memory
466 digits=(AliHLTTPCDigitRowData *)fFileHandler->AliAltroDigits2Memory(ndigits,fEvent);
467 if(0){ //Memory to Binary
468 fFileHandler->SetBinaryOutput(name);
469 fFileHandler->Memory2CompBinary(ndigits,digits);
470 fFileHandler->CloseBinaryOutput();
474 }//end else UseBinary
476 points = (AliHLTTPCSpacePointData *) memory->Allocate(kpointsize);
477 fClusterFinder = new AliHLTTPCClusterFinder();
478 fDigitReader = new AliHLTTPCDigitReaderUnpacked();
479 fClusterFinder->InitSlice(slice,patch,fRow[patch][0],fRow[patch][1],kmaxpoints);
480 fClusterFinder->SetDeconv(fClusterDeconv);
481 fClusterFinder->SetXYError(fXYClusterError);
482 fClusterFinder->SetZError(fZClusterError);
483 if((fXYClusterError>0)&&(fZClusterError>0))
484 fClusterFinder->SetCalcErr(kFALSE);
485 fClusterFinder->SetOutputArray(points);
486 fClusterFinder->SetReader( fDigitReader );
487 fBenchmark->Start("Cluster finder");
488 //fClusterFinder->Read(ndigits,digits);
489 fClusterFinder->Read( (void*)digits, (unsigned long) digitSize );
490 fClusterFinder->ProcessDigits();
491 fBenchmark->Stop("Cluster finder");
492 npoints = fClusterFinder->GetNumberOfClusters();
493 delete fClusterFinder;
495 fFileHandler->Free();
496 LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Cluster Finder")
497 <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points"<<ENDLOG;
499 else{// if not use Clusterfinder
500 if(fUseBinary){//Binary to Memory
503 sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,-1);
505 sprintf(name,"%s/points_%d_%d_%d.raw",fPath,fEvent,slice,patch);
506 if(!memory->SetBinaryInput(name)) return;
507 points = (AliHLTTPCSpacePointData *) memory->Allocate();
508 memory->Binary2Memory(npoints,points);
509 memory->CloseBinaryInput();
510 LOG(AliHLTTPCLog::kInformational,"AliHLTTPC::ProcessSlice","Read Cluster")
511 <<AliHLTTPCLog::kDec<<"Found "<<npoints<<" Points in File"<<ENDLOG;
515 points = fFileHandler->AliPoints2Memory(npoints);
518 fBenchmark->Start("Dummy Unpacker");
519 fBenchmark->Stop("Dummy Unpacker");
520 fBenchmark->Start("Dummy CF");
521 fBenchmark->Stop("Dummy CF");
524 if(patch == fNPatch-1){
529 fBenchmark->Start("Vertex Finder Read");
530 fVertexFinder->Reset();
531 fVertexFinder->Read(npoints,points);
532 fBenchmark->Stop("Vertex Finder Read");
533 fBenchmark->Start("Vertex Finder");
534 fVertexFinder->Analyze();
535 AliHLTTPCVertexData vertex[1];
536 fVertexFinder->Write(vertex);
537 fVertex->Read(vertex);
538 fBenchmark->Stop("Vertex Finder");
541 //use 0,0,0 for vertex
544 fTrackMerger->SetVertex(fVertex);
547 fTracker->InitSector(slice,fRow[patch],fEta);
548 fTracker->SetVertex(fVertex);
549 fBenchmark->Start("Tracker setup");
550 fTracker->ReadHits(npoints,points);
551 fTracker->MainVertexTracking_a();
552 fBenchmark->Stop("Tracker setup");
553 fBenchmark->Start("Track follower");
554 fTracker->MainVertexTracking_b();
555 fBenchmark->Stop("Track follower");
557 fTracker->NonVertexTracking();//Do a second pass for nonvertex tracks
558 fBenchmark->Start("Sector track fitting");
559 fTracker->FillTracks();
560 fBenchmark->Stop("Sector track fitting");
563 WriteSpacePoints(npoints, points, slice, patch); //do after Tracking
569 fFileHandler->Free();
572 AliHLTTPCTrackSegmentData *trackdata0 =
573 (AliHLTTPCTrackSegmentData *) memory->Allocate(fTracker->GetTracks());
574 memory->TrackArray2Memory(ntracks0,trackdata0,fTracker->GetTracks());
579 sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
581 sprintf(name,"%s/tracks_tr_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
582 memory->SetBinaryOutput(name);
583 memory->Memory2Binary(ntracks0,trackdata0);
584 memory->CloseBinaryOutput();
587 fInterMerger->Reset();
588 fInterMerger->Init(fRow[patch],patch);
590 fInterMerger->FillTracks(ntracks0,trackdata0);
592 //fBenchmark->Start("Inter Merger");
593 // fInterMerger->Merge();
594 // fInterMerger->SlowMerge();
596 //fBenchmark->Stop("Inter Merger");
598 //write inter merged tracks
600 sprintf(name,"%stracks_im_%d_%d.raw",fWriteOutPath,slice,patch);
601 WriteTracks(name,fInterMerger,'i'); //write output of intermerger
607 AliHLTTPCTrackSegmentData *trackdata1 =
608 (AliHLTTPCTrackSegmentData *) memory->Allocate(fInterMerger->GetInTracks(0));
609 memory->TrackArray2Memory(ntracks1,trackdata1,fInterMerger->GetInTracks(0));
611 fTrackMerger->InitSector(slice,patch);
612 fTrackMerger->FillTracks(ntracks1,trackdata1);
616 //fBenchmark->Start("Patch Merger");
617 //fTrackMerger->SlowMerge();
618 fTrackMerger->AddAllTracks();
619 //fTrackMerger->Merge();
620 //fBenchmark->Stop("Patch Merger");
622 //write merged tracks
624 sprintf(name,"%stracks_tm_%d.raw",fWriteOutPath,slice);
625 WriteTracks(name,fTrackMerger,'o'); //write output of trackmerger
628 fTrackData = (AliHLTTPCTrackSegmentData *)
629 fFileHandler->Allocate(fTrackMerger->GetOutTracks());
631 fFileHandler->TrackArray2Memory(fNTrackData,fTrackData,
632 fTrackMerger->GetOutTracks());
637 void AliHLTTPC::FitGlobalTracks()
640 AliHLTTPCFitter *fitter = new AliHLTTPCFitter(fVertex,AliHLTTPC::DoVertexFit());
642 fitter->LoadClusters(fWriteOutPath,fEvent,kTRUE);
644 fitter->LoadClusters(fWriteOutPath,fEvent,kFALSE);
646 fBenchmark->Start("Global track fitter");
647 AliHLTTPCTrackArray *tracks = fGlobalMerger->GetOutTracks();
648 for(Int_t i=0; i<tracks->GetNTracks(); i++)
650 AliHLTTPCTrack *tr = tracks->GetCheckedTrack(i);
652 fitter->FitHelix(tr);
653 tr->UpdateToFirstPoint();
655 fBenchmark->Stop("Global track fitter");
659 void AliHLTTPC::WriteSpacePoints(UInt_t npoints,AliHLTTPCSpacePointData *points,
660 Int_t slice,Int_t patch) const
665 sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,-1);
667 sprintf(name,"%s/points_%d_%d_%d.raw",fWriteOutPath,fEvent,slice,patch);
668 AliHLTTPCMemHandler * memory = new AliHLTTPCMemHandler();
669 memory->SetBinaryOutput(name);
670 memory->Transform(npoints,points,slice);
671 memory->Memory2Binary(npoints,points);
672 memory->CloseBinaryOutput();
676 Int_t AliHLTTPC::WriteTracks(char *filename,AliHLTTPCMerger *merger,char opt) const
679 AliHLTTPCMemHandler *memory = new AliHLTTPCMemHandler();
680 memory->SetBinaryOutput(filename);
681 if(opt=='a'||opt=='i'){ //add intracks
682 for(Int_t i=0;i<merger->GetNIn();i++){
683 AliHLTTPCTrackArray *tr=merger->GetInTracks(i);
684 memory->TrackArray2Binary(tr);
688 if(opt=='o'||opt=='a'){
689 AliHLTTPCTrackArray *tr=merger->GetOutTracks();
690 memory->TrackArray2Binary(tr);
693 memory->CloseBinaryOutput();
698 void AliHLTTPC::WriteResults()
700 //Write the resulting tracks to outputfile
702 sprintf(fname,"%s/tracks_%d.raw",fWriteOutPath,fEvent);
703 WriteTracks(fname,fGlobalMerger,'a');
704 //WriteTracks("tracks.raw",fGlobalMerger,'a');
705 sprintf(fname,"%s/tracks_gl_%d.raw",fWriteOutPath,fEvent);
706 WriteTracks(fname,fGlobalMerger,'o');
707 //WriteTracks("tracks_gl.raw",fGlobalMerger,'o');