Line data Source code
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 through the
23 : /// AliMUONRecoParam object set in the reconstruction macro or read from the CDB
24 : /// (see methods in AliMUONRecoParam.h file for details)
25 : ///
26 : /// Valid modes are :
27 : ///
28 : /// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer
29 : ///
30 : /// SIMPLEFITV3 : SIMPLEFIT with preclustering=PRECLUSTERV3
31 : ///
32 : /// MLEM : use AliMUONClusterFinderMLEM and AliMUONPreClusterFinder for preclustering (default)
33 : /// MLEMV2 : MLEM with preclustering=PRECLUSTERV2
34 : /// MLEMV3 : MLEM with preclustering=PRECLUSTERV3
35 : ///
36 : /// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as
37 : /// the produced clusters do not have a position, hence the tracking will not
38 : /// work
39 : /// PRECLUSTERV2 : another version of the preclustering
40 : /// PRECLUSTERV3 : yet another version of the preclustering
41 : ///
42 : /// COG : use AliMUONClusterFinderCOG clusterizer. Not really a production
43 : /// option either, as center-of-gravity is generally not a good estimate
44 : /// of the cluster position...
45 : ///
46 : /// PEAKCOG : COG cluster finder around local maxima
47 : /// PEAKFIT : fit around local maxima with up to 3 peaks, COG otherwise
48 : ///
49 : /// NOCLUSTERING : bypass completely the clustering stage
50 : ///
51 : /// ------
52 : ///
53 : /// The behavior of the MUON reconstruction can also be changed, besides
54 : /// the usual methods found in AliReconstruction (e.g. to disable tracking)
55 : /// by using AliReconstruction::SetOption("MUON",options)
56 : /// where options should be a space separated string.
57 : ///
58 : /// Valid options are :
59 : ///
60 : /// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits
61 : /// that are used for the clustering
62 : ///
63 : /// DIGITSTOREV1 : use the V1 implementation of the digitstore
64 : /// DIGITSTOREV2R : use the V2R implementation of the digitstore
65 : ///
66 : /// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence
67 : /// "recover" old behavior)
68 : ///
69 : /// TRIGGERDISABLE : disable the treatment of MUON trigger
70 : ///
71 : /// ENABLEERRORLOGGING : enable error logging (this activates also warnings in RawStreamTracker)
72 : ///
73 : /// \author Laurent Aphecetche, Subatech
74 : //-----------------------------------------------------------------------------
75 :
76 : #include "AliMUONReconstructor.h"
77 :
78 : #include "AliMUONCalibrationData.h"
79 : #include "AliMUONClusterFinderCOG.h"
80 : #include "AliMUONClusterFinderMLEM.h"
81 : #include "AliMUONClusterFinderSimpleFit.h"
82 : #include "AliMUONClusterFinderPeakCOG.h"
83 : #include "AliMUONClusterFinderPeakFit.h"
84 : #include "AliMUONClusterStoreV1.h"
85 : #include "AliMUONClusterStoreV2.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 "AliMUONPadStatusMaker.h"
93 : #include "AliMUONPreClusterFinder.h"
94 : #include "AliMUONPreClusterFinderV2.h"
95 : #include "AliMUONPreClusterFinderV3.h"
96 : #include "AliMUONSimpleClusterServer.h"
97 : #include "AliMUONTracker.h"
98 : #include "AliMUONTriggerCircuit.h"
99 : #include "AliMUONTriggerStoreV1.h"
100 : #include "AliMUONVClusterFinder.h"
101 : #include "AliMUONVClusterServer.h"
102 : #include "AliMUONVTrackStore.h"
103 : #include "AliMUONTriggerElectronics.h"
104 : #include "AliMUONTriggerUtilities.h"
105 :
106 : #include "AliMpArea.h"
107 : #include "AliMpCDB.h"
108 : #include "AliMpConstants.h"
109 : #include "AliMpDDLStore.h"
110 : #include "AliMpSegmentation.h"
111 :
112 : #include "AliRawReader.h"
113 : #include "AliCDBManager.h"
114 : #include "AliCodeTimer.h"
115 : #include "AliLog.h"
116 : #include "AliRunInfo.h"
117 :
118 : #include <Riostream.h>
119 : #include <TObjArray.h>
120 : #include <TClonesArray.h>
121 : #include <TString.h>
122 : #include <TTree.h>
123 :
124 : /// \cond CLASSIMP
125 18 : ClassImp(AliMUONReconstructor)
126 : /// \endcond
127 :
128 : //_____________________________________________________________________________
129 : AliMUONReconstructor::AliMUONReconstructor() :
130 2 : AliReconstructor(),
131 2 : fDigitMaker(0x0),
132 6 : fTransformer(new AliMUONGeometryTransformer()),
133 2 : fDigitStore(0x0),
134 2 : fTriggerCircuit(0x0),
135 2 : fCalibrationData(0x0),
136 2 : fDigitCalibrator(0x0),
137 2 : fTriggerStore(0x0),
138 2 : fTrackStore(0x0),
139 2 : fClusterStore(0x0),
140 2 : fTriggerProcessor(0x0),
141 2 : fTriggerUtilities(0x0),
142 2 : fClusterServers(),
143 2 : fTrackers(),
144 2 : fShouldCalibrate(kTRUE)
145 10 : {
146 : /// normal ctor
147 :
148 10 : AliDebug(1,"");
149 :
150 : // Unload mapping objects
151 : // if they have been loaded from the obsolete OCDB mapping objects
152 :
153 4 : if ( AliMpDDLStore::Instance(false) ) {
154 0 : AliCDBManager::Instance()->UnloadFromCache("MUON/Calib/DDLStore");
155 0 : delete AliMpDDLStore::Instance();
156 : }
157 :
158 4 : if ( AliMpSegmentation::Instance(false) ) {
159 0 : AliCDBManager::Instance()->UnloadFromCache("MUON/Calib/Mapping");
160 0 : delete AliMpSegmentation::Instance();
161 : }
162 :
163 : // Load mapping
164 4 : if ( ! AliMpCDB::LoadDDLStore() ) {
165 0 : AliFatal("Could not access mapping from OCDB !");
166 : }
167 :
168 : // Load geometry data
169 2 : fTransformer->LoadGeometryData();
170 :
171 2 : fClusterServers.SetOwner(kTRUE);
172 2 : fTrackers.SetOwner(kTRUE);
173 4 : }
174 :
175 : //_____________________________________________________________________________
176 : AliMUONReconstructor::~AliMUONReconstructor()
177 12 : {
178 : /// dtor
179 :
180 10 : AliDebug(1,"");
181 :
182 4 : delete fDigitCalibrator;
183 :
184 3 : delete fDigitMaker;
185 4 : delete fDigitStore;
186 4 : delete fTransformer;
187 4 : delete fTriggerCircuit;
188 4 : delete fTriggerStore;
189 2 : delete fTrackStore;
190 4 : delete fClusterStore;
191 4 : delete fTriggerProcessor;
192 4 : delete fTriggerUtilities;
193 :
194 6 : delete AliMpSegmentation::Instance(false);
195 6 : delete AliMpDDLStore::Instance(false);
196 :
197 4 : delete fCalibrationData;
198 6 : }
199 :
200 : //_____________________________________________________________________________
201 : void
202 : AliMUONReconstructor::Calibrate(AliMUONVDigitStore& digitStore) const
203 : {
204 : /// Calibrate the digitStore
205 16 : if (!fDigitCalibrator)
206 : {
207 2 : CreateCalibrator();
208 2 : }
209 :
210 8 : if ( fShouldCalibrate )
211 : {
212 8 : AliCodeTimerAuto(Form("%s::Calibrate(AliMUONVDigitStore*)",fDigitCalibrator->ClassName()),0)
213 8 : fDigitCalibrator->Calibrate(digitStore);
214 8 : }
215 8 : }
216 :
217 : //_____________________________________________________________________________
218 : void
219 : AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader,
220 : AliMUONVDigitStore* digitStore,
221 : AliMUONVTriggerStore* triggerStore) const
222 : {
223 : /// Convert raw data into digit and trigger stores
224 8 : CreateDigitMaker();
225 :
226 : // Skip reconstruction if event is Calibration
227 4 : if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) {
228 0 : digitStore->Clear(); // Remove possible digits from previous event
229 0 : triggerStore->Clear(); // Remove possible triggers from previous event
230 0 : AliInfo("Calibration event: do not convert digits");
231 0 : return;
232 : }
233 :
234 4 : AliCodeTimerStart(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)",
235 : fDigitMaker->ClassName()))
236 4 : fDigitMaker->Raw2Digits(rawReader,digitStore,triggerStore);
237 4 : AliCodeTimerStop(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)",
238 : fDigitMaker->ClassName()))
239 4 : Calibrate(*digitStore);
240 8 : }
241 :
242 : //_____________________________________________________________________________
243 : void
244 : AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const
245 : {
246 : /// convert raw data into a digit tree
247 0 : AliCodeTimerAuto("",0)
248 :
249 0 : Bool_t alone = ( TriggerStore() == 0 );
250 :
251 0 : Bool_t ok = DigitStore()->Connect(*digitsTree,alone);
252 0 : if ( TriggerStore() )
253 : {
254 0 : ok = ok && TriggerStore()->Connect(*digitsTree,kFALSE);
255 0 : }
256 :
257 0 : if (!ok)
258 : {
259 0 : AliError("Could not make branches on TreeD");
260 : }
261 : else
262 : {
263 0 : ConvertDigits(rawReader,DigitStore(),TriggerStore());
264 0 : AliCodeTimerStart("Fill digits")
265 0 : digitsTree->Fill();
266 0 : AliCodeTimerStop("Fill digits")
267 0 : DigitStore()->Clear();
268 : }
269 0 : }
270 :
271 : //_____________________________________________________________________________
272 : void
273 : AliMUONReconstructor::CreateDigitMaker() const
274 : {
275 : /// Create (and create if necessary) the digit maker
276 8 : if (fDigitMaker) return;
277 :
278 1 : AliCodeTimerAuto("",0)
279 :
280 2 : TString option = GetOption();
281 :
282 : Bool_t enableErrorLogging = kFALSE;
283 :
284 2 : if (option.Contains("ENABLEERRORLOGGING"))
285 : {
286 : enableErrorLogging = kTRUE;
287 0 : }
288 :
289 3 : fDigitMaker = new AliMUONDigitMaker(enableErrorLogging);
290 1 : option.ToUpper();
291 :
292 : // Always make trigger digits
293 : // (needed when calculating trigger chamber efficiency)
294 1 : fDigitMaker->SetMakeTriggerDigits(kTRUE);
295 :
296 3 : if ( GetRecoParam()->TryRecover() )
297 : {
298 1 : fDigitMaker->SetTryRecover(kTRUE);
299 : }
300 : else
301 : {
302 1 : fDigitMaker->SetTryRecover(kFALSE);
303 : }
304 5 : }
305 :
306 : //_____________________________________________________________________________
307 : void
308 : AliMUONReconstructor::CreateTriggerCircuit() const
309 : {
310 : /// Return (and create if necessary) the trigger circuit object
311 16 : if (fTriggerCircuit) return;
312 :
313 2 : AliCodeTimerAuto("",0)
314 :
315 6 : fTriggerCircuit = new AliMUONTriggerCircuit(fTransformer);
316 :
317 10 : }
318 :
319 : //_____________________________________________________________________________
320 : void
321 : AliMUONReconstructor::CreateTriggerUtilities() const
322 : {
323 : /// Return (and create if necessary) the trigger utilities object
324 16 : if ( fTriggerUtilities ) return;
325 :
326 2 : AliCodeTimerAuto("",0)
327 :
328 2 : if ( ! fCalibrationData ) CreateCalibrationData();
329 :
330 6 : fTriggerUtilities = new AliMUONTriggerUtilities(fCalibrationData);
331 10 : }
332 :
333 : //_____________________________________________________________________________
334 : AliTracker*
335 : AliMUONReconstructor::CreateTracker() const
336 : {
337 : /// Create the MUONTracker object
338 :
339 16 : CreateTriggerCircuit();
340 8 : CreateTriggerUtilities();
341 :
342 8 : const AliMUONRecoParam* rp = GetRecoParam();
343 :
344 8 : Int_t es = rp->GetEventSpecie();
345 :
346 : AliTracker* tracker = 0X0;
347 :
348 8 : if ( es <= fTrackers.GetLast() )
349 : {
350 6 : tracker = static_cast<AliTracker*>(fTrackers.At(es));
351 6 : }
352 :
353 8 : if (!tracker )
354 : {
355 4 : if ( ! rp->CombineClusterTrackReco() )
356 : {
357 4 : tracker = new AliMUONTracker(rp,
358 : 0x0,
359 2 : *DigitStore(),
360 2 : fTransformer,
361 2 : fTriggerCircuit,
362 2 : fTriggerUtilities);
363 :
364 2 : AliInfo(Form("Created tracker %p for recoparam of type %s es=%d",
365 : tracker,
366 : AliRecoParam::GetEventSpecieName(AliRecoParam::Convert(rp->GetEventSpecie())),es));
367 2 : }
368 : else
369 : {
370 :
371 2 : tracker = new AliMUONTracker(rp,
372 0 : CreateClusterServer(*rp),
373 0 : *DigitStore(),
374 0 : fTransformer,
375 0 : fTriggerCircuit,
376 0 : fTriggerUtilities);
377 :
378 0 : AliInfo(Form("Created (combined) tracker %p for recoparam of type %s es=%d",
379 : tracker,
380 : AliRecoParam::GetEventSpecieName(AliRecoParam::Convert(rp->GetEventSpecie())),es));
381 : }
382 :
383 2 : fTrackers.AddAtAndExpand(tracker,es);
384 2 : }
385 :
386 :
387 8 : return tracker;
388 0 : }
389 :
390 : //_____________________________________________________________________________
391 : AliMUONVClusterFinder*
392 : AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType)
393 : {
394 : /// Create a given cluster finder instance
395 :
396 4 : AliCodeTimerAutoGeneral("",0)
397 :
398 : AliMUONVClusterFinder* clusterFinder(0x0);
399 :
400 2 : TString opt(clusterFinderType);
401 2 : opt.ToUpper();
402 :
403 6 : if ( strstr(opt,"PRECLUSTERV2") )
404 : {
405 0 : clusterFinder = new AliMUONPreClusterFinderV2;
406 0 : }
407 6 : else if ( strstr(opt,"PRECLUSTERV3") )
408 : {
409 0 : clusterFinder = new AliMUONPreClusterFinderV3;
410 0 : }
411 6 : else if ( strstr(opt,"PRECLUSTER") )
412 : {
413 0 : clusterFinder = new AliMUONPreClusterFinder;
414 0 : }
415 6 : else if ( strstr(opt,"PEAKCOG") )
416 : {
417 0 : clusterFinder = new AliMUONClusterFinderPeakCOG(kFALSE,new AliMUONPreClusterFinder);
418 0 : }
419 6 : else if ( strstr(opt,"PEAKFIT") )
420 : {
421 0 : clusterFinder = new AliMUONClusterFinderPeakFit(kFALSE,new AliMUONPreClusterFinder);
422 0 : }
423 6 : else if ( strstr(opt,"COG") )
424 : {
425 0 : clusterFinder = new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder);
426 0 : }
427 6 : else if ( strstr(opt,"SIMPLEFITV3") )
428 : {
429 0 : clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3));
430 0 : }
431 6 : else if ( strstr(opt,"SIMPLEFIT") )
432 : {
433 0 : clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder));
434 0 : }
435 6 : else if ( strstr(opt,"MLEM:DRAW") )
436 : {
437 0 : clusterFinder = new AliMUONClusterFinderMLEM(kTRUE,new AliMUONPreClusterFinder);
438 0 : }
439 6 : else if ( strstr(opt,"MLEMV3") )
440 : {
441 0 : clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV3);
442 0 : }
443 6 : else if ( strstr(opt,"MLEMV2") )
444 : {
445 0 : clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV2);
446 0 : }
447 6 : else if ( strstr(opt,"MLEM") )
448 : {
449 10 : clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinder);
450 : }
451 : else
452 : {
453 0 : AliErrorClass(Form("clustering mode \"%s\" does not exist",opt.Data()));
454 0 : return 0x0;
455 : }
456 :
457 2 : return clusterFinder;
458 2 : }
459 :
460 : //_____________________________________________________________________________
461 : AliMUONVClusterServer*
462 : AliMUONReconstructor::CreateClusterServer(const AliMUONRecoParam& rp) const
463 : {
464 : /// Create cluster server
465 :
466 16 : AliCodeTimerAuto("",0);
467 :
468 : AliMUONVClusterServer* clusterServer = 0x0;
469 :
470 16 : if (rp.GetEventSpecie() <= fClusterServers.GetLast() )
471 : {
472 12 : clusterServer = static_cast<AliMUONVClusterServer*>(fClusterServers.At(rp.GetEventSpecie()));
473 6 : }
474 :
475 8 : if (!clusterServer )
476 : {
477 4 : AliMUONVClusterFinder* clusterFinder = CreateClusterFinder(rp.GetClusteringMode());
478 :
479 2 : if ( !clusterFinder ) return 0x0;
480 :
481 6 : clusterServer = new AliMUONSimpleClusterServer(clusterFinder,*fTransformer);
482 :
483 10 : AliInfo(Form("Created AliMUONSimpleClusterServer (%p) for specie %d with clustering = %s (following requesting clustering mode %s)",
484 : clusterServer,rp.GetEventSpecie(),clusterFinder->ClassName(),rp.GetClusteringMode()));
485 :
486 2 : fClusterServers.AddAtAndExpand(clusterServer,rp.GetEventSpecie());
487 2 : }
488 :
489 8 : return clusterServer;
490 8 : }
491 :
492 : //_____________________________________________________________________________
493 : void
494 : AliMUONReconstructor::CreateCalibrationData() const
495 : {
496 : /// Create the calibrator
497 :
498 4 : AliCodeTimerAuto("",0);
499 :
500 4 : Int_t runNumber = AliCDBManager::Instance()->GetRun();
501 :
502 6 : fCalibrationData = new AliMUONCalibrationData(runNumber);
503 2 : if ( !fCalibrationData->IsValid() )
504 : {
505 0 : AliError("Could not retrieve calibrations !");
506 0 : delete fCalibrationData;
507 0 : fCalibrationData = 0x0;
508 0 : return;
509 : }
510 :
511 : // It is now time to check whether we have everything to proceed.
512 : // What we need depends on whether both tracker and trigger
513 : // are in the readout chain, and what specific "bad channel policy"
514 : // we use
515 :
516 : Bool_t kTracker(kFALSE);
517 : Bool_t kTrigger(kFALSE);
518 :
519 2 : const AliRunInfo* runInfo = GetRunInfo();
520 2 : if (!runInfo)
521 : {
522 0 : AliError("Could not get runinfo ?");
523 : }
524 : else
525 : {
526 4 : TString detectors(runInfo->GetActiveDetectors());
527 6 : if (detectors.Contains("MUONTRK")) kTracker=kTRUE;
528 6 : if (detectors.Contains("MUONTRG")) kTrigger=kTRUE;
529 2 : }
530 :
531 6 : AliInfo(Form("Run with MUON TRIGGER : %s and MUON TRACKER : %s",
532 : kTrigger ? "YES":"NO" ,
533 : kTracker ? "YES":"NO"));
534 :
535 2 : if ( kTracker )
536 : {
537 : // Check that we get all the calibrations we'll need
538 4 : if ( !fCalibrationData->Pedestals() )
539 : {
540 0 : AliFatal(Form("Could not access all required calibration data (PED %p)",
541 : fCalibrationData->Pedestals()));
542 : }
543 :
544 4 : if ( !fCalibrationData->HV() )
545 : {
546 : // Special treatment of HV. We only break if the values
547 : // are not there *AND* we cut on them.
548 0 : UInt_t mask = GetRecoParam()->PadGoodnessMask();
549 0 : TString smask(AliMUONPadStatusMaker::AsCondition(mask));
550 0 : if ( smask.Contains("HV") )
551 : {
552 0 : AliFatal("Could not access all required calibration data (HV)");
553 : }
554 0 : }
555 : }
556 4 : }
557 :
558 : //_____________________________________________________________________________
559 : void
560 : AliMUONReconstructor::CreateCalibrator() const
561 : {
562 : /// Create the calibrator
563 :
564 4 : AliCodeTimerAuto("",0);
565 :
566 2 : if ( ! fCalibrationData )
567 2 : CreateCalibrationData();
568 :
569 4 : AliInfo("Calibration will occur.");
570 :
571 4 : TString opt(GetOption());
572 2 : opt.ToUpper();
573 :
574 6 : if ( strstr(opt,"NOSTATUSMAP") )
575 : {
576 0 : AliWarning("NOSTATUSMAP is obsolete");
577 : }
578 :
579 : Bool_t kTracker(kFALSE);
580 :
581 2 : const AliRunInfo* runInfo = GetRunInfo();
582 2 : if (!runInfo)
583 : {
584 0 : AliError("Could not get runinfo ?");
585 : }
586 : else
587 : {
588 4 : TString detectors(runInfo->GetActiveDetectors());
589 6 : if (detectors.Contains("MUONTRK")) kTracker=kTRUE;
590 2 : }
591 :
592 2 : if ( kTracker )
593 : {
594 8 : fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,GetRecoParam());
595 2 : }
596 : else
597 : {
598 0 : AliWarning("Apparently running without MCH so will not instantiante the DigitCalibrator nor read MCH OCDB objects...");
599 0 : fShouldCalibrate=kFALSE;
600 : }
601 2 : }
602 :
603 : //_____________________________________________________________________________
604 : void
605 : AliMUONReconstructor::ResponseRemovingChambers(AliMUONVTriggerStore* triggerStore) const
606 : {
607 : /// Update trigger information with informatins obtained after
608 : /// re-calculation of trigger response
609 16 : AliCodeTimerAuto("",0);
610 :
611 8 : if ( ! fCalibrationData )
612 0 : CreateCalibrationData();
613 :
614 8 : if ( ! fTriggerProcessor )
615 6 : fTriggerProcessor = new AliMUONTriggerElectronics(fCalibrationData);
616 :
617 8 : fTriggerProcessor->ResponseRemovingChambers(*triggerStore);
618 8 : }
619 :
620 : //_____________________________________________________________________________
621 : AliMUONVDigitStore*
622 : AliMUONReconstructor::DigitStore() const
623 : {
624 : /// Return (and create if necessary) the digit container
625 44 : if (!fDigitStore)
626 : {
627 1 : TString sopt(GetOption());
628 1 : sopt.ToUpper();
629 :
630 4 : AliInfo(Form("Options=%s",sopt.Data()));
631 :
632 2 : if ( sopt.Contains("DIGITSTOREV1") )
633 : {
634 0 : fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV1");
635 0 : }
636 2 : else if ( sopt.Contains("DIGITSTOREV2R") )
637 : {
638 0 : fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
639 0 : }
640 2 : else if ( sopt.Contains("DIGITSTOREV2S") )
641 : {
642 0 : fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2S");
643 0 : }
644 :
645 3 : if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
646 :
647 4 : AliInfo(Form("Will use %s to store digits during reconstruction",fDigitStore->ClassName()));
648 1 : }
649 22 : return fDigitStore;
650 0 : }
651 :
652 : //_____________________________________________________________________________
653 : void
654 : AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore,
655 : TTree& clustersTree) const
656 : {
657 : /// Write the trigger and cluster information into TreeR
658 :
659 16 : AliCodeTimerAuto("",0)
660 :
661 : Bool_t ok(kFALSE);
662 : Bool_t alone(kTRUE); // is trigger the only info in TreeR ?
663 :
664 8 : const AliMUONRecoParam* rp = GetRecoParam();
665 :
666 8 : if ( ! rp->CombineClusterTrackReco() )
667 : {
668 : alone = kFALSE; // we'll get both tracker and trigger information in TreeR
669 8 : }
670 :
671 8 : if ( triggerStore )
672 : {
673 8 : ResponseRemovingChambers(triggerStore);
674 16 : ok = triggerStore->Connect(clustersTree,alone);
675 8 : if (!ok)
676 : {
677 0 : AliError("Could not create triggerStore branches in TreeR");
678 : }
679 : }
680 :
681 8 : if ( !alone )
682 : {
683 8 : if (!fClusterStore)
684 : {
685 6 : fClusterStore = new AliMUONClusterStoreV2;
686 2 : }
687 :
688 8 : AliMUONVClusterServer* clusterServer = CreateClusterServer(*rp);
689 :
690 24 : TIter next(DigitStore()->CreateIterator());
691 16 : clusterServer->UseDigits(next,DigitStore());
692 :
693 8 : AliMpArea area;
694 :
695 40 : AliDebug(1,Form("Doing full clusterization in local reconstruction using %s ",clusterServer->ClassName()));
696 :
697 176 : for ( Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i )
698 : {
699 80 : if (rp->UseChamber(i))
700 : {
701 112 : if ( ( i == 6 || i == 7 ) && rp->BypassSt4() ) continue;
702 96 : if ( ( i == 8 || i == 9 ) && rp->BypassSt5() ) continue;
703 :
704 80 : clusterServer->Clusterize(i,*fClusterStore,area,rp);
705 : }
706 : }
707 :
708 16 : Bool_t cok = fClusterStore->Connect(clustersTree,alone);
709 :
710 8 : if (!cok) AliError("Could not connect clusterStore to clusterTree");
711 :
712 40 : AliDebug(1,Form("Number of clusters found = %d",fClusterStore->GetSize()));
713 :
714 32 : StdoutToAliDebug(1,fClusterStore->Print());
715 8 : }
716 :
717 8 : if (ok) // at least one type of branches created successfully
718 : {
719 8 : clustersTree.Fill();
720 : }
721 :
722 16 : if (fClusterStore) fClusterStore->Clear();
723 8 : }
724 :
725 : //_____________________________________________________________________________
726 : const AliMUONRecoParam* AliMUONReconstructor::GetRecoParam()
727 : {
728 : /// Get the recoparam from reconstruction
729 92 : return dynamic_cast<const AliMUONRecoParam*>(AliReconstructor::GetRecoParam(AliReconstruction::GetDetIndex("MUON")));
730 : }
731 :
732 :
733 : //_____________________________________________________________________________
734 : Bool_t
735 : AliMUONReconstructor::HasDigitConversion() const
736 : {
737 : /// We *do* have digit conversion, but we might advertise it only
738 : /// if we want to save the digits.
739 :
740 24 : TString opt(GetOption());
741 12 : opt.ToUpper();
742 24 : if ( opt.Contains("SAVEDIGITS" ) && !opt.Contains("NOLOCALRECONSTRUCTION") )
743 : {
744 0 : return kTRUE;
745 : }
746 : else
747 : {
748 12 : return kFALSE;
749 : }
750 12 : }
751 :
752 : //_____________________________________________________________________________
753 : void
754 : AliMUONReconstructor::Reconstruct(AliRawReader* rawReader, TTree* clustersTree) const
755 : {
756 : /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE AND
757 : /// HasDigitConversion()==kFALSE
758 :
759 8 : if ( !clustersTree )
760 : {
761 0 : AliError("clustersTree is 0x0 !");
762 0 : return;
763 : }
764 :
765 4 : ConvertDigits(rawReader,DigitStore(),TriggerStore());
766 :
767 4 : FillTreeR(TriggerStore(),*clustersTree);
768 8 : }
769 :
770 : //_____________________________________________________________________________
771 : void
772 : AliMUONReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const
773 : {
774 : /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE
775 : /// AND HasDigitConversion()==kTRUE
776 :
777 8 : AliCodeTimerAuto("",0)
778 :
779 20 : AliDebug(1,"");
780 :
781 4 : if (!digitsTree || !clustersTree)
782 : {
783 0 : AliError(Form("Tree is null : digitsTree=%p clustersTree=%p",
784 : digitsTree,clustersTree));
785 0 : return;
786 : }
787 :
788 4 : if (!fDigitStore)
789 : {
790 2 : fDigitStore = AliMUONVDigitStore::Create(*digitsTree);
791 1 : if (!fDigitStore)
792 : {
793 0 : AliError(Form("Could not get DigitStore from %s",digitsTree->GetName()));
794 : }
795 : else
796 : {
797 5 : AliInfo(Form("Created %s from %s",fDigitStore->ClassName(),digitsTree->GetName()));
798 : }
799 : }
800 4 : if (!fTriggerStore)
801 : {
802 2 : fTriggerStore = AliMUONVTriggerStore::Create(*digitsTree);
803 1 : if (!fTriggerStore)
804 : {
805 0 : AliError(Form("Could not get TriggerStore from %s",digitsTree->GetName()));
806 : }
807 : else
808 : {
809 5 : AliInfo(Form("Created %s from %s",fTriggerStore->ClassName(),digitsTree->GetName()));
810 : }
811 : }
812 :
813 4 : if (!fTriggerStore && !fDigitStore)
814 : {
815 0 : AliError("No store at all. Nothing to do.");
816 0 : return;
817 : }
818 :
819 : // insure we start with empty stores
820 4 : if ( fDigitStore )
821 : {
822 4 : fDigitStore->Clear();
823 4 : Bool_t alone = ( fTriggerStore ? kFALSE : kTRUE );
824 8 : Bool_t ok = fDigitStore->Connect(*digitsTree,alone);
825 4 : if (!ok)
826 : {
827 0 : AliError("Could not connect digitStore to digitsTree");
828 0 : return;
829 : }
830 4 : }
831 4 : if ( fTriggerStore )
832 : {
833 4 : fTriggerStore->Clear();
834 4 : Bool_t alone = ( fDigitStore ? kFALSE : kTRUE );
835 8 : Bool_t ok = fTriggerStore->Connect(*digitsTree,alone);
836 4 : if (!ok)
837 : {
838 0 : AliError("Could not connect triggerStore to digitsTree");
839 0 : return;
840 : }
841 4 : }
842 :
843 4 : digitsTree->GetEvent(0);
844 :
845 4 : if ( fDigitStore )
846 : {
847 : // Insure we got calibrated digits (if we reconstruct from pure simulated,
848 : // i.e. w/o going through raw data, this will be the case)
849 8 : TIter next(fDigitStore->CreateIterator());
850 8 : AliMUONVDigit* digit = static_cast<AliMUONVDigit*>(next());
851 12 : if (digit && !digit->IsCalibrated())
852 : {
853 4 : Calibrate(*fDigitStore);
854 : }
855 4 : }
856 :
857 4 : FillTreeR(fTriggerStore,*clustersTree);
858 8 : }
859 :
860 : //_____________________________________________________________________________
861 : AliMUONVTriggerStore*
862 : AliMUONReconstructor::TriggerStore() const
863 : {
864 : /// Return (and create if necessary and allowed) the trigger container
865 16 : TString sopt(GetOption());
866 8 : sopt.ToUpper();
867 :
868 16 : if (sopt.Contains("TRIGGERDISABLE"))
869 : {
870 8 : delete fTriggerStore;
871 0 : fTriggerStore = 0x0;
872 0 : }
873 : else
874 : {
875 8 : if (!fTriggerStore)
876 : {
877 3 : fTriggerStore = new AliMUONTriggerStoreV1;
878 1 : }
879 : }
880 8 : return fTriggerStore;
881 8 : }
|