X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONReconstructor.cxx;h=561c78ad9d767f83dfd4c47ed55ccc4f1b5dc035;hb=09cd3cd002cc0594e742971fab6f95c6a69dac0e;hp=ec99f783ae0a7f185f8ae605f8d746113f7de079;hpb=6a518391867356ca3f338b42cf561dcc348d9e16;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONReconstructor.cxx b/MUON/AliMUONReconstructor.cxx index ec99f783ae0..561c78ad9d7 100644 --- a/MUON/AliMUONReconstructor.cxx +++ b/MUON/AliMUONReconstructor.cxx @@ -14,594 +14,833 @@ **************************************************************************/ /* $Id$ */ -//----------------------------- -// Class AliMUONReconstructor -//----------------------------- -// Class for the -// MUON track reconstruction +//----------------------------------------------------------------------------- +/// \class AliMUONReconstructor +/// +/// Implementation of AliReconstructor for MUON subsystem. +/// +/// The clustering mode and the associated parameters can be changed through the +/// AliMUONRecoParam object set in the reconstruction macro or read from the CDB +/// (see methods in AliMUONRecoParam.h file for details) +/// +/// Valid modes are : +/// +/// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer +/// +/// SIMPLEFITV3 : SIMPLEFIT with preclustering=PRECLUSTERV3 +/// +/// MLEM : use AliMUONClusterFinderMLEM and AliMUONPreClusterFinder for preclustering (default) +/// MLEMV2 : MLEM with preclustering=PRECLUSTERV2 +/// MLEMV3 : MLEM with preclustering=PRECLUSTERV3 +/// +/// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as +/// the produced clusters do not have a position, hence the tracking will not +/// work +/// PRECLUSTERV2 : another version of the preclustering +/// PRECLUSTERV3 : yet another version of the preclustering +/// +/// COG : use AliMUONClusterFinderCOG clusterizer. Not really a production +/// option either, as center-of-gravity is generally not a good estimate +/// of the cluster position... +/// +/// PEAKCOG : COG cluster finder around local maxima +/// PEAKFIT : fit around local maxima with up to 3 peaks, COG otherwise +/// +/// NOCLUSTERING : bypass completely the clustering stage +/// +/// ------ +/// +/// The behavior of the MUON reconstruction can also be changed, besides +/// the usual methods found in AliReconstruction (e.g. to disable tracking) +/// by using AliReconstruction::SetOption("MUON",options) +/// where options should be a space separated string. +/// +/// Valid options are : +/// +/// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits +/// that are used for the clustering +/// +/// DIGITSTOREV1 : use the V1 implementation of the digitstore +/// DIGITSTOREV2R : use the V2R implementation of the digitstore +/// +/// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence +/// "recover" old behavior) +/// +/// TRIGGERDISABLE : disable the treatment of MUON trigger +/// +/// ENABLEERRORLOGGING : enable error logging (this activates also warnings in RawStreamTracker) +/// +/// \author Laurent Aphecetche, Subatech +//----------------------------------------------------------------------------- #include "AliMUONReconstructor.h" -#include "AliESD.h" -#include "AliESDMuonTrack.h" -#include "AliLog.h" -#include "AliMUONConstants.h" #include "AliMUONCalibrationData.h" -#include "AliMUONClusterFinderAZ.h" -#include "AliMUONClusterReconstructor.h" -#include "AliMUONData.h" +#include "AliMUONClusterFinderCOG.h" +#include "AliMUONClusterFinderMLEM.h" +#include "AliMUONClusterFinderSimpleFit.h" +#include "AliMUONClusterFinderPeakCOG.h" +#include "AliMUONClusterFinderPeakFit.h" +#include "AliMUONClusterStoreV1.h" +#include "AliMUONClusterStoreV2.h" +#include "AliMUONConstants.h" #include "AliMUONDigitCalibrator.h" -#include "AliMUONEventRecoCombi.h" #include "AliMUONDigitMaker.h" -#include "AliMUONTrack.h" -#include "AliMUONTrackParam.h" -#include "AliMUONTrackExtrap.h" -#include "AliMUONVTrackReconstructor.h" -#include "AliMUONTrackReconstructor.h" -#include "AliMUONTrackReconstructorK.h" -#include "AliMUONTriggerTrack.h" +#include "AliMUONDigitStoreV1.h" +#include "AliMUONDigitStoreV2R.h" +#include "AliMUONGeometryTransformer.h" +#include "AliMUONPadStatusMaker.h" +#include "AliMUONPreClusterFinder.h" +#include "AliMUONPreClusterFinderV2.h" +#include "AliMUONPreClusterFinderV3.h" +#include "AliMUONSimpleClusterServer.h" +#include "AliMUONTracker.h" #include "AliMUONTriggerCircuit.h" -#include "AliMUONTriggerCrateStore.h" -#include "AliMUONSegFactory.h" -#include "AliMUONSegmentation.h" - +#include "AliMUONTriggerStoreV1.h" +#include "AliMUONVClusterFinder.h" +#include "AliMUONVClusterServer.h" +#include "AliMUONVTrackStore.h" +#include "AliMUONTriggerElectronics.h" +#include "AliMUONTriggerUtilities.h" + +#include "AliMpArea.h" +#include "AliMpCDB.h" +#include "AliMpConstants.h" +#include "AliMpDDLStore.h" #include "AliMpSegmentation.h" -#include "AliMUONPreClusterFinder.h" -#include "AliMUONClusterFinderCOG.h" -#include "AliMUONClusterFinderSimpleFit.h" -#include "AliMUONClusterFinderMLEM.h" - #include "AliRawReader.h" -#include "AliRun.h" -#include "AliRunLoader.h" -#include "TTask.h" -#include "TStopwatch.h" +#include "AliCDBManager.h" +#include "AliCodeTimer.h" +#include "AliLog.h" +#include "AliRunInfo.h" + +#include +#include +#include +#include +#include /// \cond CLASSIMP ClassImp(AliMUONReconstructor) -/// \endcond +/// \endcond //_____________________________________________________________________________ -AliMUONReconstructor::AliMUONReconstructor() - : AliReconstructor(), - fRunLoader(0x0), - fDigitMaker(new AliMUONDigitMaker()), - fCalibrationData(0x0), - fCrateManager(new AliMUONTriggerCrateStore()), - fTriggerCircuit(new TClonesArray("AliMUONTriggerCircuit", 234)), - fTransformer(new AliMUONGeometryTransformer(kTRUE)), - fSegmentation(0x0) - +AliMUONReconstructor::AliMUONReconstructor() : +AliReconstructor(), +fDigitMaker(0x0), +fTransformer(new AliMUONGeometryTransformer()), +fDigitStore(0x0), +fTriggerCircuit(0x0), +fCalibrationData(0x0), +fDigitCalibrator(0x0), +fTriggerStore(0x0), +fTrackStore(0x0), +fClusterStore(0x0), +fTriggerProcessor(0x0), +fTriggerUtilities(0x0), +fClusterServers(), +fTrackers() { -/// Default constructor + /// normal ctor - AliDebug(1,""); - // Crate manager - fCrateManager->ReadFromFile(); + AliDebug(1,""); + + // Unload mapping objects + // if they have been loaded from the obsolete OCDB mapping objects - // set to digit maker - fDigitMaker->SetCrateManager(fCrateManager); + if ( AliMpDDLStore::Instance(false) ) { + AliCDBManager::Instance()->UnloadFromCache("MUON/Calib/DDLStore"); + delete AliMpDDLStore::Instance(); + } - // transformater - fTransformer->ReadGeometryData("volpath.dat", "geometry.root"); - - // create segmentation and pass it to EventRecoCombi - AliMUONSegFactory factory(fTransformer); - fSegmentation = factory.CreateSegmentation(); - AliMUONEventRecoCombi::Instance(fSegmentation); - - // trigger circuit - for (Int_t i = 0; i < AliMUONConstants::NTriggerCircuit(); i++) { - AliMUONTriggerCircuit* c = new AliMUONTriggerCircuit(); - c->SetTransformer(fTransformer); - c->Init(i,*fCrateManager); - TClonesArray& circuit = *fTriggerCircuit; - new(circuit[circuit.GetEntriesFast()])AliMUONTriggerCircuit(*c); - delete c; - } + if ( AliMpSegmentation::Instance(false) ) { + AliCDBManager::Instance()->UnloadFromCache("MUON/Calib/Mapping"); + delete AliMpSegmentation::Instance(); + } + // Load mapping + if ( ! AliMpCDB::LoadDDLStore() ) { + AliFatal("Could not access mapping from OCDB !"); + } + // Load geometry data + fTransformer->LoadGeometryData(); + + fClusterServers.SetOwner(kTRUE); + fTrackers.SetOwner(kTRUE); } //_____________________________________________________________________________ AliMUONReconstructor::~AliMUONReconstructor() { -/// Destructor + /// dtor AliDebug(1,""); - delete fCalibrationData; + + delete fDigitCalibrator; + delete fDigitMaker; - delete fCrateManager; - delete fTriggerCircuit; + delete fDigitStore; delete fTransformer; - delete fSegmentation; + delete fTriggerCircuit; + delete fTriggerStore; + delete fTrackStore; + delete fClusterStore; + delete fTriggerProcessor; + delete fTriggerUtilities; + + delete AliMpSegmentation::Instance(false); + delete AliMpDDLStore::Instance(false); + + delete fCalibrationData; +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::Calibrate(AliMUONVDigitStore& digitStore) const +{ + /// Calibrate the digitStore + if (!fDigitCalibrator) + { + CreateCalibrator(); + } + AliCodeTimerAuto(Form("%s::Calibrate(AliMUONVDigitStore*)",fDigitCalibrator->ClassName()),0) + fDigitCalibrator->Calibrate(digitStore); } //_____________________________________________________________________________ -TTask* -AliMUONReconstructor::GetCalibrationTask(AliMUONData* data) const +void +AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, + AliMUONVDigitStore* digitStore, + AliMUONVTriggerStore* triggerStore) const { -/// Create the calibration task(s). + /// Convert raw data into digit and trigger stores + CreateDigitMaker(); + + // Skip reconstruction if event is Calibration + if ( GetRecoParam()->GetEventSpecie() == AliRecoParam::kCalib ) { + digitStore->Clear(); // Remove possible digits from previous event + triggerStore->Clear(); // Remove possible triggers from previous event + AliInfo("Calibration event: do not convert digits"); + return; + } - const AliRun* run = fRunLoader->GetAliRun(); + AliCodeTimerStart(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)", + fDigitMaker->ClassName())) + fDigitMaker->Raw2Digits(rawReader,digitStore,triggerStore); + AliCodeTimerStop(Form("%s::Raw2Digits(AliRawReader*,AliMUONVDigitStore*,AliMUONVTriggerStore*)", + fDigitMaker->ClassName())) + Calibrate(*digitStore); +} - AliInfo("Calibration will occur."); - Int_t runNumber = run->GetRunNumber(); - fCalibrationData = new AliMUONCalibrationData(runNumber); - if ( !fCalibrationData->IsValid() ) - { - AliError("Could not retrieve calibrations !"); - delete fCalibrationData; - fCalibrationData = 0x0; - return 0x0; - } - TTask* calibration = new TTask("MUONCalibrator","MUON Digit calibrator"); - calibration->Add(new AliMUONDigitCalibrator(data,fCalibrationData)); - //FIXME: calibration->Add(something about dead channels should go here). - return calibration; +//_____________________________________________________________________________ +void +AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const +{ + /// convert raw data into a digit tree + AliCodeTimerAuto("",0) + Bool_t alone = ( TriggerStore() == 0 ); + + Bool_t ok = DigitStore()->Connect(*digitsTree,alone); + if ( TriggerStore() ) + { + ok = ok && TriggerStore()->Connect(*digitsTree,kFALSE); + } + + if (!ok) + { + AliError("Could not make branches on TreeD"); + } + else + { + ConvertDigits(rawReader,DigitStore(),TriggerStore()); + AliCodeTimerStart("Fill digits") + digitsTree->Fill(); + AliCodeTimerStop("Fill digits") + DigitStore()->Clear(); + } } //_____________________________________________________________________________ void -AliMUONReconstructor::Init(AliRunLoader* runLoader) +AliMUONReconstructor::CreateDigitMaker() const { -/// Initialize + /// Create (and create if necessary) the digit maker + if (fDigitMaker) return; + + AliCodeTimerAuto("",0) + + TString option = GetOption(); + + Bool_t enableErrorLogging = kFALSE; + + if (option.Contains("ENABLEERRORLOGGING")) + { + enableErrorLogging = kTRUE; + } + + fDigitMaker = new AliMUONDigitMaker(enableErrorLogging); + option.ToUpper(); + + // Always make trigger digits + // (needed when calculating trigger chamber efficiency) + fDigitMaker->SetMakeTriggerDigits(kTRUE); - fRunLoader = runLoader; + if ( GetRecoParam()->TryRecover() ) + { + fDigitMaker->SetTryRecover(kTRUE); + } + else + { + fDigitMaker->SetTryRecover(kFALSE); + } } //_____________________________________________________________________________ -AliMUONClusterReconstructor* -AliMUONReconstructor::CreateClusterReconstructor(AliMUONData* data) const +void +AliMUONReconstructor::CreateTriggerCircuit() const { -/// Create cluster reconstructor + /// Return (and create if necessary) the trigger circuit object + if (fTriggerCircuit) return; + + AliCodeTimerAuto("",0) + + fTriggerCircuit = new AliMUONTriggerCircuit(fTransformer); + +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateTriggerUtilities() const +{ + /// Return (and create if necessary) the trigger utilities object + if ( fTriggerUtilities ) return; + + AliCodeTimerAuto("",0) + + if ( ! fCalibrationData ) CreateCalibrationData(); + + fTriggerUtilities = new AliMUONTriggerUtilities(fCalibrationData); +} + +//_____________________________________________________________________________ +AliTracker* +AliMUONReconstructor::CreateTracker() const +{ + /// Create the MUONTracker object + + CreateTriggerCircuit(); + CreateTriggerUtilities(); + + const AliMUONRecoParam* rp = GetRecoParam(); + + Int_t es = rp->GetEventSpecie(); + + AliTracker* tracker = static_cast(fTrackers.At(es)); + + if (!tracker ) + { + if ( ! rp->CombineClusterTrackReco() ) + { + tracker = new AliMUONTracker(rp, + 0x0, + *DigitStore(), + fTransformer, + fTriggerCircuit, + fTriggerUtilities); + + AliInfo(Form("Created tracker %p for recoparam of type %s es=%d", + tracker, + AliRecoParam::GetEventSpecieName(AliRecoParam::Convert(rp->GetEventSpecie())),es)); + } + else + { + + tracker = new AliMUONTracker(rp, + CreateClusterServer(*rp), + *DigitStore(), + fTransformer, + fTriggerCircuit, + fTriggerUtilities); + + AliInfo(Form("Created (combined) tracker %p for recoparam of type %s es=%d", + tracker, + AliRecoParam::GetEventSpecieName(AliRecoParam::Convert(rp->GetEventSpecie())),es)); + } + + fTrackers.AddAtAndExpand(tracker,es); + } + + + return tracker; +} + +//_____________________________________________________________________________ +AliMUONVClusterFinder* +AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType) +{ + /// Create a given cluster finder instance + + AliCodeTimerAutoGeneral("",0) AliMUONVClusterFinder* clusterFinder(0x0); - TString opt(GetOption()); + TString opt(clusterFinderType); opt.ToUpper(); - if ( strstr(opt,"PRECLUSTER") ) + if ( strstr(opt,"PRECLUSTERV2") ) + { + clusterFinder = new AliMUONPreClusterFinderV2; + } + else if ( strstr(opt,"PRECLUSTERV3") ) + { + clusterFinder = new AliMUONPreClusterFinderV3; + } + else if ( strstr(opt,"PRECLUSTER") ) { clusterFinder = new AliMUONPreClusterFinder; } + else if ( strstr(opt,"PEAKCOG") ) + { + clusterFinder = new AliMUONClusterFinderPeakCOG(kFALSE,new AliMUONPreClusterFinder); + } + else if ( strstr(opt,"PEAKFIT") ) + { + clusterFinder = new AliMUONClusterFinderPeakFit(kFALSE,new AliMUONPreClusterFinder); + } else if ( strstr(opt,"COG") ) { - clusterFinder = new AliMUONClusterFinderCOG; + clusterFinder = new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder); } + else if ( strstr(opt,"SIMPLEFITV3") ) + { + clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3)); + } else if ( strstr(opt,"SIMPLEFIT") ) { - clusterFinder = new AliMUONClusterFinderSimpleFit; + clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder)); } else if ( strstr(opt,"MLEM:DRAW") ) { - clusterFinder = new AliMUONClusterFinderMLEM(kTRUE); + clusterFinder = new AliMUONClusterFinderMLEM(kTRUE,new AliMUONPreClusterFinder); } + else if ( strstr(opt,"MLEMV3") ) + { + clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV3); + } + else if ( strstr(opt,"MLEMV2") ) + { + clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV2); + } else if ( strstr(opt,"MLEM") ) { - clusterFinder = new AliMUONClusterFinderMLEM(kFALSE); + clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinder); } - - if ( clusterFinder) + else { - AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName())); + AliErrorClass(Form("clustering mode \"%s\" does not exist",opt.Data())); + return 0x0; } - AliMUONClusterReconstructor* clusterReco = - new AliMUONClusterReconstructor(data,clusterFinder,fTransformer); - return clusterReco; + return clusterFinder; } //_____________________________________________________________________________ -void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const +AliMUONVClusterServer* +AliMUONReconstructor::CreateClusterServer(const AliMUONRecoParam& rp) const { -/// Reconstruct -/// \todo add more - - AliLoader* loader = runLoader->GetLoader("MUONLoader"); - Int_t nEvents = runLoader->GetNumberOfEvents(); - Int_t evtNumber = runLoader->GetEventNumber(); - - AliMUONData* data = new AliMUONData(loader,"MUON","MUON"); - -// passing loader as argument. - AliMUONVTrackReconstructor* recoEvent; - if (strstr(GetOption(),"Original")) recoEvent = new AliMUONTrackReconstructor(data); - else if (strstr(GetOption(),"Combi")) recoEvent = new AliMUONTrackReconstructorK(data,"Combi"); - else recoEvent = new AliMUONTrackReconstructorK(data,"Kalman"); + /// Create cluster server - recoEvent->SetTriggerCircuit(fTriggerCircuit); - - AliMUONClusterReconstructor* recoCluster = CreateClusterReconstructor(data); + AliCodeTimerAuto("",0); - AliMUONClusterFinderVS *recModel = recoCluster->GetRecoModel(); + AliMUONVClusterServer* clusterServer = static_cast(fClusterServers.At(rp.GetEventSpecie())); + + if (!clusterServer ) + { + AliMUONVClusterFinder* clusterFinder = CreateClusterFinder(rp.GetClusteringMode()); + + if ( !clusterFinder ) return 0x0; + + clusterServer = new AliMUONSimpleClusterServer(clusterFinder,*fTransformer); - if (!strstr(GetOption(),"VS")) { - recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ(); - recoCluster->SetRecoModel(recModel); + AliInfo(Form("Created AliMUONSimpleClusterServer (%p) for specie %d with clustering = %s (following requesting clustering mode %s)", + clusterServer,rp.GetEventSpecie(),clusterFinder->ClassName(),rp.GetClusteringMode())); + + fClusterServers.AddAtAndExpand(clusterServer,rp.GetEventSpecie()); } - recModel->SetGhostChi2Cut(10); - recModel->SetEventNumber(evtNumber); + + return clusterServer; +} - loader->LoadDigits("READ"); - loader->LoadRecPoints("RECREATE"); - loader->LoadTracks("RECREATE"); +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateCalibrationData() const +{ + /// Create the calibrator - TTask* calibration = GetCalibrationTask(data); + AliCodeTimerAuto("",0); - Int_t chBeg = (strstr(GetOption(),"Combi") ? 6 : 0); - - // Loop over events - for(Int_t ievent = 0; ievent < nEvents; ievent++) { + Int_t runNumber = AliCDBManager::Instance()->GetRun(); - AliDebug(1,Form("Event %d",ievent)); - - runLoader->GetEvent(ievent); - - //----------------------- digit2cluster & Trigger2Trigger ------------------- - if (!loader->TreeR()) loader->MakeRecPointsContainer(); - - // tracking branch - if (!strstr(GetOption(),"Combi")) { - data->MakeBranch("RC"); - data->SetTreeAddress("D,RC"); - } else { - data->SetTreeAddress("D"); - data->SetTreeAddress("RCC"); - } - // Important for avoiding a memory leak when reading digits ( to be investigated more in detail) - // In any case the reading of GLT is needed for the Trigger2Tigger method below - data->SetTreeAddress("GLT"); - - data->GetDigits(); - - if ( calibration ) + fCalibrationData = new AliMUONCalibrationData(runNumber); + if ( !fCalibrationData->IsValid() ) + { + AliError("Could not retrieve calibrations !"); + delete fCalibrationData; + fCalibrationData = 0x0; + return; + } + + // It is now time to check whether we have everything to proceed. + // What we need depends on whether both tracker and trigger + // are in the readout chain, and what specific "bad channel policy" + // we use + + Bool_t kTracker(kFALSE); + Bool_t kTrigger(kFALSE); + + const AliRunInfo* runInfo = GetRunInfo(); + if (!runInfo) + { + AliError("Could not get runinfo ?"); + } + else + { + TString detectors(runInfo->GetActiveDetectors()); + if (detectors.Contains("MUONTRK")) kTracker=kTRUE; + if (detectors.Contains("MUONTRG")) kTrigger=kTRUE; + } + + AliInfo(Form("Run with MUON TRIGGER : %s and MUON TRACKER : %s", + kTrigger ? "YES":"NO" , + kTracker ? "YES":"NO")); + + if ( kTracker ) + { + // Check that we get all the calibrations we'll need + if ( !fCalibrationData->Pedestals() || + !fCalibrationData->Gains() ) { - calibration->ExecuteTask(); + AliFatal(Form("Could not access all required calibration data (PED %p GAIN %p)", + fCalibrationData->Pedestals(),fCalibrationData->Gains())); } - recoCluster->Digits2Clusters(chBeg); - - if (strstr(GetOption(),"Combi")) { - // Combined cluster / track finder - AliMUONEventRecoCombi::Instance()->FillEvent(data, (AliMUONClusterFinderAZ*)recModel); - ((AliMUONClusterFinderAZ*) recModel)->SetReco(2); - } - else data->Fill("RC"); - - // trigger branch - data->MakeBranch("TC"); - data->SetTreeAddress("TC"); - recoCluster->Trigger2Trigger(); - data->Fill("TC"); - - //AZ loader->WriteRecPoints("OVERWRITE"); - - //---------------------------- Track & TriggerTrack --------------------- - if (!loader->TreeT()) loader->MakeTracksContainer(); - - // trigger branch - data->MakeBranch("RL"); //trigger track - data->SetTreeAddress("RL"); - recoEvent->EventReconstructTrigger(); - data->Fill("RL"); - - // tracking branch - data->MakeBranch("RT"); //track - data->SetTreeAddress("RT"); - recoEvent->EventReconstruct(); - data->Fill("RT"); - - loader->WriteTracks("OVERWRITE"); - - if (strstr(GetOption(),"Combi")) { - // Combined cluster / track - ((AliMUONClusterFinderAZ*) recModel)->SetReco(1); - data->MakeBranch("RC"); - data->SetTreeAddress("RC"); - AliMUONEventRecoCombi::Instance()->FillRecP(data, (AliMUONTrackReconstructorK*)recoEvent); - data->Fill("RC"); - } - loader->WriteRecPoints("OVERWRITE"); - - //--------------------------- Resetting branches ----------------------- - data->ResetDigits(); - data->ResetRawClusters(); - data->ResetTrigger(); - data->ResetRecTracks(); - data->ResetRecTriggerTracks(); - + if ( !fCalibrationData->HV() ) + { + // Special treatment of HV. We only break if the values + // are not there *AND* we cut on them. + UInt_t mask = GetRecoParam()->PadGoodnessMask(); + TString smask(AliMUONPadStatusMaker::AsCondition(mask)); + if ( smask.Contains("HV") ) + { + AliFatal("Could not access all required calibration data (HV)"); + } + } } - loader->UnloadDigits(); - loader->UnloadRecPoints(); - loader->UnloadTracks(); - - delete recoCluster; - delete recoEvent; - delete data; - delete calibration; } //_____________________________________________________________________________ -void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, - AliRawReader* rawReader) const +void +AliMUONReconstructor::CreateCalibrator() const { -/// Recontruct -/// \todo add more + /// Create the calibrator - // AliLoader - AliLoader* loader = runLoader->GetLoader("MUONLoader"); - Int_t evtNumber = runLoader->GetEventNumber(); - - AliMUONData data(loader,"MUON","MUON"); + AliCodeTimerAuto("",0); - // passing loader as argument. - fDigitMaker->SetMUONData(&data); + if ( ! fCalibrationData ) + CreateCalibrationData(); - AliMUONClusterReconstructor* recoCluster = CreateClusterReconstructor(&data); + AliInfo("Calibration will occur."); - AliMUONVTrackReconstructor *recoEvent; - if (strstr(GetOption(),"Original")) recoEvent = new AliMUONTrackReconstructor(&data); - else if (strstr(GetOption(),"Combi")) recoEvent = new AliMUONTrackReconstructorK(&data,"Combi"); - else recoEvent = new AliMUONTrackReconstructorK(&data,"Kalman"); + TString opt(GetOption()); + opt.ToUpper(); + + if ( strstr(opt,"NOSTATUSMAP") ) + { + AliWarning("NOSTATUSMAP is obsolete"); + } - recoEvent->SetTriggerCircuit(fTriggerCircuit); + fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,GetRecoParam()); +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::ResponseRemovingChambers(AliMUONVTriggerStore* triggerStore) const +{ + /// Update trigger information with informatins obtained after + /// re-calculation of trigger response + AliCodeTimerAuto("",0); - AliMUONClusterFinderVS *recModel = recoCluster->GetRecoModel(); + if ( ! fCalibrationData ) + CreateCalibrationData(); - if (!strstr(GetOption(),"VS")) + if ( ! fTriggerProcessor ) + fTriggerProcessor = new AliMUONTriggerElectronics(fCalibrationData); + + fTriggerProcessor->ResponseRemovingChambers(*triggerStore); +} + +//_____________________________________________________________________________ +AliMUONVDigitStore* +AliMUONReconstructor::DigitStore() const +{ + /// Return (and create if necessary) the digit container + if (!fDigitStore) { - recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ(); - recoCluster->SetRecoModel(recModel); + TString sopt(GetOption()); + sopt.ToUpper(); + + AliInfo(Form("Options=%s",sopt.Data())); + + if ( sopt.Contains("DIGITSTOREV1") ) + { + fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV1"); + } + else if ( sopt.Contains("DIGITSTOREV2R") ) + { + fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R"); + } + else if ( sopt.Contains("DIGITSTOREV2S") ) + { + fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2S"); + } + + if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R"); + + AliInfo(Form("Will use %s to store digits during reconstruction",fDigitStore->ClassName())); } - recModel->SetGhostChi2Cut(10); - recModel->SetEventNumber(evtNumber); + return fDigitStore; +} - TTask* calibration = GetCalibrationTask(&data); - - loader->LoadRecPoints("RECREATE"); - loader->LoadTracks("RECREATE"); - - // Digits are not stored on disk and created on flight from rawdata. - // In order to write digits on disk the following line should be uncommented - // loader->LoadDigits("RECREATE"); +//_____________________________________________________________________________ +void +AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore, + TTree& clustersTree) const +{ + /// Write the trigger and cluster information into TreeR + + AliCodeTimerAuto("",0) - // Loop over events - Int_t iEvent = 0; - - TStopwatch totalTimer; - TStopwatch rawTimer; - TStopwatch calibTimer; - TStopwatch clusterTimer; - TStopwatch trackingTimer; + Bool_t ok(kFALSE); + Bool_t alone(kTRUE); // is trigger the only info in TreeR ? - rawTimer.Start(kTRUE); rawTimer.Stop(); - calibTimer.Start(kTRUE); calibTimer.Stop(); - clusterTimer.Start(kTRUE); clusterTimer.Stop(); - trackingTimer.Start(kTRUE); trackingTimer.Stop(); + const AliMUONRecoParam* rp = GetRecoParam(); - totalTimer.Start(kTRUE); + if ( ! rp->CombineClusterTrackReco() ) + { + alone = kFALSE; // we'll get both tracker and trigger information in TreeR + } - while (rawReader->NextEvent()) + if ( triggerStore ) { - AliDebug(1,Form("Event %d",iEvent)); + ResponseRemovingChambers(triggerStore); + ok = triggerStore->Connect(clustersTree,alone); + if (!ok) + { + AliError("Could not create triggerStore branches in TreeR"); + } + } + + if ( !alone ) + { + if (!fClusterStore) + { + fClusterStore = new AliMUONClusterStoreV2; + } - runLoader->GetEvent(iEvent++); - - //----------------------- raw2digits & raw2trigger------------------- -// if (!loader->TreeD()) -// { -// AliDebug(1,Form("Making Digit Container for event %d",iEvent)); -// loader->MakeDigitsContainer(); -// } - // Digits are not stored on disk and created on flight from rawdata. - // In order to write digits on disk the following lines should be uncommented - // data.MakeBranch("D,GLT"); - // data.SetTreeAddress("D,GLT"); - data.SetDataContainer("D, GLT"); - rawTimer.Start(kFALSE); - fDigitMaker->Raw2Digits(rawReader); - rawTimer.Stop(); + AliMUONVClusterServer* clusterServer = CreateClusterServer(*rp); - if ( calibration ) + TIter next(DigitStore()->CreateIterator()); + clusterServer->UseDigits(next,DigitStore()); + + AliMpArea area; + + AliDebug(1,Form("Doing full clusterization in local reconstruction using %s ",clusterServer->ClassName())); + + for ( Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i ) { - calibTimer.Start(kFALSE); - calibration->ExecuteTask(); - calibTimer.Stop(); + if (rp->UseChamber(i)) + { + if ( ( i == 6 || i == 7 ) && rp->BypassSt4() ) continue; + if ( ( i == 8 || i == 9 ) && rp->BypassSt5() ) continue; + + clusterServer->Clusterize(i,*fClusterStore,area,rp); + } } - // Digits are not stored on disk and created on flight from rawdata. - // In order to write digits on disk the following lines should be uncommented - // data.Fill("D,GLT"); - // loader->WriteDigits("OVERWRITE"); - //----------------------- digit2cluster & Trigger2Trigger ------------------- - clusterTimer.Start(kFALSE); - - if (!loader->TreeR()) loader->MakeRecPointsContainer(); - - // tracking branch - data.MakeBranch("RC"); - data.SetTreeAddress("RC"); - recoCluster->Digits2Clusters(); - data.Fill("RC"); - - // trigger branch - data.MakeBranch("TC"); - data.SetTreeAddress("TC"); - data.Fill("TC"); - loader->WriteRecPoints("OVERWRITE"); - - clusterTimer.Stop(); - - //---------------------------- Track & TriggerTrack --------------------- - trackingTimer.Start(kFALSE); - if (!loader->TreeT()) loader->MakeTracksContainer(); + Bool_t cok = fClusterStore->Connect(clustersTree,alone); + + if (!cok) AliError("Could not connect clusterStore to clusterTree"); + + AliDebug(1,Form("Number of clusters found = %d",fClusterStore->GetSize())); + + StdoutToAliDebug(1,fClusterStore->Print()); + } + + if (ok) // at least one type of branches created successfully + { + clustersTree.Fill(); + } + + if (fClusterStore) fClusterStore->Clear(); +} - // trigger branch - data.MakeBranch("RL"); //trigger track - data.SetTreeAddress("RL"); - recoEvent->EventReconstructTrigger(); - data.Fill("RL"); +//_____________________________________________________________________________ +const AliMUONRecoParam* AliMUONReconstructor::GetRecoParam() +{ + /// Get the recoparam from reconstruction + return dynamic_cast(AliReconstructor::GetRecoParam(AliReconstruction::GetDetIndex("MUON"))); +} - // tracking branch - data.MakeBranch("RT"); //track - data.SetTreeAddress("RT"); - recoEvent->EventReconstruct(); - data.Fill("RT"); - loader->WriteTracks("OVERWRITE"); - trackingTimer.Stop(); - - //--------------------------- Resetting branches ----------------------- - data.ResetDigits(); - data.ResetRawClusters(); - data.ResetTrigger(); - data.ResetRecTracks(); - data.ResetRecTriggerTracks(); +//_____________________________________________________________________________ +Bool_t +AliMUONReconstructor::HasDigitConversion() const +{ + /// We *do* have digit conversion, but we might advertise it only + /// if we want to save the digits. + TString opt(GetOption()); + opt.ToUpper(); + if ( opt.Contains("SAVEDIGITS" ) && !opt.Contains("NOLOCALRECONSTRUCTION") ) + { + return kTRUE; } + else + { + return kFALSE; + } +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::Reconstruct(AliRawReader* rawReader, TTree* clustersTree) const +{ + /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE AND + /// HasDigitConversion()==kFALSE - totalTimer.Stop(); - - loader->UnloadRecPoints(); - loader->UnloadTracks(); - loader->UnloadDigits(); + if ( !clustersTree ) + { + AliError("clustersTree is 0x0 !"); + return; + } - delete recoEvent; + ConvertDigits(rawReader,DigitStore(),TriggerStore()); - delete recoCluster; - - AliInfo(Form("Execution time for converting RAW data to digits in MUON : R:%.2fs C:%.2fs", - rawTimer.RealTime(),rawTimer.CpuTime())); - AliInfo(Form("Execution time for calibrating MUON : R:%.2fs C:%.2fs", - calibTimer.RealTime(),calibTimer.CpuTime())); - AliInfo(Form("Execution time for clusterizing MUON : R:%.2fs C:%.2fs", - clusterTimer.RealTime(),clusterTimer.CpuTime())); - AliInfo(Form("Execution time for tracking MUON : R:%.2fs C:%.2fs", - trackingTimer.RealTime(),trackingTimer.CpuTime())); - AliInfo(Form("Total Execution time for Reconstruct(from raw) MUON : R:%.2fs C:%.2fs", - totalTimer.RealTime(),totalTimer.CpuTime())); + FillTreeR(TriggerStore(),*clustersTree); } //_____________________________________________________________________________ -void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const +void +AliMUONReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const { -/// Fill ESD -/// \todo add more - - TClonesArray* recTracksArray = 0; - TClonesArray* recTrigTracksArray = 0; - - AliLoader* loader = runLoader->GetLoader("MUONLoader"); - loader->LoadTracks("READ"); - AliMUONData* muonData = new AliMUONData(loader,"MUON","MUON"); - - // declaration - Int_t iEvent;// nPart; - Int_t nTrackHits;// nPrimary; - Double_t fitFmin; - - Double_t bendingSlope, nonBendingSlope, inverseBendingMomentum; - Double_t xRec, yRec, zRec, chi2MatchTrigger; - Bool_t matchTrigger; - - // setting pointer for tracks, triggertracks & trackparam at vertex - AliMUONTrack* recTrack = 0; - AliMUONTrackParam* trackParam = 0; - AliMUONTriggerTrack* recTriggerTrack = 0; - - iEvent = runLoader->GetEventNumber(); - runLoader->GetEvent(iEvent); - - // Get vertex - Double_t vertex[3] = {0}; - const AliESDVertex *esdVert = esd->GetVertex(); - if (esdVert->GetNContributors()) { - esdVert->GetXYZ(vertex); - printf("find vertex\n"); - } - // setting ESD MUON class - AliESDMuonTrack* theESDTrack = new AliESDMuonTrack() ; - - //-------------------- trigger tracks------------- - Long_t trigPat = 0; - muonData->SetTreeAddress("RL"); - muonData->GetRecTriggerTracks(); - recTrigTracksArray = muonData->RecTriggerTracks(); - - // ready global trigger pattern from first track - if (recTrigTracksArray) - recTriggerTrack = (AliMUONTriggerTrack*) recTrigTracksArray->First(); - if (recTriggerTrack) trigPat = recTriggerTrack->GetGTPattern(); - - //printf(">>> Event %d Number of Recconstructed tracks %d \n",iEvent, nrectracks); - - // -------------------- tracks------------- - muonData->SetTreeAddress("RT"); - muonData->GetRecTracks(); - recTracksArray = muonData->RecTracks(); - - Int_t nRecTracks = 0; - if (recTracksArray) - nRecTracks = (Int_t) recTracksArray->GetEntriesFast(); // + /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE + /// AND HasDigitConversion()==kTRUE + + AliCodeTimerAuto("",0) - // loop over tracks - for (Int_t iRecTracks = 0; iRecTracks < nRecTracks; iRecTracks++) { + AliDebug(1,""); + + if (!digitsTree || !clustersTree) + { + AliError(Form("Tree is null : digitsTree=%p clustersTree=%p", + digitsTree,clustersTree)); + return; + } - // reading info from tracks - recTrack = (AliMUONTrack*) recTracksArray->At(iRecTracks); + if (!fDigitStore) + { + fDigitStore = AliMUONVDigitStore::Create(*digitsTree); + if (!fDigitStore) + { + AliError(Form("Could not get DigitStore from %s",digitsTree->GetName())); + } + else + { + AliInfo(Form("Created %s from %s",fDigitStore->ClassName(),digitsTree->GetName())); + } + } + if (!fTriggerStore) + { + fTriggerStore = AliMUONVTriggerStore::Create(*digitsTree); + if (!fTriggerStore) + { + AliError(Form("Could not get TriggerStore from %s",digitsTree->GetName())); + } + else + { + AliInfo(Form("Created %s from %s",fTriggerStore->ClassName(),digitsTree->GetName())); + } + } + + if (!fTriggerStore && !fDigitStore) + { + AliError("No store at all. Nothing to do."); + return; + } + + // insure we start with empty stores + if ( fDigitStore ) + { + fDigitStore->Clear(); + Bool_t alone = ( fTriggerStore ? kFALSE : kTRUE ); + Bool_t ok = fDigitStore->Connect(*digitsTree,alone); + if (!ok) + { + AliError("Could not connect digitStore to digitsTree"); + return; + } + } + if ( fTriggerStore ) + { + fTriggerStore->Clear(); + Bool_t alone = ( fDigitStore ? kFALSE : kTRUE ); + Bool_t ok = fTriggerStore->Connect(*digitsTree,alone); + if (!ok) + { + AliError("Could not connect triggerStore to digitsTree"); + return; + } + } + + digitsTree->GetEvent(0); + + if ( fDigitStore ) + { + // Insure we got calibrated digits (if we reconstruct from pure simulated, + // i.e. w/o going through raw data, this will be the case) + TIter next(fDigitStore->CreateIterator()); + AliMUONVDigit* digit = static_cast(next()); + if (digit && !digit->IsCalibrated()) + { + Calibrate(*fDigitStore); + } + } + + FillTreeR(fTriggerStore,*clustersTree); +} - trackParam = (AliMUONTrackParam*) (recTrack->GetTrackParamAtHit())->First(); - - if (esdVert->GetNContributors()) - AliMUONTrackExtrap::ExtrapToVertex(trackParam, vertex[0],vertex[1],vertex[2]); - - bendingSlope = trackParam->GetBendingSlope(); - nonBendingSlope = trackParam->GetNonBendingSlope(); - inverseBendingMomentum = trackParam->GetInverseBendingMomentum(); - xRec = trackParam->GetNonBendingCoor(); - yRec = trackParam->GetBendingCoor(); - zRec = trackParam->GetZ(); - - nTrackHits = recTrack->GetNTrackHits(); - fitFmin = recTrack->GetFitFMin(); - matchTrigger = recTrack->GetMatchTrigger(); - chi2MatchTrigger = recTrack->GetChi2MatchTrigger(); - - // setting data member of ESD MUON - theESDTrack->SetInverseBendingMomentum(inverseBendingMomentum); - theESDTrack->SetThetaX(TMath::ATan(nonBendingSlope)); - theESDTrack->SetThetaY(TMath::ATan(bendingSlope)); - theESDTrack->SetZ(zRec); - theESDTrack->SetBendingCoor(yRec); // calculate vertex at ESD or Tracking level ? - theESDTrack->SetNonBendingCoor(xRec); - theESDTrack->SetChi2(fitFmin); - theESDTrack->SetNHit(nTrackHits); - theESDTrack->SetMatchTrigger(matchTrigger); - theESDTrack->SetChi2MatchTrigger(chi2MatchTrigger); - - // storing ESD MUON Track into ESD Event - if (nRecTracks != 0) - esd->AddMuonTrack(theESDTrack); - } // end loop tracks - - // reset muondata - muonData->ResetRecTracks(); - muonData->ResetRecTriggerTracks(); - - //} // end loop on event - loader->UnloadTracks(); - - delete theESDTrack; - delete muonData; -}//_____________________________________________________________________________ -void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliRawReader* /*rawReader*/, AliESD* esd) const +//_____________________________________________________________________________ +AliMUONVTriggerStore* +AliMUONReconstructor::TriggerStore() const { -/// Fill ESD -/// \todo add more - - // don't need rawReader ??? - FillESD(runLoader, esd); + /// Return (and create if necessary and allowed) the trigger container + TString sopt(GetOption()); + sopt.ToUpper(); + + if (sopt.Contains("TRIGGERDISABLE")) + { + delete fTriggerStore; + fTriggerStore = 0x0; + } + else + { + if (!fTriggerStore) + { + fTriggerStore = new AliMUONTriggerStoreV1; + } + } + return fTriggerStore; }