1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 /// \class AliMUONReconstructor
19 /// Implementation of AliReconstructor for MUON subsystem.
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.
26 /// Valid options are :
28 /// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits
29 /// that are used for the clustering
31 /// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer
33 /// AZ : use the AliMUONClusterFinderAZ clusterizer (default)
35 /// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as
36 /// the produced clusters do not have a position, hence the tracking will not
39 /// COG : use AliMUONClusterFinderCOG clusterizer. Not really a production
40 /// option either, as center-of-gravity is generally not a good estimate
41 /// of the cluster position...
43 /// NOCLUSTERING : bypass completely the clustering stage
45 /// NOSTATUSMAP : disable the computation and usage of the pad status map. Only
48 /// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence
49 /// "recover" old behavior)
51 /// TRIGGERDISABLE : disable the treatment of MUON trigger
53 /// \author Laurent Aphecetche, Subatech
55 #include "AliMUONReconstructor.h"
57 #include "AliCDBManager.h"
58 #include "AliLoader.h"
60 #include "AliRunLoader.h"
61 #include "AliMUONCalibrationData.h"
62 #include "AliMUONClusterFinderCOG.h"
63 #include "AliMUONClusterFinderMLEM.h"
64 #include "AliMUONClusterFinderSimpleFit.h"
65 #include "AliMUONClusterFinderAZ.h"
66 #include "AliMUONClusterReconstructor.h"
67 #include "AliMUONClusterStoreV1.h"
68 #include "AliMUONConstants.h"
69 #include "AliMUONDigitCalibrator.h"
70 #include "AliMUONDigitMaker.h"
71 #include "AliMUONDigitStoreV1.h"
72 #include "AliMUONGeometryTransformer.h"
73 #include "AliMUONPreClusterFinder.h"
74 #include "AliMUONTracker.h"
75 #include "AliMUONVTrackStore.h"
76 #include "AliMUONTriggerCircuit.h"
77 #include "AliMUONTriggerCrateStore.h"
78 #include "AliMUONTriggerStoreV1.h"
79 #include "AliMUONVClusterFinder.h"
80 #include "AliRawReader.h"
81 #include "AliMUONStopwatchGroup.h"
82 #include "AliMUONStopwatchGroupElement.h"
83 #include <Riostream.h>
84 #include <TClonesArray.h>
89 ClassImp(AliMUONReconstructor)
92 //_____________________________________________________________________________
93 AliMUONReconstructor::AliMUONReconstructor() :
97 fTransformer(new AliMUONGeometryTransformer(kTRUE)),
100 fCalibrationData(0x0),
101 fDigitCalibrator(0x0),
102 fClusterReconstructor(0x0),
106 fTimers(new AliMUONStopwatchGroup)
109 fTransformer->ReadGeometryData("volpath.dat", "geometry.root");
112 //_____________________________________________________________________________
113 AliMUONReconstructor::~AliMUONReconstructor()
119 delete fCrateManager;
120 delete fTriggerCircuit;
121 delete fCalibrationData;
122 delete fDigitCalibrator;
123 delete fClusterReconstructor;
124 delete fClusterStore;
125 delete fTriggerStore;
132 //_____________________________________________________________________________
134 AliMUONReconstructor::Calibrate(AliMUONVDigitStore& digitStore) const
136 /// Calibrate the digitStore
137 if (!fDigitCalibrator)
141 AliMUONStopwatchGroupElement timer(fTimers,"MUON",Form("%s::Calibrate(AliMUONVDigitStore*)",fDigitCalibrator->ClassName()));
142 fDigitCalibrator->Calibrate(digitStore);
145 //_____________________________________________________________________________
147 AliMUONReconstructor::Clusterize(const AliMUONVDigitStore& digitStore,
148 AliMUONVClusterStore& clusterStore) const
150 /// Creates clusters from digits.
152 TString sopt(GetOption());
154 if ( sopt.Contains("NOCLUSTERING") ) return;
156 if (!fClusterReconstructor)
158 CreateClusterReconstructor();
161 AliMUONStopwatchGroupElement timer(fTimers,"MUON",Form("%s::Digits2Clusters(const AliMUONVDigitStore&,AliMUONVClusterStore&)",
162 fClusterReconstructor->ClassName()));
163 fClusterReconstructor->Digits2Clusters(digitStore,clusterStore);
166 //_____________________________________________________________________________
167 AliMUONVClusterStore*
168 AliMUONReconstructor::ClusterStore() const
170 /// Return (and create if necessary) the cluster container
173 fClusterStore = new AliMUONClusterStoreV1;
175 return fClusterStore;
178 //_____________________________________________________________________________
180 AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader,
181 AliMUONVDigitStore* digitStore,
182 AliMUONVTriggerStore* triggerStore) const
184 /// Convert raw data into digit and trigger stores
186 AliMUONStopwatchGroupElement timer(fTimers,"MUON",Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)",
187 fDigitMaker->ClassName()));
188 fDigitMaker->Raw2Digits(rawReader,digitStore,triggerStore);
189 Calibrate(*digitStore);
192 //_____________________________________________________________________________
194 AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const
196 /// convert raw data into a digit tree
198 Bool_t alone = ( TriggerStore() == 0 );
200 Bool_t ok = DigitStore()->Connect(*digitsTree,alone);
201 if ( TriggerStore() )
203 ok = ok && TriggerStore()->Connect(*digitsTree,kFALSE);
208 AliError("Could not make branches on TreeD");
212 ConvertDigits(rawReader,DigitStore(),TriggerStore());
214 DigitStore()->Clear();
218 //_____________________________________________________________________________
219 AliMUONTriggerCrateStore*
220 AliMUONReconstructor::CrateManager() const
222 /// Return (and create if necessary) the trigger crate store
223 if (fCrateManager) return fCrateManager;
224 fCrateManager = new AliMUONTriggerCrateStore;
225 fCrateManager->ReadFromFile();
226 return fCrateManager;
229 //_____________________________________________________________________________
231 AliMUONReconstructor::CreateDigitMaker() const
233 /// Create (and create if necessary) the digit maker
234 if (fDigitMaker) return;
236 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::CreateDigitMaker()");
238 fDigitMaker = new AliMUONDigitMaker;
241 //_____________________________________________________________________________
243 AliMUONReconstructor::CreateTriggerCircuit() const
245 /// Return (and create if necessary) the trigger circuit object
246 if (fTriggerCircuit) return;
248 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::CreateTriggerCircuit()");
250 fTriggerCircuit = new AliMUONTriggerCircuit(fTransformer);
253 //_____________________________________________________________________________
255 AliMUONReconstructor::CreateTracker(AliRunLoader* runLoader) const
257 /// Create the MUONTracker object
258 /// The MUONTracker is passed the GetOption(), i.e. our own options
260 CreateTriggerCircuit();
263 AliLoader* loader = runLoader->GetDetectorLoader("MUON");
266 AliError("Cannot get MUONLoader, so cannot create MUONTracker");
269 AliMUONTracker* tracker = new AliMUONTracker(loader,fDigitMaker,fTransformer,fTriggerCircuit);
270 tracker->SetOption(GetOption());
275 //_____________________________________________________________________________
277 AliMUONReconstructor::CreateClusterReconstructor() const
279 /// Create cluster reconstructor, depending on GetOption()
281 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::CreateClusterReconstructor()");
285 AliMUONVClusterFinder* clusterFinder(0x0);
287 TString opt(GetOption());
290 if ( strstr(opt,"PRECLUSTER") )
292 clusterFinder = new AliMUONPreClusterFinder;
294 else if ( strstr(opt,"COG") )
296 clusterFinder = new AliMUONClusterFinderCOG;
298 else if ( strstr(opt,"SIMPLEFIT") )
300 clusterFinder = new AliMUONClusterFinderSimpleFit;
302 else if ( strstr(opt,"MLEM:DRAW") )
304 clusterFinder = new AliMUONClusterFinderMLEM(kTRUE);
306 else if ( strstr(opt,"MLEM") )
308 clusterFinder = new AliMUONClusterFinderMLEM(kFALSE);
310 else if ( strstr(opt,"AZ") )
312 clusterFinder = new AliMUONClusterFinderAZ;
316 clusterFinder = new AliMUONClusterFinderAZ;
321 AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
324 fClusterReconstructor = new AliMUONClusterReconstructor(clusterFinder,fTransformer);
327 //_____________________________________________________________________________
329 AliMUONReconstructor::CreateCalibrator() const
331 /// Create the calibrator
333 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::CreateCalibrator()");
335 Int_t runNumber = AliCDBManager::Instance()->GetRun();
337 AliInfo("Calibration will occur.");
339 fCalibrationData = new AliMUONCalibrationData(runNumber);
340 if ( !fCalibrationData->IsValid() )
342 AliError("Could not retrieve calibrations !");
343 delete fCalibrationData;
344 fCalibrationData = 0x0;
348 // Check that we get all the calibrations we'll need
349 if ( !fCalibrationData->Pedestals() ||
350 !fCalibrationData->Gains() ||
351 !fCalibrationData->HV() )
353 AliFatal("Could not access all required calibration data");
356 TString opt(GetOption());
358 Bool_t statusMap(kTRUE);
360 if ( strstr(opt,"NOSTATUSMAP") )
362 AliWarning("Disconnecting status map : SHOULD BE USED FOR DEBUG ONLY. NOT FOR PRODUCTION !!!");
365 fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,statusMap);
368 //_____________________________________________________________________________
370 AliMUONReconstructor::DigitStore() const
372 /// Return (and create if necessary) the digit container
375 fDigitStore = new AliMUONDigitStoreV1;
380 //_____________________________________________________________________________
382 AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore,
383 AliMUONVClusterStore* clusterStore,
384 TTree& clustersTree) const
386 /// Write the trigger and cluster information into TreeR
388 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::FillTreeR()");
395 Bool_t alone = ( clusterStore ? kFALSE : kTRUE );
396 ok = triggerStore->Connect(clustersTree,alone);
399 AliError("Could not create triggerStore branches in TreeR");
405 Bool_t alone = ( triggerStore ? kFALSE : kTRUE );
406 ok = clusterStore->Connect(clustersTree,alone);
409 AliError("Could not create triggerStore branches in TreeR");
413 if (ok) // at least one type of branches created successfully
419 //_____________________________________________________________________________
421 AliMUONReconstructor::HasDigitConversion() const
423 /// We *do* have digit conversion, but we might advertise it only
424 /// if we want to save the digits.
426 TString opt(GetOption());
428 if ( opt.Contains("SAVEDIGITS" ) && !opt.Contains("NOLOCALRECONSTRUCTION") )
438 //_____________________________________________________________________________
440 AliMUONReconstructor::HasLocalReconstruction() const
442 /// Whether or not we have local reconstruction
443 TString opt(GetOption());
445 if ( opt.Contains("NOLOCALRECONSTRUCTION" ) )
455 //_____________________________________________________________________________
457 AliMUONReconstructor::Reconstruct(AliRawReader* rawReader, TTree* clustersTree) const
459 /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE AND
460 /// HasDigitConversion()==kFALSE
464 AliError("clustersTree is 0x0 !");
470 ConvertDigits(rawReader,DigitStore(),TriggerStore());
471 Clusterize(*(DigitStore()),*(ClusterStore()));
474 FillTreeR(TriggerStore(),ClusterStore(),*clustersTree);
477 //_____________________________________________________________________________
479 AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const
481 /// Reconstruct simulated data
483 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::Reconstruct(AliRunLoader*)");
485 AliLoader* loader = runLoader->GetDetectorLoader("MUON");
488 AliError("Could not get MUON loader");
492 Int_t nEvents = runLoader->GetNumberOfEvents();
494 for ( Int_t i = 0; i < nEvents; ++i )
496 runLoader->GetEvent(i);
498 loader->LoadRecPoints("update");
499 loader->CleanRecPoints();
500 loader->MakeRecPointsContainer();
501 TTree* clustersTree = loader->TreeR();
503 loader->LoadDigits("read");
504 TTree* digitsTree = loader->TreeD();
506 Reconstruct(digitsTree,clustersTree);
508 loader->UnloadDigits();
509 loader->WriteRecPoints("OVERWRITE");
510 loader->UnloadRecPoints();
514 //_____________________________________________________________________________
516 AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, AliRawReader* rawReader) const
518 /// This method is called by AliReconstruction if HasLocalReconstruction()==kFALSE
520 AliMUONStopwatchGroupElement timer(fTimers,"MUON","AliMUONReconstructor::Reconstruct(AliRunLoader*, AliRawReader*)");
522 AliLoader* loader = runLoader->GetDetectorLoader("MUON");
525 AliError("Could not get MUON loader");
531 while (rawReader->NextEvent())
533 runLoader->GetEvent(i++);
535 loader->LoadRecPoints("update");
536 loader->CleanRecPoints();
537 loader->MakeRecPointsContainer();
538 TTree* clustersTree = loader->TreeR();
540 loader->LoadDigits("update");
541 loader->CleanDigits();
542 loader->MakeDigitsContainer();
543 TTree* digitsTree = loader->TreeD();
544 ConvertDigits(rawReader, digitsTree);
545 loader->WriteDigits("OVERWRITE");
547 Reconstruct(digitsTree,clustersTree);
549 loader->UnloadDigits();
550 loader->WriteRecPoints("OVERWRITE");
551 loader->UnloadRecPoints();
555 //_____________________________________________________________________________
557 AliMUONReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const
559 /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE
560 /// AND HasDigitConversion()==kTRUE
564 if (!digitsTree || !clustersTree)
566 AliError(Form("Tree is null : digitsTree=%p clustersTree=%p",
567 digitsTree,clustersTree));
573 fDigitStore = AliMUONVDigitStore::Create(*digitsTree);
576 AliError(Form("Could not get DigitStore from %s",digitsTree->GetName()));
580 AliInfo(Form("Created %s from %s",fDigitStore->ClassName(),digitsTree->GetName()));
585 fTriggerStore = AliMUONVTriggerStore::Create(*digitsTree);
588 AliError(Form("Could not get TriggerStore from %s",digitsTree->GetName()));
592 AliInfo(Form("Created %s from %s",fTriggerStore->ClassName(),digitsTree->GetName()));
596 if (!fTriggerStore && !fDigitStore)
598 AliError("No store at all. Nothing to do.");
602 // insure we start with empty stores
605 fDigitStore->Clear();
606 Bool_t alone = ( fTriggerStore ? kFALSE : kTRUE );
607 Bool_t ok = fDigitStore->Connect(*digitsTree,alone);
610 AliError("Could not connect digitStore to digitsTree");
616 fTriggerStore->Clear();
617 Bool_t alone = ( fDigitStore ? kFALSE : kTRUE );
618 Bool_t ok = fTriggerStore->Connect(*digitsTree,alone);
621 AliError("Could not connect triggerStore to digitsTree");
626 digitsTree->GetEvent(0);
630 Clusterize(*fDigitStore,*(ClusterStore()));
633 FillTreeR(fTriggerStore,ClusterStore(),*clustersTree);
636 //_____________________________________________________________________________
637 AliMUONVTriggerStore*
638 AliMUONReconstructor::TriggerStore() const
640 /// Return (and create if necessary and allowed) the trigger container
641 TString sopt(GetOption());
644 if (sopt.Contains("TRIGGERDISABLE"))
646 delete fTriggerStore;
653 fTriggerStore = new AliMUONTriggerStoreV1;
656 return fTriggerStore;