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