7bf15bebf075b005cc1bd3d1b2e9c5ef4d6f8117
[u/mrichter/AliRoot.git] / MUON / AliMUONReconstructor.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 /* $Id$ */
16
17 //-----------------------------
18 // Class AliMUONReconstructor  
19 //-----------------------------
20 // Class for the 
21 // MUON track reconstruction
22
23 #include "AliMUONReconstructor.h"
24
25 #include "AliMUONConstants.h"
26 #include "AliMUONCalibrationData.h"
27 #include "AliMUONClusterFinderAZ.h"
28 #include "AliMUONClusterReconstructor.h"
29 #include "AliMUONData.h"
30 #include "AliMUONDigitCalibrator.h"
31 #include "AliMUONEventRecoCombi.h" 
32 #include "AliMUONDigitMaker.h"
33 #include "AliMUONTrack.h"
34 #include "AliMUONTrackParam.h"
35 #include "AliMUONTrackExtrap.h"
36 #include "AliMUONTracker.h"
37 #include "AliMUONVTrackReconstructor.h"
38 #include "AliMUONTrackReconstructor.h"
39 #include "AliMUONTrackReconstructorK.h"
40 #include "AliMUONTriggerTrack.h"
41 #include "AliMUONTriggerCircuit.h"
42 #include "AliMUONTriggerCrateStore.h"
43 #include "AliMUONSegFactory.h"
44 #include "AliMUONSegmentation.h"
45 #include "AliMUONPreClusterFinder.h"
46 #include "AliMUONClusterFinderCOG.h"
47 #include "AliMUONClusterFinderSimpleFit.h"
48 #include "AliMUONClusterFinderMLEM.h"
49
50 #include "AliESD.h"
51 #include "AliESDMuonTrack.h"
52 #include "AliLog.h"
53 #include "AliRawReader.h"
54 #include "AliRunLoader.h"
55 #include "AliCDBManager.h"
56
57 #include "TTask.h"
58 #include "TStopwatch.h"
59
60 /// \cond CLASSIMP
61 ClassImp(AliMUONReconstructor)
62 /// \endcond
63
64 //_____________________________________________________________________________
65 AliMUONReconstructor::AliMUONReconstructor()
66   : AliReconstructor(), 
67     fDigitMaker(new AliMUONDigitMaker()), 
68     fCalibrationData(0x0),
69     fCrateManager(new AliMUONTriggerCrateStore()),
70     fTriggerCircuit(new TClonesArray("AliMUONTriggerCircuit", 234)),
71     fTransformer(new AliMUONGeometryTransformer(kTRUE)),
72     fSegmentation(0x0),
73     fMUONData(new AliMUONData(0x0,"MUON","MUON"))
74 {
75 /// Default constructor
76
77     AliDebug(1,"");
78     // Crate manager
79     fCrateManager->ReadFromFile();
80
81     // set to digit maker
82     fDigitMaker->SetCrateManager(fCrateManager);
83
84     // transformater
85     fTransformer->ReadGeometryData("volpath.dat", "geometry.root");
86     
87     // create segmentation and pass it to EventRecoCombi
88     AliMUONSegFactory factory(fTransformer);
89     fSegmentation = factory.CreateSegmentation();
90     AliMUONEventRecoCombi::Instance(fSegmentation); 
91
92     // trigger circuit
93     for (Int_t i = 0; i < AliMUONConstants::NTriggerCircuit(); i++)  {
94       AliMUONTriggerCircuit* c = new AliMUONTriggerCircuit();
95       c->SetTransformer(fTransformer);
96       c->Init(i,*fCrateManager);
97       TClonesArray& circuit = *fTriggerCircuit;
98       new(circuit[circuit.GetEntriesFast()])AliMUONTriggerCircuit(*c);
99       delete c;
100     }
101
102   
103 }
104
105 //_____________________________________________________________________________
106 AliMUONReconstructor::~AliMUONReconstructor()
107 {
108 /// Destructor
109
110   AliDebug(1,"");
111   delete fCalibrationData;
112   delete fDigitMaker;
113   delete fCrateManager;
114   delete fTriggerCircuit;
115   delete fTransformer;
116   delete fSegmentation;
117   delete fMUONData;
118 }
119
120 //_____________________________________________________________________________
121 TTask* 
122 AliMUONReconstructor::GetCalibrationTask() const
123 {
124 /// Create the calibration task(s). 
125   
126   //const AliRun* run = fRunLoader->GetAliRun();
127   //Int_t runNumber = run->GetRunNumber();     
128   Int_t runNumber = AliCDBManager::Instance()->GetRun();
129   AliInfo("Calibration will occur.");
130  
131   fCalibrationData = new AliMUONCalibrationData(runNumber);
132   if ( !fCalibrationData->IsValid() )
133     {
134       AliError("Could not retrieve calibrations !");
135       delete fCalibrationData;
136       fCalibrationData = 0x0;
137       return 0x0;
138     }    
139   // Check that we get all the calibrations we'll need
140   if ( !fCalibrationData->Pedestals() ||
141        !fCalibrationData->Gains() ||
142        !fCalibrationData->HV() )
143   {
144     AliFatal("Could not access all required calibration data");
145   }
146   TTask* calibration = new TTask("MUONCalibrator","MUON Digit calibrator");
147   
148   TString opt(GetOption());
149   opt.ToUpper();
150   Bool_t statusMap(kTRUE);
151   
152   if ( strstr(opt,"NOSTATUSMAP") )
153   {
154     AliWarning("Disconnecting status map : SHOULD BE USED FOR DEBUG ONLY. NOT FOR PRODUCTION !!!");
155     statusMap = kFALSE; 
156   }
157   calibration->Add(new AliMUONDigitCalibrator(fMUONData,fCalibrationData,statusMap));
158   return calibration;
159 }
160
161 //_____________________________________________________________________________
162 AliMUONClusterReconstructor*
163 AliMUONReconstructor::CreateClusterReconstructor() const
164 {
165 /// Create cluster reconstructor
166
167   AliMUONVClusterFinder* clusterFinder(0x0);
168   
169   TString opt(GetOption());
170   opt.ToUpper();
171   
172   if ( strstr(opt,"PRECLUSTER") )
173   {
174     clusterFinder = new AliMUONPreClusterFinder;
175   }  
176   else if ( strstr(opt,"COG") )
177   {
178     clusterFinder = new AliMUONClusterFinderCOG;
179   }  
180   else if ( strstr(opt,"SIMPLEFIT") )
181   {
182     clusterFinder = new AliMUONClusterFinderSimpleFit;
183   }
184   else if ( strstr(opt,"MLEM:DRAW") )
185   {
186     clusterFinder = new AliMUONClusterFinderMLEM(kTRUE);
187   }
188   else if ( strstr(opt,"MLEM") )
189   {
190     clusterFinder = new AliMUONClusterFinderMLEM(kFALSE);
191   } 
192   
193   if ( clusterFinder) 
194   {
195     AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
196   }
197   
198   AliMUONClusterReconstructor* clusterReco = 
199     new AliMUONClusterReconstructor(fMUONData,clusterFinder,fTransformer);
200   return clusterReco;
201 }
202
203 //_____________________________________________________________________________
204 void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const
205 {
206 /// Reconstruct
207 /// \todo add more
208
209   AliLoader* loader = runLoader->GetLoader("MUONLoader");
210   Int_t nEvents     = runLoader->GetNumberOfEvents();
211   Int_t evtNumber   = runLoader->GetEventNumber();
212
213   fMUONData->SetLoader(loader);
214
215 // passing loader as argument.
216   AliMUONVTrackReconstructor* recoEvent;
217   if (strstr(GetOption(),"Original")) recoEvent = new AliMUONTrackReconstructor(fMUONData);
218   else if (strstr(GetOption(),"Combi")) recoEvent = new AliMUONTrackReconstructorK(fMUONData,"Combi");
219   else recoEvent = new AliMUONTrackReconstructorK(fMUONData,"Kalman");
220   
221   recoEvent->SetTriggerCircuit(fTriggerCircuit);
222
223   AliMUONClusterReconstructor* recoCluster = CreateClusterReconstructor();
224   
225   AliMUONClusterFinderVS *recModel = recoCluster->GetRecoModel();
226
227   if (!strstr(GetOption(),"VS")) {
228     recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ();
229     recoCluster->SetRecoModel(recModel);
230   }
231   recModel->SetGhostChi2Cut(10);
232   recModel->SetEventNumber(evtNumber);
233
234   loader->LoadDigits("READ");
235   loader->LoadRecPoints("RECREATE");
236   loader->LoadTracks("RECREATE");
237   
238   TTask* calibration = GetCalibrationTask();
239   
240   Int_t chBeg = (strstr(GetOption(),"Combi") ? 6 : 0);
241
242   //   Loop over events              
243   for(Int_t ievent = 0; ievent < nEvents; ievent++) {
244
245     AliDebug(1,Form("Event %d",ievent));
246     
247     runLoader->GetEvent(ievent);
248
249     //----------------------- digit2cluster & Trigger2Trigger -------------------
250     if (!loader->TreeR()) loader->MakeRecPointsContainer();
251      
252     // tracking branch
253     if (!strstr(GetOption(),"Combi")) {
254       fMUONData->MakeBranch("RC");
255       fMUONData->SetTreeAddress("D,RC");
256     } else {
257       fMUONData->SetTreeAddress("D");
258       fMUONData->SetTreeAddress("RCC");
259     }
260     // Important for avoiding a memory leak when reading digits ( to be investigated more in detail)
261     // In any case the reading of GLT is needed for the Trigger2Tigger method below
262     fMUONData->SetTreeAddress("GLT");
263
264     fMUONData->GetDigits();
265     
266     if ( calibration ) 
267     {
268       calibration->ExecuteTask();
269     }
270     
271     recoCluster->Digits2Clusters(chBeg); 
272     
273     if (strstr(GetOption(),"Combi")) {
274       // Combined cluster / track finder
275       AliMUONEventRecoCombi::Instance()->FillEvent(fMUONData, (AliMUONClusterFinderAZ*)recModel);
276       ((AliMUONClusterFinderAZ*) recModel)->SetReco(2); 
277     }
278     else fMUONData->Fill("RC"); 
279
280     // trigger branch
281     fMUONData->MakeBranch("TC");
282     fMUONData->SetTreeAddress("TC");
283     recoCluster->Trigger2Trigger(); 
284     fMUONData->Fill("TC");
285
286     //AZ loader->WriteRecPoints("OVERWRITE");
287
288     //---------------------------- Track & TriggerTrack ---------------------
289     if (!loader->TreeT()) loader->MakeTracksContainer();
290
291     // trigger branch
292     fMUONData->MakeBranch("RL"); //trigger track
293     fMUONData->SetTreeAddress("RL");
294     recoEvent->EventReconstructTrigger();
295     fMUONData->Fill("RL");
296
297     // tracking branch
298     fMUONData->MakeBranch("RT"); //track
299     fMUONData->SetTreeAddress("RT");
300     recoEvent->EventReconstruct();
301     fMUONData->Fill("RT");
302
303     loader->WriteTracks("OVERWRITE"); 
304   
305     if (strstr(GetOption(),"Combi")) { 
306       // Combined cluster / track
307       ((AliMUONClusterFinderAZ*) recModel)->SetReco(1);
308       fMUONData->MakeBranch("RC");
309       fMUONData->SetTreeAddress("RC");
310       AliMUONEventRecoCombi::Instance()->FillRecP(fMUONData, (AliMUONTrackReconstructorK*)recoEvent); 
311       fMUONData->Fill("RC"); 
312     }
313     loader->WriteRecPoints("OVERWRITE"); 
314
315     //--------------------------- Resetting branches -----------------------
316     fMUONData->ResetDigits();
317     fMUONData->ResetRawClusters();
318     fMUONData->ResetTrigger();
319     fMUONData->ResetRecTracks();  
320     fMUONData->ResetRecTriggerTracks();
321
322   }
323   loader->UnloadDigits();
324   loader->UnloadRecPoints();
325   loader->UnloadTracks();
326
327   delete recoCluster;
328   delete recoEvent;
329   delete calibration;
330 }
331
332 //_____________________________________________________________________________
333 void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, 
334                                        AliRawReader* rawReader) const
335 {
336 /// Recontruct
337 /// \todo add more
338
339   //  AliLoader
340   AliLoader* loader = runLoader->GetLoader("MUONLoader");
341   Int_t evtNumber   = runLoader->GetEventNumber();
342  
343   fMUONData->SetLoader(loader);
344
345   // passing loader as argument.
346   fDigitMaker->SetMUONData(fMUONData);
347
348   // disable trigger rawdata reading
349   if (strstr(GetOption(),"TriggerDisable"))
350       fDigitMaker->DisableTrigger();
351
352   AliMUONClusterReconstructor* recoCluster = CreateClusterReconstructor();
353
354   AliMUONClusterFinderVS *recModel = recoCluster->GetRecoModel();
355
356   if (!strstr(GetOption(),"VS")) 
357   {
358     recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ();
359     recoCluster->SetRecoModel(recModel);
360   }
361   recModel->SetGhostChi2Cut(10);
362   recModel->SetEventNumber(evtNumber);
363   
364   TTask* calibration = GetCalibrationTask();
365   
366   loader->LoadRecPoints("RECREATE");
367  
368   // Digits are not stored on disk and created on flight from rawdata.
369   // In order to write digits on disk the following line should be uncommented
370   // loader->LoadDigits("RECREATE"); 
371
372   //   Loop over events  
373   Int_t iEvent = 0;
374            
375   TStopwatch totalTimer;
376   TStopwatch rawTimer;
377   TStopwatch calibTimer;
378   TStopwatch clusterTimer;
379   
380   rawTimer.Start(kTRUE); rawTimer.Stop();
381   calibTimer.Start(kTRUE); calibTimer.Stop();
382   clusterTimer.Start(kTRUE); clusterTimer.Stop();
383   
384   totalTimer.Start(kTRUE);
385   
386   while (rawReader->NextEvent()) 
387   {
388     AliDebug(1,Form("Event %d",iEvent));
389     
390     runLoader->GetEvent(iEvent++);
391     
392     //----------------------- raw2digits & raw2trigger-------------------
393     //  if (!loader->TreeD()) 
394     //  {
395     //    AliDebug(1,Form("Making Digit Container for event %d",iEvent));
396     //    loader->MakeDigitsContainer();
397     //  }
398     //  Digits are not stored on disk and created on flight from rawdata.
399     //  In order to write digits on disk the following lines should be uncommented
400     //  fMUONData->MakeBranch("D,GLT");
401     //  fMUONData->SetTreeAddress("D,GLT");
402     fMUONData->SetDataContainer("D, GLT");
403     rawTimer.Start(kFALSE);
404     fDigitMaker->Raw2Digits(rawReader);
405     rawTimer.Stop();
406     
407     if ( calibration )
408     {
409       calibTimer.Start(kFALSE);
410       calibration->ExecuteTask();
411       calibTimer.Stop();
412     }
413     // Digits are not stored on disk and created on flight from rawdata.
414     // In order to write digits on disk the following lines should be uncommented
415     // fMUONData->Fill("D,GLT");
416     // loader->WriteDigits("OVERWRITE");
417     //----------------------- digit2cluster & Trigger2Trigger -------------------
418     clusterTimer.Start(kFALSE);
419
420     if (!loader->TreeR()) loader->MakeRecPointsContainer();
421     
422     // tracking branch
423     fMUONData->MakeBranch("RC");
424     fMUONData->SetTreeAddress("RC");
425     recoCluster->Digits2Clusters(); 
426     fMUONData->Fill("RC"); 
427
428     // trigger branch
429     fMUONData->MakeBranch("TC");
430     fMUONData->SetTreeAddress("TC");
431     fMUONData->Fill("TC");
432     
433     loader->WriteRecPoints("OVERWRITE");
434
435     clusterTimer.Stop();
436     
437     
438     //--------------------------- Resetting branches -----------------------
439     fMUONData->ResetDigits();
440     fMUONData->ResetRawClusters();
441     fMUONData->ResetTrigger();
442   }
443   
444   totalTimer.Stop();
445   
446   loader->UnloadRecPoints();
447   loader->UnloadDigits();
448   
449   delete recoCluster;
450   delete calibration;
451   
452   AliInfo(Form("Execution time for converting RAW data to digits in MUON : R:%.2fs C:%.2fs",
453                rawTimer.RealTime(),rawTimer.CpuTime()));
454   AliInfo(Form("Execution time for calibrating MUON : R:%.2fs C:%.2fs",
455                calibTimer.RealTime(),calibTimer.CpuTime()));
456   AliInfo(Form("Execution time for clusterizing MUON : R:%.2fs C:%.2fs",
457                clusterTimer.RealTime(),clusterTimer.CpuTime()));
458   AliInfo(Form("Total Execution time for Reconstruct(from raw) MUON : R:%.2fs C:%.2fs",
459                totalTimer.RealTime(),totalTimer.CpuTime()));
460 }
461
462 //_____________________________________________________________________________
463 void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const
464 {
465 /// Fill ESD
466 /// \todo add more
467
468   TClonesArray* recTracksArray = 0;
469   TClonesArray* recTrigTracksArray = 0;
470   
471   AliLoader* loader = runLoader->GetLoader("MUONLoader");
472   loader->LoadTracks("READ");
473   fMUONData->SetLoader(loader);
474
475    // declaration  
476   Int_t iEvent;// nPart;
477   Int_t nTrackHits;// nPrimary;
478   Double_t fitFmin, chi2MatchTrigger;
479   Double_t xRec, yRec, zRec, bendingSlope, nonBendingSlope, inverseBendingMomentum;
480   Double_t xVtx, yVtx, zVtx, bendingSlopeAtVtx, nonBendingSlopeAtVtx, inverseBendingMomentumAtVtx;
481   Bool_t matchTrigger;
482
483   // setting pointer for tracks, triggertracks & trackparam at vertex
484   AliMUONTrack* recTrack = 0;
485   AliMUONTrackParam trackParamAtVtx;
486   AliMUONTriggerTrack* recTriggerTrack = 0;
487
488   iEvent = runLoader->GetEventNumber(); 
489   runLoader->GetEvent(iEvent);
490
491   // Get vertex 
492   Double_t vertex[3] = {0};
493   const AliESDVertex *esdVert = esd->GetVertex(); 
494   if (esdVert->GetNContributors()) {
495     esdVert->GetXYZ(vertex);
496     AliDebug(1, "find vertex\n");
497   }
498   // setting ESD MUON class
499   AliESDMuonTrack* theESDTrack = new  AliESDMuonTrack() ;
500
501   //-------------------- trigger tracks-------------
502   Long_t trigPat = 0;
503   fMUONData->SetTreeAddress("RL");
504   fMUONData->GetRecTriggerTracks();
505   recTrigTracksArray = fMUONData->RecTriggerTracks();
506
507   // ready global trigger pattern from first track
508   if (recTrigTracksArray) 
509     recTriggerTrack = (AliMUONTriggerTrack*) recTrigTracksArray->First();
510   if (recTriggerTrack) trigPat = recTriggerTrack->GetGTPattern();
511
512   //printf(">>> Event %d Number of Recconstructed tracks %d \n",iEvent, nrectracks);
513  
514   // -------------------- tracks-------------
515   fMUONData->SetTreeAddress("RT");
516   fMUONData->GetRecTracks();
517   recTracksArray = fMUONData->RecTracks();
518         
519   Int_t nRecTracks = 0;
520   if (recTracksArray)
521     nRecTracks = (Int_t) recTracksArray->GetEntriesFast(); //
522   
523   // loop over tracks
524   for (Int_t iRecTracks = 0; iRecTracks <  nRecTracks;  iRecTracks++) {
525
526     // reading info from tracks
527     recTrack = (AliMUONTrack*) recTracksArray->At(iRecTracks);
528     AliMUONTrackParam *trackParam = (AliMUONTrackParam*) (recTrack->GetTrackParamAtHit())->First();
529     trackParamAtVtx = *trackParam;
530    
531     // extrapolate to the vertex if available, else to (0,0,0)
532     if (esdVert->GetNContributors())
533       AliMUONTrackExtrap::ExtrapToVertex(&trackParamAtVtx, vertex[0],vertex[1],vertex[2]);
534     else
535       AliMUONTrackExtrap::ExtrapToVertex(&trackParamAtVtx, 0.,0.,0.);
536     
537     // Track parameters at first station
538     bendingSlope           = trackParam->GetBendingSlope();
539     nonBendingSlope        = trackParam->GetNonBendingSlope();
540     inverseBendingMomentum = trackParam->GetInverseBendingMomentum();
541     xRec = trackParam->GetNonBendingCoor();
542     yRec = trackParam->GetBendingCoor();
543     zRec = trackParam->GetZ();
544     
545     // Track parameters at vertex
546     bendingSlopeAtVtx           = trackParamAtVtx.GetBendingSlope();
547     nonBendingSlopeAtVtx        = trackParamAtVtx.GetNonBendingSlope();
548     inverseBendingMomentumAtVtx = trackParamAtVtx.GetInverseBendingMomentum();
549     xVtx = trackParamAtVtx.GetNonBendingCoor();
550     yVtx = trackParamAtVtx.GetBendingCoor();
551     zVtx = trackParamAtVtx.GetZ();
552     
553     // Global info
554     nTrackHits       = recTrack->GetNTrackHits();
555     fitFmin          = recTrack->GetFitFMin();
556     matchTrigger     = recTrack->GetMatchTrigger();
557     chi2MatchTrigger = recTrack->GetChi2MatchTrigger();
558
559     // setting data member of ESD MUON
560     // at first station
561     theESDTrack->SetInverseBendingMomentumUncorrected(inverseBendingMomentum);
562     theESDTrack->SetThetaXUncorrected(TMath::ATan(nonBendingSlope));
563     theESDTrack->SetThetaYUncorrected(TMath::ATan(bendingSlope));
564     theESDTrack->SetZUncorrected(zRec);
565     theESDTrack->SetBendingCoorUncorrected(yRec);
566     theESDTrack->SetNonBendingCoorUncorrected(xRec);
567     // at vertex
568     theESDTrack->SetInverseBendingMomentum(inverseBendingMomentumAtVtx);
569     theESDTrack->SetThetaX(TMath::ATan(nonBendingSlopeAtVtx));
570     theESDTrack->SetThetaY(TMath::ATan(bendingSlopeAtVtx));
571     theESDTrack->SetZ(zVtx);
572     theESDTrack->SetBendingCoor(yVtx);
573     theESDTrack->SetNonBendingCoor(xVtx);
574     // global info
575     theESDTrack->SetChi2(fitFmin);
576     theESDTrack->SetNHit(nTrackHits);
577     theESDTrack->SetMatchTrigger(matchTrigger);
578     theESDTrack->SetChi2MatchTrigger(chi2MatchTrigger);
579
580     // storing ESD MUON Track into ESD Event 
581     if (nRecTracks != 0)  
582       esd->AddMuonTrack(theESDTrack);
583   } // end loop tracks
584
585   // reset muondata
586   fMUONData->ResetRecTracks();
587   fMUONData->ResetRecTriggerTracks();
588
589   //} // end loop on event  
590   loader->UnloadTracks(); 
591
592   delete theESDTrack;
593 }
594
595 //_____________________________________________________________________________
596 void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliRawReader* /*rawReader*/, AliESD* esd) const
597 {
598 /// Fill ESD
599 /// \todo add more
600
601   // don't need rawReader ???
602   FillESD(runLoader, esd);
603 }
604
605 //_____________________________________________________________________________
606 AliTracker* AliMUONReconstructor::CreateTracker(AliRunLoader* runLoader) const
607 {
608   /// create tracker for MUON
609   /// go into the tracking framework finally (Ch.F)
610  
611   AliLoader* loader = runLoader->GetLoader("MUONLoader");
612
613   fMUONData->SetLoader(loader);
614
615   AliMUONTracker* tracker = new AliMUONTracker();
616   tracker->SetMUONData(fMUONData);
617   tracker->SetTriggerCircuit(fTriggerCircuit);
618   tracker->SetOption(GetOption());
619
620   return tracker;
621
622 }