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