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