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