Adding comment lines to class description needed for Root documentation,
[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 /// Implementation of AliReconstructor for MUON subsystem.
21 ///
22 /// The behavior of the MUON reconstruction can be changed, besides
23 /// the usual methods found in AliReconstruction (e.g. to disable tracking)
24 /// by using AliReconstruction::SetOption("MUON",options)
25 /// where options should be a space separated string.
26 ///
27 /// Valid options are :
28 ///
29 /// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits
30 ///     that are used for the clustering
31 ///
32 /// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer
33 ///
34 /// AZ : use the AliMUONClusterFinderAZ clusterizer (default)
35 ///
36 /// MLEM : another implementation of AZ, where preclustering is external
37 /// MLEMV3 : MLEM with preclustering=PRECLUSTERV2
38 /// MLEMV3 : MLEM with preclustering=PRECLUSTERV3
39 ///
40 /// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as
41 /// the produced clusters do not have a position, hence the tracking will not
42 /// work
43 /// PRECLUSTERV2 : another version of the preclustering
44 /// PRECLUSTERV3 : yet another version of the preclustering
45 ///
46 /// COG : use AliMUONClusterFinderCOG clusterizer. Not really a production
47 /// option either, as center-of-gravity is generally not a good estimate
48 /// of the cluster position...
49 ///
50 /// NOCLUSTERING : bypass completely the clustering stage
51 ///
52 /// NOSTATUSMAP : disable the computation and usage of the pad status map. Only
53 /// for debug !
54 ///
55 /// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence
56 /// "recover" old behavior)
57 ///
58 /// TRIGGERDISABLE : disable the treatment of MUON trigger
59 ///
60 /// DIGITSTOREV1 : use the V1 implementation of the digitstore 
61 /// DIGITSTOREV2R : use the V2R implementation of the digitstore 
62 ///
63 /// \author Laurent Aphecetche, Subatech
64 //-----------------------------------------------------------------------------
65
66 #include "AliMUONReconstructor.h"
67
68 #include "AliCDBManager.h"
69 #include "AliLoader.h"
70 #include "AliLog.h"
71 #include "AliRunLoader.h"
72 #include "AliMUONCalibrationData.h"
73 #include "AliMUONClusterFinderCOG.h"
74 #include "AliMUONClusterFinderMLEM.h"
75 #include "AliMUONClusterFinderSimpleFit.h"
76 #include "AliMUONClusterFinderAZ.h"
77 #include "AliMUONClusterReconstructor.h"
78 #include "AliMUONClusterStoreV1.h"
79 #include "AliMUONConstants.h"
80 #include "AliMUONDigitCalibrator.h"
81 #include "AliMUONDigitMaker.h"
82 #include "AliMUONDigitStoreV1.h"
83 #include "AliMUONDigitStoreV2R.h"
84 #include "AliMUONGeometryTransformer.h"
85 #include "AliMUONPreClusterFinder.h"
86 #include "AliMUONPreClusterFinderV2.h"
87 #include "AliMUONPreClusterFinderV3.h"
88 #include "AliMUONTracker.h"
89 #include "AliMUONVTrackStore.h"
90 #include "AliMUONTriggerChamberEff.h"
91 #include "AliMUONTriggerCircuit.h"
92 #include "AliMUONTriggerCrateStore.h"
93 #include "AliMUONTriggerStoreV1.h"
94 #include "AliMUONVClusterFinder.h"
95 #include "AliMpCDB.h"
96 #include "AliRawReader.h"
97 #include "AliCodeTimer.h"
98 #include <Riostream.h>
99 #include <TClonesArray.h>
100 #include <TString.h>
101 #include <TTree.h>
102 //#include "AliCodeTimer.h"
103 /// \cond CLASSIMP
104 ClassImp(AliMUONReconstructor)
105 /// \endcond 
106
107 //_____________________________________________________________________________
108 AliMUONReconstructor::AliMUONReconstructor() : 
109 AliReconstructor(),
110 fCrateManager(0x0),
111 fDigitMaker(0x0),
112 fTransformer(new AliMUONGeometryTransformer()),
113 fDigitStore(0x0),
114 fTriggerCircuit(0x0),
115 fCalibrationData(0x0),
116 fDigitCalibrator(0x0),
117 fClusterReconstructor(0x0),
118 fClusterStore(0x0),
119 fTriggerStore(0x0),
120 fTrackStore(0x0),
121 fTrigChamberEff(0x0)
122 {
123   /// normal ctor
124
125   // Load geometry data
126   fTransformer->LoadGeometryData();
127   
128   // Load mapping
129   if ( ! AliMpCDB::LoadMpSegmentation() ) 
130   {
131     AliFatal("Could not access mapping from OCDB !");
132   }
133   
134   // Load DDL store
135   if ( ! AliMpCDB::LoadDDLStore() ) 
136   {
137     AliFatal("Could not access DDL Store from OCDB !");
138   }
139   
140   
141 }
142
143 //_____________________________________________________________________________
144 AliMUONReconstructor::~AliMUONReconstructor()
145 {
146   /// dtor
147   delete fDigitMaker;
148   delete fDigitStore;
149   delete fTransformer;
150   delete fCrateManager;
151   delete fTriggerCircuit;
152   delete fCalibrationData;
153   delete fDigitCalibrator;
154   delete fClusterReconstructor;
155   delete fClusterStore;
156   delete fTriggerStore;
157   delete fTrackStore;
158   delete fTrigChamberEff;
159 }
160
161 //_____________________________________________________________________________
162 void
163 AliMUONReconstructor::Calibrate(AliMUONVDigitStore& digitStore) const
164 {
165   /// Calibrate the digitStore
166   if (!fDigitCalibrator)
167   {
168     CreateCalibrator();
169   }
170   AliCodeTimerAuto(Form("%s::Calibrate(AliMUONVDigitStore*)",fDigitCalibrator->ClassName()))
171   fDigitCalibrator->Calibrate(digitStore);  
172 }
173
174 //_____________________________________________________________________________
175 void
176 AliMUONReconstructor::Clusterize(const AliMUONVDigitStore& digitStore,
177                                  AliMUONVClusterStore& clusterStore) const
178 {
179   /// Creates clusters from digits.
180
181   TString sopt(GetOption());
182   sopt.ToUpper();
183   if ( sopt.Contains("NOCLUSTERING") ) return;
184   
185   if  (!fClusterReconstructor)
186   {
187     CreateClusterReconstructor();
188   }
189   
190   AliCodeTimerAuto(Form("%s::Digits2Clusters(const AliMUONVDigitStore&,AliMUONVClusterStore&)",
191                         fClusterReconstructor->ClassName()))
192   fClusterReconstructor->Digits2Clusters(digitStore,clusterStore);  
193 }
194
195 //_____________________________________________________________________________
196 AliMUONVClusterStore*
197 AliMUONReconstructor::ClusterStore() const
198 {
199   /// Return (and create if necessary) the cluster container
200   if (!fClusterStore) 
201   {
202     fClusterStore = new AliMUONClusterStoreV1;
203   }
204   return fClusterStore;
205 }
206
207 //_____________________________________________________________________________
208 void
209 AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, 
210                                     AliMUONVDigitStore* digitStore,
211                                     AliMUONVTriggerStore* triggerStore) const
212 {
213   /// Convert raw data into digit and trigger stores
214   CreateDigitMaker();
215   
216   AliCodeTimerStart(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)",
217                     fDigitMaker->ClassName()))
218   fDigitMaker->Raw2Digits(rawReader,digitStore,triggerStore);
219   AliCodeTimerStop(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)",
220                          fDigitMaker->ClassName()))
221   Calibrate(*digitStore);
222 }
223
224 //_____________________________________________________________________________
225 void 
226 AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const
227 {
228    /// convert raw data into a digit tree
229
230   Bool_t alone = ( TriggerStore() == 0 );
231   
232   Bool_t ok = DigitStore()->Connect(*digitsTree,alone);
233   if ( TriggerStore() ) 
234   {
235     ok = ok && TriggerStore()->Connect(*digitsTree,kFALSE);
236   }
237   
238   if (!ok)
239   {
240     AliError("Could not make branches on TreeD");
241   }
242   else
243   {
244     ConvertDigits(rawReader,DigitStore(),TriggerStore());
245     digitsTree->Fill();
246     DigitStore()->Clear();
247   }
248 }
249
250 //_____________________________________________________________________________
251 AliMUONTriggerCrateStore*
252 AliMUONReconstructor::CrateManager() const
253 {
254   /// Return (and create if necessary) the trigger crate store
255   if (fCrateManager) return fCrateManager;
256   fCrateManager = new AliMUONTriggerCrateStore;
257   fCrateManager->ReadFromFile();
258   return fCrateManager;
259 }
260
261 //_____________________________________________________________________________
262 void
263 AliMUONReconstructor::CreateDigitMaker() const
264 {
265   /// Create (and create if necessary) the digit maker
266   if (fDigitMaker) return;
267
268   AliCodeTimerAuto("")
269
270   fDigitMaker = new AliMUONDigitMaker;
271 }
272
273 //_____________________________________________________________________________
274 void 
275 AliMUONReconstructor::CreateTriggerCircuit() const
276 {
277   /// Return (and create if necessary) the trigger circuit object
278   if (fTriggerCircuit) return;
279
280   AliCodeTimerAuto("")
281
282   fTriggerCircuit = new AliMUONTriggerCircuit(fTransformer);
283
284 }
285
286 //_____________________________________________________________________________
287 void
288 AliMUONReconstructor::CreateTriggerChamberEff() const
289 {
290   /// Create (and create if necessary) the trigger chamber efficiency class
291   if (fTrigChamberEff) return;
292
293   AliCodeTimerAuto("")
294
295   fTrigChamberEff = new AliMUONTriggerChamberEff(fTransformer,fDigitMaker,kTRUE);
296   //fTrigChamberEff->SetDebugLevel(1);
297 }
298
299 //_____________________________________________________________________________
300 AliTracker* 
301 AliMUONReconstructor::CreateTracker(AliRunLoader* runLoader) const
302 {
303   /// Create the MUONTracker object
304   /// The MUONTracker is passed the GetOption(), i.e. our own options
305   
306   CreateTriggerCircuit();
307   CreateDigitMaker();
308   CreateTriggerChamberEff();
309   
310   AliLoader* loader = runLoader->GetDetectorLoader("MUON");
311   if (!loader)
312   {
313     AliError("Cannot get MUONLoader, so cannot create MUONTracker");
314     return 0x0;
315   }
316   AliMUONTracker* tracker = new AliMUONTracker(loader,fDigitMaker,fTransformer,fTriggerCircuit,fTrigChamberEff);
317   tracker->SetOption(GetOption());
318   
319   return tracker;
320 }
321
322 //_____________________________________________________________________________
323 void
324 AliMUONReconstructor::CreateClusterReconstructor() const
325 {
326   /// Create cluster reconstructor, depending on GetOption()
327   
328   AliCodeTimerAuto("")
329
330   AliDebug(1,"");
331   
332   AliMUONVClusterFinder* clusterFinder(0x0);
333   
334   TString opt(GetOption());
335   opt.ToUpper();
336   
337   if ( strstr(opt,"PRECLUSTERV2") )
338   {
339     clusterFinder = new AliMUONPreClusterFinderV2;
340   }    
341   else if ( strstr(opt,"PRECLUSTERV3") )
342   {
343     clusterFinder = new AliMUONPreClusterFinderV3;
344   }  
345   else if ( strstr(opt,"PRECLUSTER") )
346   {
347     clusterFinder = new AliMUONPreClusterFinder;
348   }  
349   else if ( strstr(opt,"COG") )
350   {
351     clusterFinder = new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder);
352   }  
353   else if ( strstr(opt,"SIMPLEFITV3") )
354   {
355     clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3));
356   }
357   else if ( strstr(opt,"SIMPLEFIT") )
358   {
359     clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder));
360   }
361   else if ( strstr(opt,"MLEM:DRAW") )
362   {
363     clusterFinder = new AliMUONClusterFinderMLEM(kTRUE,new AliMUONPreClusterFinder);
364   }
365   else if ( strstr(opt,"MLEMV3") )
366   {
367     clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV3);
368   } 
369   else if ( strstr(opt,"MLEMV2") )
370   {
371     clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV2);
372   } 
373   else if ( strstr(opt,"MLEM") )
374   {
375     clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinder);
376   } 
377   else if ( strstr(opt,"AZ") )
378   {
379     clusterFinder = new AliMUONClusterFinderAZ;
380   }
381   else
382   {
383     // default is currently AZ
384     clusterFinder = new AliMUONClusterFinderAZ;
385   }
386   
387   if ( clusterFinder ) 
388   {
389     AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
390   }
391   
392   fClusterReconstructor = new AliMUONClusterReconstructor(clusterFinder,fTransformer);
393 }
394
395 //_____________________________________________________________________________
396 void
397 AliMUONReconstructor::CreateCalibrator() const
398 {
399   /// Create the calibrator
400   
401   AliCodeTimerAuto("")
402   
403   Int_t runNumber = AliCDBManager::Instance()->GetRun();
404
405   AliInfo("Calibration will occur.");
406   
407   fCalibrationData = new AliMUONCalibrationData(runNumber);
408   if ( !fCalibrationData->IsValid() )
409   {
410     AliError("Could not retrieve calibrations !");
411     delete fCalibrationData;
412     fCalibrationData = 0x0;
413     return;
414   }    
415   
416   // Check that we get all the calibrations we'll need
417   if ( !fCalibrationData->Pedestals() ||
418        !fCalibrationData->Gains() ||
419        !fCalibrationData->HV() )
420   {
421     AliFatal("Could not access all required calibration data");
422   }
423   
424   TString opt(GetOption());
425   opt.ToUpper();
426   Bool_t statusMap(kTRUE);
427   
428   if ( strstr(opt,"NOSTATUSMAP") )
429   {
430     AliWarning("Disconnecting status map : SHOULD BE USED FOR DEBUG ONLY. NOT FOR PRODUCTION !!!");
431     statusMap = kFALSE; 
432   }
433   fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,statusMap);
434 }
435
436 //_____________________________________________________________________________
437 AliMUONVDigitStore*
438 AliMUONReconstructor::DigitStore() const
439 {
440   /// Return (and create if necessary) the digit container
441   if (!fDigitStore) 
442   {
443     TString sopt(GetOption());
444     sopt.ToUpper();
445     
446     AliInfo(Form("Options=%s",sopt.Data()));
447     
448     if ( sopt.Contains("DIGITSTOREV1") )
449     {
450       fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV1");
451     }
452     else if ( sopt.Contains("DIGITSTOREV2R") ) 
453     {
454       fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
455     }
456     else if ( sopt.Contains("DIGITSTOREV2S") ) 
457     {
458       fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2S");
459     }
460     
461     if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
462     
463     AliInfo(Form("Will use %s to store digits during reconstruction",fDigitStore->ClassName()));
464   }
465   return fDigitStore;
466 }
467
468 //_____________________________________________________________________________
469 void
470 AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore,
471                                 AliMUONVClusterStore* clusterStore,
472                                 TTree& clustersTree) const
473 {
474   /// Write the trigger and cluster information into TreeR
475   
476   AliCodeTimerAuto("")
477
478   AliDebug(1,"");
479   
480   Bool_t ok(kFALSE);
481   if ( triggerStore ) 
482   {
483     Bool_t alone = ( clusterStore ? kFALSE : kTRUE );
484     ok = triggerStore->Connect(clustersTree,alone);
485     if (!ok)
486     {
487       AliError("Could not create triggerStore branches in TreeR");
488     }
489   }
490   
491   if ( clusterStore ) 
492   {
493     Bool_t alone = ( triggerStore ? kFALSE : kTRUE );
494     ok = clusterStore->Connect(clustersTree,alone);
495     if (!ok)
496     {
497       AliError("Could not create triggerStore branches in TreeR");
498     }    
499   }
500   
501   if (ok) // at least one type of branches created successfully
502   {
503     clustersTree.Fill();
504   }
505 }
506
507 //_____________________________________________________________________________
508 Bool_t 
509 AliMUONReconstructor::HasDigitConversion() const
510 {
511   /// We *do* have digit conversion, but we might advertise it only 
512   /// if we want to save the digits.
513   
514   TString opt(GetOption());
515   opt.ToUpper();
516   if ( opt.Contains("SAVEDIGITS" ) && !opt.Contains("NOLOCALRECONSTRUCTION") )
517   {
518     return kTRUE;
519   }
520   else
521   {
522     return kFALSE;
523   }
524 }
525
526 //_____________________________________________________________________________
527 Bool_t 
528 AliMUONReconstructor::HasLocalReconstruction() const
529 {
530   /// Whether or not we have local reconstruction
531   TString opt(GetOption());
532   opt.ToUpper();
533   if ( opt.Contains("NOLOCALRECONSTRUCTION" ) )
534   {
535     return kFALSE;
536   }
537   else
538   {
539     return kTRUE;
540   }
541 }
542
543 //_____________________________________________________________________________
544 void 
545 AliMUONReconstructor::Reconstruct(AliRawReader* rawReader, TTree* clustersTree) const
546 {
547   /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE AND
548   /// HasDigitConversion()==kFALSE
549   
550   if ( !clustersTree ) 
551   {
552     AliError("clustersTree is 0x0 !");
553     return;
554   }
555   
556   ConvertDigits(rawReader,DigitStore(),TriggerStore());
557   Clusterize(*(DigitStore()),*(ClusterStore()));
558     
559   FillTreeR(TriggerStore(),ClusterStore(),*clustersTree);
560 }
561
562 //_____________________________________________________________________________
563 void 
564 AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const
565 {
566   /// Reconstruct simulated data
567   
568   AliCodeTimerAuto("Reconstruct(AliRunLoader*)")
569   
570   AliLoader* loader = runLoader->GetDetectorLoader("MUON");
571   if (!loader) 
572   {
573     AliError("Could not get MUON loader");
574     return;
575   }
576   
577   Int_t nEvents = runLoader->GetNumberOfEvents();
578   
579   for ( Int_t i = 0; i < nEvents; ++i ) 
580   {
581     runLoader->GetEvent(i);
582     
583     loader->LoadRecPoints("update");
584     loader->CleanRecPoints();
585     loader->MakeRecPointsContainer();
586     TTree* clustersTree = loader->TreeR();
587     
588     loader->LoadDigits("read");
589     TTree* digitsTree = loader->TreeD();
590
591     Reconstruct(digitsTree,clustersTree);
592     
593     loader->UnloadDigits();
594     loader->WriteRecPoints("OVERWRITE");
595     loader->UnloadRecPoints();    
596   }
597 }
598
599 //_____________________________________________________________________________
600 void 
601 AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, AliRawReader* rawReader) const
602 {
603   /// This method is called by AliReconstruction if HasLocalReconstruction()==kFALSE
604   
605   AliCodeTimerAuto("AliMUONReconstructor::Reconstruct(AliRunLoader*, AliRawReader*)")
606   
607   AliLoader* loader = runLoader->GetDetectorLoader("MUON");
608   if (!loader) 
609   {
610     AliError("Could not get MUON loader");
611     return;
612   }
613
614   Int_t i(0);
615   
616   while (rawReader->NextEvent()) 
617   {
618     runLoader->GetEvent(i++);
619     
620     loader->LoadRecPoints("update");
621     loader->CleanRecPoints();
622     loader->MakeRecPointsContainer();
623     TTree* clustersTree = loader->TreeR();
624     
625     loader->LoadDigits("update");
626     loader->CleanDigits();
627     loader->MakeDigitsContainer();
628     TTree* digitsTree = loader->TreeD();
629     ConvertDigits(rawReader, digitsTree);
630     loader->WriteDigits("OVERWRITE");
631     
632     Reconstruct(digitsTree,clustersTree);
633     
634     loader->UnloadDigits();
635     loader->WriteRecPoints("OVERWRITE");
636     loader->UnloadRecPoints();    
637   }
638 }
639
640 //_____________________________________________________________________________
641 void 
642 AliMUONReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const
643 {
644   /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE
645   /// AND HasDigitConversion()==kTRUE
646   
647 //  AliCodeTimerAuto("(TTree*,TTree*)")
648   
649   AliDebug(1,"");
650   
651   if (!digitsTree || !clustersTree) 
652   {
653     AliError(Form("Tree is null : digitsTree=%p clustersTree=%p",
654                   digitsTree,clustersTree));
655     return;
656   }
657
658   if (!fDigitStore)
659   {
660     fDigitStore = AliMUONVDigitStore::Create(*digitsTree);
661     if (!fDigitStore)
662     {
663       AliError(Form("Could not get DigitStore from %s",digitsTree->GetName()));
664     }
665     else
666     {
667       AliInfo(Form("Created %s from %s",fDigitStore->ClassName(),digitsTree->GetName()));
668     }
669   }
670   if (!fTriggerStore)
671   {
672     fTriggerStore = AliMUONVTriggerStore::Create(*digitsTree);
673     if (!fTriggerStore)
674     {
675       AliError(Form("Could not get TriggerStore from %s",digitsTree->GetName()));
676     }
677     else
678     {
679       AliInfo(Form("Created %s from %s",fTriggerStore->ClassName(),digitsTree->GetName()));
680     }
681   }
682   
683   if (!fTriggerStore && !fDigitStore)
684   {
685     AliError("No store at all. Nothing to do.");
686     return;
687   }
688   
689   // insure we start with empty stores
690   if ( fDigitStore ) 
691   {
692     fDigitStore->Clear(); 
693     Bool_t alone = ( fTriggerStore ? kFALSE : kTRUE );
694     Bool_t ok = fDigitStore->Connect(*digitsTree,alone);
695     if (!ok)
696     {
697       AliError("Could not connect digitStore to digitsTree");
698       return;
699     }
700   }
701   if ( fTriggerStore ) 
702   {
703     fTriggerStore->Clear();
704     Bool_t alone = ( fDigitStore ? kFALSE : kTRUE );
705     Bool_t ok = fTriggerStore->Connect(*digitsTree,alone);
706     if (!ok)
707     {
708       AliError("Could not connect triggerStore to digitsTree");
709       return;
710     }
711   }
712   
713   digitsTree->GetEvent(0);
714   
715   if ( fDigitStore ) 
716   {
717     // Insure we got calibrated digits (if we reconstruct from pure simulated,
718     // i.e. w/o going through raw data, this will be the case)
719     TIter next(fDigitStore->CreateIterator());
720     AliMUONVDigit* digit = static_cast<AliMUONVDigit*>(next());
721     if (!digit->IsCalibrated())
722     {
723       Calibrate(*fDigitStore);
724     }
725     Clusterize(*fDigitStore,*(ClusterStore()));
726   }
727     
728   FillTreeR(fTriggerStore,ClusterStore(),*clustersTree);
729 }
730
731 //_____________________________________________________________________________
732 AliMUONVTriggerStore*
733 AliMUONReconstructor::TriggerStore() const
734 {
735   /// Return (and create if necessary and allowed) the trigger container
736   TString sopt(GetOption());
737   sopt.ToUpper();
738   
739   if (sopt.Contains("TRIGGERDISABLE"))
740   {
741     delete fTriggerStore;
742     fTriggerStore = 0x0;
743   }
744   else
745   {
746     if (!fTriggerStore)
747     {
748       fTriggerStore = new AliMUONTriggerStoreV1;
749     }
750   }
751   return fTriggerStore;
752 }