X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONReconstructor.cxx;h=13084e40b76c2cb18cccdee95fb3e008d0b094ea;hb=542e9a388e60e7b3a7ee53bc3ad4118c0463c8d1;hp=88ff13fc703b9aeeb87d7755010fcf8d699410f9;hpb=cf4646915e8cf61be747d19ac2d2e44a146a7208;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONReconstructor.cxx b/MUON/AliMUONReconstructor.cxx index 88ff13fc703..13084e40b76 100644 --- a/MUON/AliMUONReconstructor.cxx +++ b/MUON/AliMUONReconstructor.cxx @@ -12,349 +12,651 @@ * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ - /* $Id$ */ -/////////////////////////////////////////////////////////////////////////////// -// // -// class for MUON reconstruction // -// // -/////////////////////////////////////////////////////////////////////////////// -#include -#include - -#include "AliRunLoader.h" -#include "AliHeader.h" -#include "AliGenEventHeader.h" -#include "AliESD.h" +//----------------------------------------------------------------------------- +/// \class AliMUONReconstructor +/// +/// Implementation of AliReconstructor for MUON subsystem. +/// +/// The clustering mode and the associated parameters can be changed by using +/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam(); +/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details +/// AliRecoParam::Instance()->RegisterRecoParam(muonRecoParam); +/// +/// 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 +/// +/// USEFASTDECODER : makes the digit maker class use the high performance decoder +/// AliMUONTrackerDDLDecoder instead of AliMUONPayloadTracker. +/// +/// \author Laurent Aphecetche, Subatech +//----------------------------------------------------------------------------- + #include "AliMUONReconstructor.h" -#include "AliMUONData.h" -#include "AliMUONEventReconstructor.h" -#include "AliMUONClusterReconstructor.h" -#include "AliMUONTriggerDecision.h" -#include "AliMUONClusterFinderVS.h" -#include "AliMUONTrack.h" -#include "AliMUONTrackParam.h" -#include "AliMUONTriggerTrack.h" -#include "AliESDMuonTrack.h" +#include "AliMUONCalibrationData.h" +#include "AliMUONClusterFinderCOG.h" +#include "AliMUONClusterFinderMLEM.h" +#include "AliMUONClusterFinderSimpleFit.h" +#include "AliMUONClusterFinderPeakCOG.h" +#include "AliMUONClusterFinderPeakFit.h" +#include "AliMUONConstants.h" +#include "AliMUONDigitCalibrator.h" +#include "AliMUONDigitMaker.h" +#include "AliMUONDigitStoreV1.h" +#include "AliMUONDigitStoreV2R.h" +#include "AliMUONGeometryTransformer.h" +#include "AliMUONPreClusterFinder.h" +#include "AliMUONPreClusterFinderV2.h" +#include "AliMUONPreClusterFinderV3.h" +#include "AliMUONRecoParam.h" +#include "AliMUONSimpleClusterServer.h" +#include "AliMUONTracker.h" +#include "AliMUONTriggerCircuit.h" +#include "AliMUONTriggerCrateStore.h" +#include "AliMUONTriggerStoreV1.h" +#include "AliMUONVClusterFinder.h" +#include "AliMUONVClusterServer.h" +#include "AliMUONVTrackStore.h" + +#include "AliMpArea.h" +#include "AliMpCDB.h" +#include "AliMpConstants.h" + +#include "AliRecoParam.h" #include "AliRawReader.h" +#include "AliCDBManager.h" +#include "AliCodeTimer.h" +#include "AliLog.h" + +#include +#include +#include +#include +#include +/// \cond CLASSIMP ClassImp(AliMUONReconstructor) +/// \endcond + +AliMUONRecoParam* AliMUONReconstructor::fgRecoParam = 0x0; // reconstruction parameters + //_____________________________________________________________________________ -AliMUONReconstructor::AliMUONReconstructor() - : AliReconstructor() +AliMUONReconstructor::AliMUONReconstructor() : +AliReconstructor(), +fCrateManager(0x0), +fDigitMaker(0x0), +fTransformer(new AliMUONGeometryTransformer()), +fDigitStore(0x0), +fTriggerCircuit(0x0), +fCalibrationData(0x0), +fDigitCalibrator(0x0), +fClusterServer(0x0), +fTriggerStore(0x0), +fTrackStore(0x0) { + /// normal ctor + + // Load mapping + if ( ! AliMpCDB::LoadDDLStore() ) { + AliFatal("Could not access mapping from OCDB !"); + } + + // Load geometry data + fTransformer->LoadGeometryData(); + } + //_____________________________________________________________________________ AliMUONReconstructor::~AliMUONReconstructor() { + /// dtor + delete fDigitMaker; + delete fDigitStore; + delete fTransformer; + delete fCrateManager; + delete fTriggerCircuit; + delete fCalibrationData; + delete fDigitCalibrator; + delete fClusterServer; + delete fTriggerStore; + delete fTrackStore; } + //_____________________________________________________________________________ -void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const +const AliMUONRecoParam* AliMUONReconstructor::GetRecoParam() { -// AliLoader - AliLoader* loader = runLoader->GetLoader("MUONLoader"); - Int_t nEvents = runLoader->GetNumberOfEvents(); + /// get reconstruction parameters + + if (!fgRecoParam) { + + // get reconstruction parameters from AliRecoParam if any + TObjArray *recoParams = AliRecoParam::Instance()->GetRecoParam("MUON"); + + if (recoParams) { + + fgRecoParam = (AliMUONRecoParam*) recoParams->Last(); + + } else { + + // initialize reconstruction parameters if not already done + cout<<"W-AliMUONReconstructor::GetRecoParam: Reconstruction parameters not initialized - Use default one"<RegisterRecoParam(fgRecoParam); + + } + + } + + return fgRecoParam; +} -// used local container for each method -// passing fLoader as argument, could be avoided ??? - AliMUONEventReconstructor* recoEvent = new AliMUONEventReconstructor(loader); - AliMUONData* dataEvent = recoEvent->GetMUONData(); +//_____________________________________________________________________________ +void +AliMUONReconstructor::Calibrate(AliMUONVDigitStore& digitStore) const +{ + /// Calibrate the digitStore + if (!fDigitCalibrator) + { + CreateCalibrator(); + } + AliCodeTimerAuto(Form("%s::Calibrate(AliMUONVDigitStore*)",fDigitCalibrator->ClassName())) + fDigitCalibrator->Calibrate(digitStore); +} - AliMUONClusterReconstructor* recoCluster = new AliMUONClusterReconstructor(loader); - AliMUONData* dataCluster = recoCluster->GetMUONData(); +//_____________________________________________________________________________ +void +AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, + AliMUONVDigitStore* digitStore, + AliMUONVTriggerStore* triggerStore) const +{ + /// Convert raw data into digit and trigger stores + CreateDigitMaker(); + + 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); +} - AliMUONTriggerDecision* trigDec = new AliMUONTriggerDecision(loader,0,dataCluster); - // AliMUONData* dataTrig = trigDec->GetMUONData(); +//_____________________________________________________________________________ +void +AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const +{ + /// convert raw data into a digit tree + AliCodeTimerAuto("") + + 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(); + } +} +//_____________________________________________________________________________ +AliMUONTriggerCrateStore* +AliMUONReconstructor::CrateManager() const +{ + /// Return (and create if necessary) the trigger crate store + if (fCrateManager) return fCrateManager; + fCrateManager = new AliMUONTriggerCrateStore; + fCrateManager->ReadFromFile(); + return fCrateManager; +} - for (Int_t i = 0; i < 10; i++) { - AliMUONClusterFinderVS *recModel = new AliMUONClusterFinderVS(); - recModel->SetGhostChi2Cut(10); - recoCluster->SetReconstructionModel(i,recModel); +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateDigitMaker() const +{ + /// Create (and create if necessary) the digit maker + if (fDigitMaker) return; + + AliCodeTimerAuto("") + + TString option = GetOption(); + Bool_t enableErrorLogging = kTRUE; + Bool_t useFastDecoder = kFALSE; + if (option.Contains("USEFASTDECODER")) + { + useFastDecoder = kTRUE; + } + fDigitMaker = new AliMUONDigitMaker(enableErrorLogging, useFastDecoder); +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateTriggerCircuit() const +{ + /// Return (and create if necessary) the trigger circuit object + if (fTriggerCircuit) return; + + AliCodeTimerAuto("") + + fTriggerCircuit = new AliMUONTriggerCircuit(fTransformer); + +} + +//_____________________________________________________________________________ +AliTracker* +AliMUONReconstructor::CreateTracker() const +{ + /// Create the MUONTracker object + + CreateTriggerCircuit(); + CreateDigitMaker(); + CreateClusterServer(); + + if (!fClusterServer) + { + AliError("ClusterServer is NULL ! Cannot create tracker"); + return 0x0; + } + + AliMUONTracker* tracker = new AliMUONTracker(*fClusterServer, + *DigitStore(), + fDigitMaker, + fTransformer, + fTriggerCircuit); + + return tracker; +} + +//_____________________________________________________________________________ +AliMUONVClusterFinder* +AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType) const +{ + /// Create a given cluster finder instance + + AliCodeTimerAuto("") + + AliMUONVClusterFinder* clusterFinder(0x0); + + TString opt(clusterFinderType); + opt.ToUpper(); + + 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(new AliMUONPreClusterFinder); + } + else if ( strstr(opt,"SIMPLEFITV3") ) + { + clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3)); + } + else if ( strstr(opt,"SIMPLEFIT") ) + { + clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder)); + } + else if ( strstr(opt,"MLEM:DRAW") ) + { + 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,new AliMUONPreClusterFinder); + } + else + { + AliError(Form("clustering mode \"%s\" does not exist",opt.Data())); + return 0x0; + } + + return clusterFinder; +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateClusterServer() const +{ + /// Create cluster server + + if ( fClusterServer ) return; + + AliCodeTimerAuto("") + + AliDebug(1,""); + + AliMUONVClusterFinder* clusterFinder = CreateClusterFinder(GetRecoParam()->GetClusteringMode()); + + if ( !clusterFinder ) return; + + AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName())); + + fClusterServer = new AliMUONSimpleClusterServer(*clusterFinder,*fTransformer); +} + +//_____________________________________________________________________________ +void +AliMUONReconstructor::CreateCalibrator() const +{ + /// Create the calibrator + + AliCodeTimerAuto("") + + Int_t runNumber = AliCDBManager::Instance()->GetRun(); - loader->LoadDigits("READ"); - loader->LoadRecPoints("RECREATE"); - loader->LoadTracks("RECREATE"); - - // Loop over events - for(Int_t ievent = 0; ievent < nEvents; ievent++) { - printf("Event %d\n",ievent); - runLoader->GetEvent(ievent); - - //----------------------- digit2cluster & Digits2Trigger ------------------- - if (!loader->TreeR()) loader->MakeRecPointsContainer(); - - // tracking branch - dataCluster->MakeBranch("RC"); - dataCluster->SetTreeAddress("D,RC"); - recoCluster->Digits2Clusters(); - dataCluster->Fill("RC"); - - // trigger branch - dataCluster->MakeBranch("TC"); - dataCluster->SetTreeAddress("TC"); - trigDec->Trigger2Trigger(); - dataCluster->Fill("TC"); - - loader->WriteRecPoints("OVERWRITE"); - - //---------------------------- Track & TriggerTrack --------------------- - if (!loader->TreeT()) loader->MakeTracksContainer(); - - // trigger branch - dataEvent->MakeBranch("RL"); //trigger track - dataEvent->SetTreeAddress("RL"); - recoEvent->EventReconstructTrigger(); - dataEvent->Fill("RL"); - - // tracking branch - dataEvent->MakeBranch("RT"); //track - dataEvent->SetTreeAddress("RT"); - recoEvent->EventReconstruct(); - dataEvent->Fill("RT"); - - loader->WriteTracks("OVERWRITE"); - - //--------------------------- Resetting branches ----------------------- - dataCluster->ResetDigits(); - dataCluster->ResetRawClusters(); - dataCluster->ResetTrigger(); - - dataEvent->ResetRawClusters(); - dataEvent->ResetTrigger(); - dataEvent->ResetRecTracks(); - dataEvent->ResetRecTriggerTracks(); + AliInfo("Calibration will occur."); + fCalibrationData = new AliMUONCalibrationData(runNumber); + if ( !fCalibrationData->IsValid() ) + { + AliError("Could not retrieve calibrations !"); + delete fCalibrationData; + fCalibrationData = 0x0; + return; + } + + // Check that we get all the calibrations we'll need + if ( !fCalibrationData->Pedestals() || + !fCalibrationData->Gains() || + !fCalibrationData->HV() ) + { + AliFatal("Could not access all required calibration data"); + } + + TString opt(GetOption()); + opt.ToUpper(); + + if ( strstr(opt,"NOSTATUSMAP") ) + { + AliWarning("NOSTATUSMAP is obsolete"); } - loader->UnloadDigits(); - loader->UnloadRecPoints(); - loader->UnloadTracks(); - delete recoCluster; - delete recoEvent; - delete trigDec; + fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData); } //_____________________________________________________________________________ -void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, AliRawReader* rawReader) const +AliMUONVDigitStore* +AliMUONReconstructor::DigitStore() const { -// AliLoader - AliLoader* loader = runLoader->GetLoader("MUONLoader"); + /// Return (and create if necessary) the digit container + if (!fDigitStore) + { + 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())); + } + return fDigitStore; +} -// used local container for each method -// passing fLoader as argument, could be avoided ??? - AliMUONEventReconstructor* recoEvent = new AliMUONEventReconstructor(loader); - AliMUONData* dataEvent = recoEvent->GetMUONData(); +//_____________________________________________________________________________ +void +AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore, + TTree& clustersTree) const +{ + /// Write the trigger and cluster information into TreeR + + AliCodeTimerAuto("") - AliMUONClusterReconstructor* recoCluster = new AliMUONClusterReconstructor(loader); - AliMUONData* dataCluster = recoCluster->GetMUONData(); + AliDebug(1,""); + + Bool_t ok(kFALSE); + if ( triggerStore ) + { + ok = triggerStore->Connect(clustersTree,kTRUE); + if (!ok) + { + AliError("Could not create triggerStore branches in TreeR"); + } + } + + if (ok) // at least one type of branches created successfully + { + clustersTree.Fill(); + } +} - AliMUONTriggerDecision* trigDec = new AliMUONTriggerDecision(loader,0,dataCluster); - // AliMUONData* dataTrig = trigDec->GetMUONData(); +//_____________________________________________________________________________ +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 + + if ( !clustersTree ) + { + AliError("clustersTree is 0x0 !"); + return; + } + + ConvertDigits(rawReader,DigitStore(),TriggerStore()); - for (Int_t i = 0; i < 10; i++) { - AliMUONClusterFinderVS *recModel = new AliMUONClusterFinderVS(); - recModel->SetGhostChi2Cut(10); - recoCluster->SetReconstructionModel(i,recModel); - } + FillTreeR(TriggerStore(),*clustersTree); +} - loader->LoadDigits("READ"); - loader->LoadRecPoints("RECREATE"); - loader->LoadTracks("RECREATE"); - - // Loop over events - Int_t iEvent = 0; - - while (rawReader->NextEvent()) { - printf("Event %d\n",iEvent); - runLoader->GetEvent(iEvent++); - - //----------------------- digit2cluster & Digits2Trigger ------------------- - if (!loader->TreeR()) loader->MakeRecPointsContainer(); - - // tracking branch - dataCluster->MakeBranch("RC"); - dataCluster->SetTreeAddress("D,RC"); - recoCluster->Digits2Clusters(rawReader); - dataCluster->Fill("RC"); - - // trigger branch - dataCluster->MakeBranch("TC"); - dataCluster->SetTreeAddress("TC"); - trigDec->Trigger2Trigger(); - dataCluster->Fill("TC"); - - loader->WriteRecPoints("OVERWRITE"); - - //---------------------------- Track & TriggerTrack --------------------- - if (!loader->TreeT()) loader->MakeTracksContainer(); - - // trigger branch - dataEvent->MakeBranch("RL"); //trigger track - dataEvent->SetTreeAddress("RL"); - recoEvent->EventReconstructTrigger(); - dataEvent->Fill("RL"); - - // tracking branch - dataEvent->MakeBranch("RT"); //track - dataEvent->SetTreeAddress("RT"); - recoEvent->EventReconstruct(); - dataEvent->Fill("RT"); - - loader->WriteTracks("OVERWRITE"); - - //--------------------------- Resetting branches ----------------------- - dataCluster->ResetDigits(); - dataCluster->ResetRawClusters(); - dataCluster->ResetTrigger(); - - dataEvent->ResetRawClusters(); - dataEvent->ResetTrigger(); - dataEvent->ResetRecTracks(); - dataEvent->ResetRecTriggerTracks(); +//_____________________________________________________________________________ +void +AliMUONReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const +{ + /// This method is called by AliReconstruction if HasLocalReconstruction()==kTRUE + /// AND HasDigitConversion()==kTRUE + + AliCodeTimerAuto("") + AliDebug(1,""); + + if (!digitsTree || !clustersTree) + { + AliError(Form("Tree is null : digitsTree=%p clustersTree=%p", + digitsTree,clustersTree)); + return; } - loader->UnloadDigits(); - loader->UnloadRecPoints(); - loader->UnloadTracks(); - delete recoCluster; - delete recoEvent; - delete trigDec; + 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->IsCalibrated()) + { + Calibrate(*fDigitStore); + } + } + + FillTreeR(fTriggerStore,*clustersTree); } //_____________________________________________________________________________ -void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const +AliMUONVTriggerStore* +AliMUONReconstructor::TriggerStore() const { - 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; - TArrayF vertex(3); - - 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; - TParticle* particle = new TParticle(); - AliGenEventHeader* header = 0; - iEvent = runLoader->GetEventNumber(); - runLoader->GetEvent(iEvent); - - // vertex calculation (maybe it exists already somewhere else) - vertex[0] = vertex[1] = vertex[2] = 0.; - nPrimary = 0; - if ( (header = runLoader->GetHeader()->GenEventHeader()) ) { - header->PrimaryVertex(vertex); - } else { - runLoader->LoadKinematics("READ"); - runLoader->TreeK()->GetBranch("Particles")->SetAddress(&particle); - nPart = (Int_t)runLoader->TreeK()->GetEntries(); - for(Int_t iPart = 0; iPart < nPart; iPart++) { - runLoader->TreeK()->GetEvent(iPart); - if (particle->GetFirstMother() == -1) { - vertex[0] += particle->Vx(); - vertex[1] += particle->Vy(); - vertex[2] += particle->Vz(); - nPrimary++; - } - if (nPrimary) { - vertex[0] /= (double)nPrimary; - vertex[1] /= (double)nPrimary; - vertex[2] /= (double)nPrimary; - } + /// 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; } } - // 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(); // - - // loop over tracks - for (Int_t iRecTracks = 0; iRecTracks < nRecTracks; iRecTracks++) { - - // reading info from tracks - recTrack = (AliMUONTrack*) recTracksArray->At(iRecTracks); - - trackParam = recTrack->GetTrackParamAtVertex(); - - 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(vertex[2]); - theESDTrack->SetBendingCoor(vertex[1]); // calculate vertex at ESD or Tracking level ? - theESDTrack->SetNonBendingCoor(vertex[0]); - 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 - - // add global trigger pattern - if (nRecTracks != 0) - esd->SetTrigger(trigPat); - - // reset muondata - muonData->ResetRecTracks(); - muonData->ResetRecTriggerTracks(); - - //} // end loop on event - loader->UnloadTracks(); - if (!header) - runLoader->UnloadKinematics(); - delete theESDTrack; - delete muonData; - // delete particle; + return fTriggerStore; }