From 091e10eb7df8f9048e3604c3a4d2823a08908770 Mon Sep 17 00:00:00 2001 From: Attila Krasznahorkay <krasznaa@cern.ch> Date: Wed, 12 Mar 2014 13:32:46 +0100 Subject: [PATCH] Fixing the python configuration after the last change (AnalysisTriggerAlgs-00-01-35) --- .../AnalysisTriggerAlgs/cmt/requirements | 37 + .../AnalysisTriggerAlgs/doc/mainpage.h | 51 ++ .../python/AnalysisTriggerAlgsConfig.py | 101 +++ .../share/AnalysisTrigger_jobOptions.py | 6 + .../share/Data09MuCTPIFix_jobOfragment.py | 40 + .../share/FakeHLT_jobOptions.py | 0 .../src/MuCTPI_RDOToRoIBResult.cxx | 132 +++ .../src/MuCTPI_RDOToRoIBResult.h | 53 ++ .../src/RoIBResultToAOD.cxx | 762 ++++++++++++++++ .../AnalysisTriggerAlgs/src/RoIBResultToAOD.h | 103 +++ .../src/RoIBResultToxAOD.cxx | 851 ++++++++++++++++++ .../src/RoIBResultToxAOD.h | 128 +++ .../AnalysisTriggerAlgs_entries.cxx | 25 + .../components/AnalysisTriggerAlgs_load.cxx | 2 + 14 files changed, 2291 insertions(+) create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements new file mode 100644 index 00000000000..1a64b47ab89 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements @@ -0,0 +1,37 @@ +package AnalysisTriggerAlgs + +author Tadashi.Maeno <Tadashi.Maeno@cern.ch> +author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch> +author Alan Watson <Alan.Watson@cern.ch> +author Wolfgang Ehrenfeld <Wolfgang.Ehrenfeld@desy.de> + +private + +use AtlasPolicy AtlasPolicy-* +use GaudiInterface GaudiInterface-* External +use AtlasCLHEP AtlasCLHEP-* External +use AthenaKernel AthenaKernel-* Control +use AthenaBaseComps AthenaBaseComps-* Control +use StoreGate StoreGate-* Control +use EventInfo EventInfo-* Event +use xAODTrigger xAODTrigger-* Event/xAOD +use xAODTriggerCnv xAODTriggerCnv-* Event/xAOD + + +# LVL1 simulation packages: +use TrigT1Interfaces TrigT1Interfaces-* Trigger/TrigT1 +use TrigT1Result TrigT1Result-* Trigger/TrigT1 +use TrigT1CaloEvent TrigT1CaloEvent-* Trigger/TrigT1 +use TrigT1CaloToolInterfaces TrigT1CaloToolInterfaces-* Trigger/TrigT1 + +# Trigger configuration packages: +use TrigConfInterfaces TrigConfInterfaces-* Trigger/TrigConfiguration +use TrigConfL1Data TrigConfL1Data-* Trigger/TrigConfiguration + +use AnalysisTriggerEvent AnalysisTriggerEvent-* PhysicsAnalysis/AnalysisTrigger + +library AnalysisTriggerAlgs *.cxx components/*.cxx +apply_pattern component_library + +apply_pattern declare_joboptions files="*.py" +apply_pattern declare_python_modules files="*.py" diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h new file mode 100644 index 00000000000..8b7d0b37953 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** +@mainpage AnalysisTriggerAlgs Package + +@author Tadashi.Maeno <Tadashi.Maeno@cern.ch> +@author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch> +@author Alan Watson <Alan.Watson@cern.ch> +@author Wolfgang Ehrenfeld <Wolfgang.Ehrenfeld@desy.de> + +@section AnalysisTriggerAlgsIntro Introduction + +This package contains some algorithms to create Trigger ESD/AOD objects. + +@section AnalysisTriggerAlgsOverview Class Overview + The AnalysisTriggerAlgs package contains of following classes: + + - RoIBResultToAOD: convert ROIB::RoIBResult into CTP_Decision and LVL1_ROI. + One important feature is the rebuilding of the trigger type. + For the configuration see section \ref AnalysisTriggerAlgsJobOptions. + +@section AnalysisTriggerAlgsJobOptions Job Options + The algorithms of the AnalysisTriggerAlgs package can be configured using configurables. + For an example see AnalysisTrigger_jobOptions.py: + @include AnalysisTrigger_jobOptions.py + + Configuration classes for the RoIBResultToAOD algorithm are: + - AnalysisTriggerAlgsConfig::DefaultRoIBResultToAOD: common setup (do not use directly) + - AnalysisTriggerAlgsConfig::RoIBResultToAOD: configuration for running in a reconstruciton job + - AnalysisTriggerAlgsConfig::RoIBResultToAODLegacy: configuration for running in a reconstruciton job rebuilding the LVL1 trigger type + + The list of properties for each algorithm can be found here: + - @link RoIBResultToAOD::RoIBResultToAOD @endlink + +@section AnalysisTriggerAlgs Extra Pages + +- @ref used_AnalysisTriggerAlgs +- @ref requirements_AnalysisTriggerAlgs +*/ + +/** + @page used_AnalysisTriggerAlgs Used Packages + @htmlinclude used_packages.html +*/ + +/** + @page requirements_AnalysisTriggerAlgs Requirements + @include requirements +*/ diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py new file mode 100644 index 00000000000..208e1e489fe --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py @@ -0,0 +1,101 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + + +# Import the genConf made configurable: +from AnalysisTriggerAlgs.AnalysisTriggerAlgsConf import RoIBResultToxAOD as genConfRoIBResultToAOD + +class DefaultRoIBResultToAOD( genConfRoIBResultToAOD ): + + def __init__( self, name = "DefaultRoIBResultToAOD" ): + super( DefaultRoIBResultToAOD, self ).__init__( name ) + + # Get a logger: + from AthenaCommon.Logging import logging + log = logging.getLogger( 'RoIBResultToAOD' ) + + # + # Get the handle to the LVL1 config service: + # + from AthenaCommon.AppMgr import ServiceMgr + if hasattr( ServiceMgr, "TrigConfigSvc" ): + log.info( "Using ServiceMgr.TrigConfigSvc for LVL1 configuration" ) + lvl1ConfigSvc = ServiceMgr.TrigConfigSvc + elif hasattr( ServiceMgr, "LVL1ConfigSvc" ): + log.info( "Using ServiceMgr.LVL1ConfigSvc for LVL1 configuration" ) + lvl1ConfigSvc = ServiceMgr.LVL1ConfigSvc + else: + log.warning( "Did not find a configured LVL1 configuration service!" ) + log.warning( "Will assume that one called 'TrigConf::TrigConfigSvc/TrigConfigSvc'" ) + log.warning( "will be available at runtime. --> The job could crash later on!" ) + lvl1ConfigSvc = "TrigConf::TrigConfigSvc/TrigConfigSvc" # Hopefully it will be configured correctly + # later on in the job configuration... + + # Set the handle for the algorithm: + self.LVL1ConfigSvc = lvl1ConfigSvc + + # + # Set up the L1Calo tools: + # + from AthenaCommon.AppMgr import ToolSvc + + log.info( "will add L1EmTauTools instance to ToolSvc" ) + from TrigT1CaloTools.TrigT1CaloToolsConf import LVL1__L1EmTauTools + theL1EmTauTools = LVL1__L1EmTauTools( "L1EmTauTools" ) + theL1EmTauTools.LVL1ConfigSvc = lvl1ConfigSvc + ToolSvc += theL1EmTauTools + self.L1EmTauTools = ToolSvc.L1EmTauTools + + log.info( "will add L1JetTools instance to ToolSvc" ) + from TrigT1CaloTools.TrigT1CaloToolsConf import LVL1__L1JetTools + theL1JetTools = LVL1__L1JetTools( "L1JetTools" ) + theL1JetTools.LVL1ConfigSvc = lvl1ConfigSvc + ToolSvc += theL1JetTools + self.L1JetTools = ToolSvc.L1JetTools + + # + # Set up the muon RoI services: + # + if not hasattr( ServiceMgr, 'LVL1RPC::RPCRecRoiSvc' ): + log.info( "will setup LVL1RPC::RPCRecRoiSvc and add instance to ServiceMgr" ) + from TrigT1RPCRecRoiSvc.TrigT1RPCRecRoiConfig import RPCRecRoiConfig + ServiceMgr += RPCRecRoiConfig() + else: + log.info( "will _not_ add LVL1RPC::RPCRecRoiSvc instance to ServiceMgr since it already exists" ) + + if not hasattr( ServiceMgr, 'LVL1TGC::TGCRecRoiSvc' ): + log.info( "will setup LVL1RPC::TGCRecRoiSvc and add instance to ServiceMgr" ) + from TrigT1TGCRecRoiSvc.TrigT1TGCRecRoiConfig import TGCRecRoiConfig + ServiceMgr += TGCRecRoiConfig() + else: + log.info( "will _not_ add LVL1RPC::TGCRecRoiSvc instance to ServiceMgr since it already exists" ) + + + def setDefaults( self, handle ): + # switch off reading of Muon/Calo inputs if subsystem is not running + from AthenaCommon.DetFlags import DetFlags + handle.DoCalo = DetFlags.detdescr.Calo_on() + handle.DoMuon = DetFlags.detdescr.Muon_on() + +class RoIBResultToAOD( DefaultRoIBResultToAOD ): + + def __init__( self, name = "RoIBResultToAOD" ): + super( RoIBResultToAOD, self ).__init__( name ) + + def setDefaults( self, handle ): + DefaultRoIBResultToAOD.setDefaults( handle ) + +class RoIBResultToAODLegacy( DefaultRoIBResultToAOD ): + + def __init__(self, name = "RoIBResultToAODLegacy"): + super( RoIBResultToAODLegacy, self ).__init__( name ) + + # configure legacy trigger type building + self.EGammaItem = ["iEM25I","iEM15I","iMU10+EM15I"] + self.TauHadItem = ["iHA25I+TM30"] + self.JetItem = ["iJT200","i3JT90","i4JT65","iJT60+TM60"] + self.ESumItem = ["iHA25I+TM30","iJT60+TM60"] + self.HighMuItem = ["iMU20"] + self.LowMuItem = ["i2MU6","iMU10+EM15I"] + + def setDefaults( self, handle ): + DefaultRoIBResultToAOD.setDefaults( handle ) diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py new file mode 100644 index 00000000000..91d3785e806 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py @@ -0,0 +1,6 @@ + +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() + +from AnalysisTriggerAlgs.AnalysisTriggerAlgsConfig import RoIBResultToAOD +topSequence += RoIBResultToAOD("RoIBResultToAOD") diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py new file mode 100644 index 00000000000..d0ef7dd2376 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py @@ -0,0 +1,40 @@ +# $Id: Data09MuCTPIFix_jobOfragment.py 275499 2010-01-27 18:25:00Z krasznaa $ +# +# JobOptions fragment fixing the LVL1_ROI object in the ESD files for the +# problem in the MuCTPI. (Present for all 2009 collision data.) +# + +# Create a new logger, saving the old one if it already exists with this name: +if "logger" in dir(): orig_logger = logger +from AthenaCommon.Logging import logging +logger = logging.getLogger( "Data09MuCTPIFix" ) + +# Set up the trigger configuration: +from TriggerJobOpts.TriggerConfigGetter import TriggerConfigGetter +TriggerConfigGetter( "ReadPool" ) +logger.info( "Set up the trigger configuration service" ) + +# Access the algorithm sequence: +from AthenaCommon.AlgSequence import AlgSequence +theJob = AlgSequence() + +# +# Fix the RoIBResult object based on the MuCTPI_RDO: +# +from AnalysisTriggerAlgs.AnalysisTriggerAlgsConf import MuCTPI_RDOToRoIBResult +theJob += MuCTPI_RDOToRoIBResult() +theJob.MuCTPI_RDOToRoIBResult.RoIBOutputKey = "CorrectRoIBResult" +logger.info( "Added the RoIBResult object fixer algorithm" ) + +# +# Create the LVL1_ROI object with the correct muon content. +# Warning: The Calo RoIs should be taken from the original LVL1_ROI object! +# +from AnalysisTriggerAlgs.AnalysisTriggerAlgsConfig import RoIBResultToAOD +theJob += RoIBResultToAOD() +theJob.RoIBResultToAOD.DoCalo = False +theJob.RoIBResultToAOD.RoIBResultInputKey = "CorrectRoIBResult" +theJob.RoIBResultToAOD.LVL1_ROIOutputKey = "LVL1_ROI" + +# Restore the original logger if necessary: +if "orig_logger" in dir(): logger = orig_logger diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx new file mode 100644 index 00000000000..00ca790692e --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx @@ -0,0 +1,132 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: MuCTPI_RDOToRoIBResult.cxx 275499 2010-01-27 18:25:00Z krasznaa $ + +// STL include(s): +#include <iomanip> + +// Gaudi/Athena include(s): +#include "AthenaKernel/errorcheck.h" + +// Trigger include(s): +#include "TrigT1Result/MuCTPI_RDO.h" +#include "TrigT1Result/RoIBResult.h" +#include "TrigT1Result/MuCTPIResult.h" +#include "TrigT1Result/MuCTPIRoI.h" + +// Local include(s): +#include "MuCTPI_RDOToRoIBResult.h" + +MuCTPI_RDOToRoIBResult::MuCTPI_RDOToRoIBResult( const std::string& name, + ISvcLocator* pSvcLocator ) + : AthAlgorithm( name, pSvcLocator ) { + + declareProperty( "MuCTPIInputKey", m_muctpiInputKey = "MUCTPI_RDO" ); + declareProperty( "RoIBInputKey", m_roibInputKey = "RoIBResult" ); + declareProperty( "RoIBOutputKey", m_roibOutputKey = "CorrectRoIBResult" ); +} + +StatusCode MuCTPI_RDOToRoIBResult::execute() { + + ATH_MSG_DEBUG( "Executing the MuCTPI RoI fixer algorithm" ); + + // + // Retrieve the (hopefully) correct MuCTPI_RDO object: + // + const MuCTPI_RDO* muctpi_rdo = 0; + CHECK( evtStore()->retrieve( muctpi_rdo, m_muctpiInputKey ) ); + ATH_MSG_VERBOSE( "Retrieved the MuCTPI_RDO object with key: " + << m_muctpiInputKey ); + + // + // Retrieve the (muon-wise) wrong RoIBResult object: + // + const ROIB::RoIBResult* roibresult = 0; + CHECK( evtStore()->retrieve( roibresult, m_roibInputKey ) ); + ATH_MSG_VERBOSE( "Retrieved the old RoIBResult object with key:" + << m_roibInputKey ); + + // Create the correct RoI vector from the RDO data: + ATH_MSG_VERBOSE( "Now creating the correct RoIs..." ); + std::vector< ROIB::MuCTPIRoI > roi_vector; + + uint32_t bcid = multiplicityBCID( muctpi_rdo->candidateMultiplicity() ); + + // + // Loop over all "data words" and select the ones that should've been + // sent ot LVL2: + // + std::vector< uint32_t >::const_iterator dword_itr = muctpi_rdo->dataWord().begin(); + std::vector< uint32_t >::const_iterator dword_end = muctpi_rdo->dataWord().end(); + for( ; dword_itr != dword_end; ++dword_itr ) { + + // Select which candidates should've gone to LVL2: + if( roiBCID( *dword_itr ) != bcid ) continue; + if( ! roiAccepted( *dword_itr ) ) continue; + + // Save the candidate: + roi_vector.push_back( ROIB::MuCTPIRoI( toRoIWord( *dword_itr ) ) ); + ATH_MSG_VERBOSE( " - Processed data word: 0x" << std::hex << std::setw( 8 ) + << std::setfill( '0' ) << *dword_itr ); + } + + // + // Create the new MuCTPI result: + // + ROIB::MuCTPIResult newResult( roibresult->muCTPIResult().header(), + roibresult->muCTPIResult().trailer(), + roi_vector ); + + // + // Create and save the new RoIBResult object: + // + ROIB::RoIBResult* new_roibresult = new ROIB::RoIBResult( newResult, + roibresult->cTPResult(), + roibresult->jetEnergyResult(), + roibresult->eMTauResult() ); + CHECK( evtStore()->record( new_roibresult, m_roibOutputKey ) ); + ATH_MSG_VERBOSE( "Saved the fixed RoIBResult object with key: " + << m_roibOutputKey ); + + return StatusCode::SUCCESS; +} + +/** + * @param multi_word Multiplicity word from the MuCTPI_RDO object + * @returns The BCID stored in the multiplicity word + */ +uint32_t MuCTPI_RDOToRoIBResult::multiplicityBCID( uint32_t multi_word ) { + + return ( ( multi_word >> 18 ) & 0x7 ); +} + +/** + * @param data_word Data word from the MuCTPI_RDO object + * @returns The RoI word created from the data word + */ +uint32_t MuCTPI_RDOToRoIBResult::toRoIWord( uint32_t data_word ) { + + return ( ( ( data_word & 0x8000000 ) >> 4 ) | ( ( data_word & 0x3fe0000 ) >> 3 ) | + ( data_word & 0x3fff ) ); +} + +/** + * @param data_word Data word from the MuCTPI_RDO object + * @returns the BCID stored in the data word + */ +uint32_t MuCTPI_RDOToRoIBResult::roiBCID( uint32_t data_word ) { + + return ( ( data_word >> 14 ) & 0x7 ); +} + +/** + * @param data_word Data word from the MuCTPI_RDO object + * @returns <code>true</code> if the candidate was destined to go to LVL2, + * <code>false</code> otherwise + */ +bool MuCTPI_RDOToRoIBResult::roiAccepted( uint32_t data_word ) { + + return ( ( data_word >> 26 ) & 0x1 ); +} diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h new file mode 100644 index 00000000000..5165d0f4e29 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h @@ -0,0 +1,53 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: MuCTPI_RDOToRoIBResult.h 275499 2010-01-27 18:25:00Z krasznaa $ +#ifndef ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H +#define ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H + +// STL include(s): +#include <string> + +// Gaudi/Athena include(s): +#include "AthenaBaseComps/AthAlgorithm.h" + +/** + * @short Algorithm fixing the muon RoI information in the data + * + * This algorithm can create a fixed ROIB::RoIBResult object from the + * incorrect object in the data, plus the MuCTPI_RDO readout data. + * + * @author Attila Krasznahorkay Jr. + * + * $Revision: 275499 $ + * $Date: 2010-01-27 19:25:00 +0100 (Wed, 27 Jan 2010) $ + */ +class MuCTPI_RDOToRoIBResult : public AthAlgorithm { + +public: + /// Regular algorithm constructor + MuCTPI_RDOToRoIBResult( const std::string& name, ISvcLocator* pSvcLocator ); + + /// Regular algorithm execure function + virtual StatusCode execute(); + +private: + /// Extract the BCID stored in the multiplicity word + static uint32_t multiplicityBCID( uint32_t multi_word ); + /// Transform a data word into an RoI word + static uint32_t toRoIWord( uint32_t data_word ); + /// Extract the BCID stored in the data word + static uint32_t roiBCID( uint32_t data_word ); + /// Extract whether the candidate was accepted to be sent to LVL2 + static bool roiAccepted( uint32_t data_word ); + + std::string m_muctpiInputKey; ///< Key of the MuCTPI_RDO object + std::string m_roibInputKey; ///< Key of the old (incorrect) RoIBResult object + std::string m_roibOutputKey; ///< Key of the new (correct) RoIBResult object + +}; // class MuCTPI_RDOToRoIBResult + +#endif // ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx new file mode 100644 index 00000000000..d7a1022abf2 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx @@ -0,0 +1,762 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RoIBResultToAOD.cxx 587265 2014-03-12 09:45:45Z krasznaa $ + +// STL include(s): +#include <algorithm> +#include <cmath> + +// Gaudi/Athena include(s): +#include "AthenaKernel/errorcheck.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "EventInfo/EventInfo.h" +#include "EventInfo/EventID.h" +#include "EventInfo/EventType.h" +#include "EventInfo/TriggerInfo.h" + +// LVL1 trigger include(s): +#include "TrigT1Interfaces/TriggerTypeWord.h" +#include "TrigT1Interfaces/RecMuonRoI.h" +#include "TrigT1Interfaces/RecMuonRoiSvc.h" +#include "TrigT1Interfaces/RecEmTauRoI.h" +#include "TrigT1Interfaces/RecJetRoI.h" +#include "TrigT1Interfaces/RecEnergyRoI.h" +#include "TrigT1Interfaces/JEPRoIDecoder.h" +#include "TrigT1Interfaces/TrigT1CaloDefs.h" +#include "TrigT1Result/RoIBResult.h" +#include "TrigT1Result/CTPResult.h" +#include "TrigT1CaloToolInterfaces/IL1EmTauTools.h" +#include "TrigT1CaloToolInterfaces/IL1JetTools.h" +#include "TrigT1CaloEvent/TriggerTowerCollection.h" +#include "TrigT1CaloEvent/JetElementCollection.h" +#include "TrigT1CaloEvent/CPMTower.h" +#include "TrigT1CaloEvent/JetInput.h" +#include "TrigConfL1Data/L1DataDef.h" +#include "TrigConfL1Data/TriggerThreshold.h" + +// Trigger configuration interface includes: +#include "TrigConfL1Data/CTPConfig.h" +#include "TrigConfL1Data/Menu.h" +#include "TrigConfL1Data/TriggerItem.h" + +// Include for the configuration service: +#include "TrigConfInterfaces/ILVL1ConfigSvc.h" + +// LVL1 AOD event include(s): +#include "AnalysisTriggerEvent/CTP_Decision.h" +#include "AnalysisTriggerEvent/LVL1_ROI.h" + +// Local include(s): +#include "RoIBResultToAOD.h" + +using namespace TrigConf; + +RoIBResultToAOD::RoIBResultToAOD( const std::string& name, ISvcLocator* pSvcLocator ) + : AthAlgorithm( name, pSvcLocator ), + m_configSvc( "TrigConf::LVL1ConfigSvc/LVL1ConfigSvc", name ), + m_recRPCRoiSvc( LVL1::ID_RecRpcRoiSvc, name ), + m_recTGCRoiSvc( LVL1::ID_RecTgcRoiSvc, name ), + m_EmTauTool( "LVL1::L1EmTauTools/L1EmTauTools" ), + m_JetTool( "LVL1::L1JetTools/L1JetTools" ) { + + // services + declareProperty( "LVL1ConfigSvc", m_configSvc, "LVL1 Config Service"); + declareProperty( "RecRpcRoiSvc", m_recRPCRoiSvc, "RPC Rec Roi Service"); + declareProperty( "RecTgcRoiSvc", m_recTGCRoiSvc, "TGC Rec Roi Service"); + + // tools + declareProperty( "L1EmTauTools", m_EmTauTool, + "Tool for calculation of EmTau trigger sums per RoI"); + declareProperty( "L1JetTools", m_JetTool, + "Tool for calculation of Jet cluster sums per RoI"); + + // Properties: input selection + declareProperty( "DoCalo", m_doCalo = true, "Use inputs from Calo system" ); + declareProperty( "DoMuon", m_doMuon = true, "Use inputs from Muon system" ); + + // Properties: rebuilding trigger type + declareProperty( "EGammaItem", m_egammaItem, + "List of LVL1 items for e/gamma trigger type" ); + declareProperty( "TauHadItem", m_tauhadItem, + "List of LVL1 items for tau trigger type" ); + declareProperty( "JetItem", m_jetItem, + "List of LVL1 items for jet trigger type" ); + declareProperty( "ESumItem", m_esumItem, + "List of LVL1 items for energy sum trigger type" ); + declareProperty( "HighMuItem", m_highmuItem, + "List of LVL1 items for high pt muon trigger type" ); + declareProperty( "LowMuItem", m_lowmuItem, + "List of LVL1 items for low pt muon trigger type" ); + + // Properties: StoreGate keys + m_TriggerTowerLocation = LVL1::TrigT1CaloDefs::TriggerTowerLocation; + m_JetElementLocation = LVL1::TrigT1CaloDefs::JetElementLocation; + declareProperty( "TriggerTowerLocation", m_TriggerTowerLocation ) ; + declareProperty( "JetElementLocation", m_JetElementLocation ) ; + declareProperty( "RoIBResultInputKey", m_roibInputKey = "RoIBResult" ); + declareProperty( "LVL1_ROIOutputKey", m_lvl1RoIOutputKey = "LVL1_ROI" ); + + m_retrievedEmTauTool = false; + m_retrievedJetTool = false; + +} + +// Initialize +StatusCode RoIBResultToAOD::initialize() { + + ATH_MSG_INFO( "initializing " << name() + << " - package version " << PACKAGE_VERSION ); + + // Print system info + if( m_doCalo == false ) { + ATH_MSG_WARNING( "Inputs from LVL1 Calo systems switched off" ); + } + if( m_doMuon == false ) { + ATH_MSG_WARNING( "Inputs from LVL1 Muon systems switched off" ); + } + + // Connect to the LVL1ConfigSvc for the trigger configuration: + CHECK( m_configSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_configSvc.typeAndName() ); + + if( m_doMuon ) { + + // Get the RPC RecRoI service + CHECK( m_recRPCRoiSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_recRPCRoiSvc.typeAndName() ); + + // Get the TGC RecRoI service + CHECK( m_recTGCRoiSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_recTGCRoiSvc.typeAndName() ); + + } // if (m_doMuon) + + if( m_doCalo ) { + + // Get tools + CHECK( m_EmTauTool.retrieve() ); + ATH_MSG_DEBUG( "Got " << m_EmTauTool.typeAndName() ); + m_retrievedEmTauTool = true; + + CHECK( m_JetTool.retrieve() ); + ATH_MSG_DEBUG( "Got " << m_JetTool.typeAndName() ); + m_retrievedJetTool = true; + + } // if (m_doCalo) + + return StatusCode::SUCCESS; +} + +// finalize +StatusCode RoIBResultToAOD::finalize() { + + ATH_MSG_INFO( "Finalizing " << name() + << " - package version " << PACKAGE_VERSION ); + + return StatusCode::SUCCESS; +} + +// execute +StatusCode RoIBResultToAOD::execute() { + + ATH_MSG_DEBUG( "in execute()" ); + + /////////////////////////////////////////////////////////////////////////// + // build CTP decision + if( buildCTP_Decision().isFailure() ) { + ATH_MSG_WARNING( "Problems building CTP_Decision" ); + } + + /////////////////////////////////////////////////////////////////////////// + // Trigger Info + + // retrieve event info + const DataHandle< EventInfo > eventInfoBeg; + const DataHandle< EventInfo > eventInfoEnd; + CHECK( evtStore()->retrieve( eventInfoBeg, eventInfoEnd ) ); + if( eventInfoBeg == eventInfoEnd ) { + ATH_MSG_ERROR( "No event info objects" ); + return StatusCode::RECOVERABLE; + } + + // get key + const std::string eventInfoKey = eventInfoBeg.key(); + + // build TriggerInfo + EventInfo* eventInfo = const_cast< EventInfo* >( eventInfoBeg.cptr() ); + TriggerInfo* tInfo = eventInfo->trigger_info(); + TriggerInfo* triggerInfo; + if( tInfo != 0 ) { + triggerInfo = new TriggerInfo( *tInfo ); + } else { + triggerInfo = new TriggerInfo( 0, 0, 0, + std::vector< TriggerInfo::number_type>( 0 ), + std::vector< TriggerInfo::number_type>( 0 ), + std::vector< TriggerInfo::StreamTag>( 0 ) ); + } + + // set TriggerInfo + eventInfo->setTriggerInfo( triggerInfo ); + + // dump + ATH_MSG_DEBUG( MSG::dec << "EventInfo:" << eventInfoKey ); + ATH_MSG_DEBUG( *( eventInfo->event_ID() ) ); + ATH_MSG_DEBUG( "[TimeStamp] = " << eventInfo->event_ID()->time_stamp() ); + ATH_MSG_DEBUG( "[Type] = " << eventInfo->event_type()->user_type() ); + ATH_MSG_DEBUG( "[BitMask]" ); + for( EventType::BitMaskIterator bitIt = eventInfo->event_type()->bit_mask_begin(); + bitIt != eventInfo->event_type()->bit_mask_end(); ++bitIt ) { + ATH_MSG_DEBUG( *bitIt ); + } + + if( triggerInfo != 0 ) { + ATH_MSG_DEBUG( MSG::hex << "[L1ID] = "<< triggerInfo->extendedLevel1ID() ); + ATH_MSG_DEBUG( "[TriggerType] = "<< triggerInfo->level1TriggerType() ); + ATH_MSG_DEBUG( "[L1Info] = "<< triggerInfo->level1TriggerInfo() ); + ATH_MSG_DEBUG( "[L2Info] = "<< triggerInfo->level2TriggerInfo() ); + ATH_MSG_DEBUG( "[EFInfo]" ); + const std::vector< TriggerInfo::number_type >& efInfo = triggerInfo->eventFilterInfo(); + for( std::vector< TriggerInfo::number_type >::const_iterator itEF = efInfo.begin(); + itEF != efInfo.end(); ++itEF ) { + ATH_MSG_DEBUG( *itEF ); + } + } + + /////////////////////////////////////////////////////////////////////////// + // build LVL1 ROI + + LVL1_ROI *lvl1ROI = new LVL1_ROI; + + /////////////////////////////////////////////////////////////////////////// + // retrive L1 result + + const ROIB::RoIBResult *result = 0; + if( evtStore()->retrieve( result, m_roibInputKey ).isFailure() ) { + ATH_MSG_WARNING( "Could not retrieve RoIBResult. Building empty LVL1_ROI" ); + result = 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Muon ROI + + if( m_doMuon == true ) addMuonRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // EmTau ROI + + if( m_doCalo == true ) addEmTauRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // JetEnergy ROI + + if( m_doCalo == true ) addJetEnergyRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // record LVL1 ROI + + CHECK( evtStore()->record( lvl1ROI, m_lvl1RoIOutputKey ) ); + CHECK( evtStore()->setConst( lvl1ROI ) ); + + return StatusCode::SUCCESS; +} + +StatusCode RoIBResultToAOD::buildCTP_Decision() { + + ATH_MSG_DEBUG( "building CTP decision" ); + + CTP_Decision* ctpDecision = new CTP_Decision; + + // retrive L1 result + const ROIB::RoIBResult *result = 0; + if( evtStore()->retrieve( result, m_roibInputKey ).isSuccess() ) { + + // Trigger Type Word + bool triggerTypeLegacyFlag = false; + uint32_t triggerTypeWord = result->cTPResult().header().triggerType(); + + if( triggerTypeWord == 0 ) { // switch to legacy mode + ATH_MSG_DEBUG( "Building TriggerType word" ); + triggerTypeWord = LVL1::TriggerTypeWord::Physics | + LVL1::TriggerTypeWord::PriorityLevel; + triggerTypeLegacyFlag = true; + } + + // store TAV vector in CTP decision object + const std::vector< ROIB::CTPRoI > tav = result->cTPResult().TAV(); + for( size_t i( 0 ); i < tav.size(); ++i ) { + ctpDecision->setWord( i, tav[ i ].roIWord() ); + } + + // search for passed items in TAV vector from CTP result + const std::bitset< 256 > items = ROIB::convertToBitset( tav ); + + for(TrigConf::ItemContainer::const_iterator item = m_configSvc->ctpConfig()->menu().items().begin(); + item != m_configSvc->ctpConfig()->menu().items().end(); ++item ) { + if( items[ ( *item )->ctpId() ] ) { + // add item name to CTP_Decision + const std::string& itemName = ( *item )->name(); + ctpDecision->setItem( itemName ); + ATH_MSG_VERBOSE( "Item : " << itemName ); + + if( triggerTypeLegacyFlag ) { + ///////// compute Trigger Type Word + ///////// This is temporary implementation for DC2 and will be moved to + ///////// CTP simulation + // e/gamma + if( m_egammaItem.end() != std::find( m_egammaItem.begin(), m_egammaItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::Egamma; + + // tau/hadron + if( m_tauhadItem.end() != std::find( m_tauhadItem.begin(), m_tauhadItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::TauHdr; + + // jet + if( m_jetItem.end() != std::find( m_jetItem.begin(), m_jetItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::Jet; + + // energy sum + if( m_esumItem.end() != std::find( m_esumItem.begin(), m_esumItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::EnergySum; + + // high pT muon + if( m_highmuItem.end() != std::find( m_highmuItem.begin(), m_highmuItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::HighPtMuon; + + // low pT muon + if( m_lowmuItem.end() != std::find( m_lowmuItem.begin(), m_lowmuItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::LowPtMuon; + } // if (triggerTypeLegacyFlag) + } // if (items[(*item)->ctpId()]) + } // for + + // set Trigger Type Word + ctpDecision->setTriggerTypeWord( triggerTypeWord ); + ATH_MSG_DEBUG( "CTP_Decision: \n" + ctpDecision->dump() ); + + } else { + ATH_MSG_WARNING( "Could not retrieve RoIBResult, building empty CTP_Decision" ); + } + + // record CTP Decision + CHECK( evtStore()->record( ctpDecision, "CTP_Decision" ) ); + CHECK( evtStore()->setConst( ctpDecision ) ); + + return StatusCode::SUCCESS; +} + +void RoIBResultToAOD::addEmTauRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "building EmTauRoI" ); + + // empty input + if( result == 0 ) return; + + // Digit scale for calorimeter trigger + float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV; + ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale ); + + /** Get EmTau Thresholds from configSvc. Also fill a map of threshold names while + we are here - will be useful later */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector< TrigConf::TriggerThreshold* > caloThresholds; + std::map< int, std::string > thresholdNames; + for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::emType() || ( *it )->type() == L1DataDef::tauType() ) { + caloThresholds.push_back( *it ); + thresholdNames.insert( std::map< int, std::string >::value_type( ( *it )->thresholdNumber(), ( *it )->name() ) ); + } + } + + // Tool to reconstruct EM/tau cluster & isolation sums + // - need to form tower map for RoI reconstruction + const DataVector< LVL1::TriggerTower >* storedTTs; + std::map< int, LVL1::CPMTower* > cpmtowers; + if( m_retrievedEmTauTool ) { + if( evtStore()->contains< TriggerTowerCollection >( m_TriggerTowerLocation ) ) { + StatusCode sc = evtStore()->retrieve( storedTTs, m_TriggerTowerLocation ); + if( sc.isSuccess() ) m_EmTauTool->mapTowers( storedTTs, &cpmtowers ); + else ATH_MSG_WARNING( "Error retrieving TriggerTowers" ); + } + else ATH_MSG_DEBUG( "No TriggerTowerCollection found at " + << m_TriggerTowerLocation ); + } + + // get EmTau Result + const std::vector< ROIB::EMTauResult >& emtauResult = result->eMTauResult(); + + // reconstruct ROI + ATH_MSG_DEBUG( "EmTau ROI" ); + std::vector< ROIB::EMTauResult >::const_iterator itEMR = emtauResult.begin(); + std::vector< ROIB::EMTauResult >::const_iterator itEMRe = emtauResult.end(); + for( ; itEMR != itEMRe; ++itEMR ) { + const std::vector< ROIB::EMTauRoI >& emtauRoIV = itEMR->roIVec(); + std::vector< ROIB::EMTauRoI >::const_iterator itEM = emtauRoIV.begin(); + std::vector< ROIB::EMTauRoI >::const_iterator itEMe = emtauRoIV.end(); + for( ; itEM != itEMe; ++itEM ) { + + uint32_t roIWord = itEM->roIWord(); + ATH_MSG_DEBUG( "About to create RecEmTauRoI : " << MSG::hex + << std::setw( 8 ) << roIWord << MSG::dec ); + + // RecRoI + LVL1::RecEmTauRoI recRoI( roIWord, &caloThresholds ); + + // AOD component + // ATLAS standard phi convention differs from L1 hardware convention + double roiPhi = recRoI.phi(); + if( roiPhi > M_PI ) roiPhi -= 2 * M_PI; + EmTau_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFFF ); + + // fired thresholds + std::vector< unsigned int >* thrV = recRoI.thresholdsPassed(); + std::vector< unsigned int >::const_iterator itTh = thrV->begin(); + std::vector< unsigned int >::const_iterator itThE = thrV->end(); + for( ; itTh != itThE; ++itTh ) { + double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV; + std::string thrName = "NameNotFound"; + if ( thresholdNames.find( *itTh - 1 ) != thresholdNames.end() ) { + thrName = thresholdNames[ *itTh - 1 ]; + } + + roi.addThresholdValue( thrValue ); + roi.addThresholdName( thrName ); + + ATH_MSG_DEBUG( "EmTau Thr : " << thrName + << ", value = " << thrValue ); + } + delete thrV; + + // Cluster ET values, reconstructed from TriggerTowers + if( m_retrievedEmTauTool ) { + m_EmTauTool->formSums( roIWord, &cpmtowers ); + roi.setCore( m_EmTauTool->Core() * caloTrigScale ); + roi.setEMClus( m_EmTauTool->EMClus() * caloTrigScale ); + roi.setTauClus( m_EmTauTool->TauClus() * caloTrigScale ); + roi.setEMIsol( m_EmTauTool->EMIsol() * caloTrigScale ); + roi.setHadIsol( m_EmTauTool->HadIsol() * caloTrigScale ); + roi.setHadCore( m_EmTauTool->HadCore() * caloTrigScale ); + } + + lvl1ROI->addEmTauROI( roi ); + } + } + + for( std::map< int, LVL1::CPMTower* >::iterator i = cpmtowers.begin(); + i != cpmtowers.end(); ++i ) delete i->second; + + return; +} + +void RoIBResultToAOD::addJetEnergyRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "building JetEnergyRoI" ); + + // empty input + if( result == 0 ) return; + + // Digit scale for calorimeter trigger + float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV; + ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale ); + + /** Get Jet/Energy Thresholds from configSvc. Also fill maps of threshold names while + we are here - will be useful later. + + Unfortunately there are 3 types of jet threshold and 3 types of ET trigger threshold, + so this bit doesn't look very elegant */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector<TrigConf::TriggerThreshold*> jetThresholds; + std::vector<TrigConf::TriggerThreshold*> energyThresholds; + std::vector<TrigConf::TriggerThreshold*> jetEnergyThresholds; + std::map<int, std::string> jetNames; + std::map<int, std::string> jfNames; + std::map<int, std::string> jbNames; + std::map<int, std::string> xeNames; + std::map<int, std::string> teNames; + std::map<int, std::string> xsNames; + std::map<int, std::string> jeNames; + + for( std::vector<TrigConf::TriggerThreshold*>::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::jetType() ) { + jetThresholds.push_back( *it ); + jetNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jfType() ) { + jetThresholds.push_back( *it ); + jfNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jbType() ) { + jetThresholds.push_back( *it ); + jbNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::xeType() ) { + energyThresholds.push_back( *it ); + xeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::teType() ) { + energyThresholds.push_back( *it ); + teNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::xsType() ) { + energyThresholds.push_back( *it ); + xsNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jeType() ) { + jetEnergyThresholds.push_back( *it ); + jeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + } + + // Tool to reconstruct Jet cluster ET sums + // - form input map ready for analysis + const DataVector< LVL1::JetElement >* storedJEs; + std::map< int, LVL1::JetInput* > jetInputs; + if( m_retrievedJetTool ) { + if( evtStore()->contains< JetElementCollection >( m_JetElementLocation ) ) { + StatusCode sc = evtStore()->retrieve( storedJEs, m_JetElementLocation ); + if( sc.isSuccess() ) m_JetTool->mapJetInputs( storedJEs, &jetInputs ); + else ATH_MSG_WARNING( "Error retrieving JetElements" ); + } + else ATH_MSG_DEBUG( "No JetElementCollection found at " + << m_JetElementLocation ); + } + + // get JetEnergy Result + const std::vector< ROIB::JetEnergyResult >& jetenergyResult = result->jetEnergyResult(); + + // reconstruct ROI + std::vector< ROIB::JetEnergyResult >::const_iterator itJETR = jetenergyResult.begin(); + std::vector< ROIB::JetEnergyResult >::const_iterator itJETRe = jetenergyResult.end(); + for( ; itJETR != itJETRe; ++itJETR ) { + const std::vector< ROIB::JetEnergyRoI >& jetenergyRoIV = itJETR->roIVec(); + std::vector< ROIB::JetEnergyRoI >::const_iterator itJET = jetenergyRoIV.begin(); + std::vector< ROIB::JetEnergyRoI >::const_iterator itJETe = jetenergyRoIV.end(); + for( ; itJET != itJETe; ++itJET ) { + uint32_t roIWord = itJET->roIWord(); + + ATH_MSG_DEBUG( "Jet RoI, RoIWord = " << MSG::hex << std::setw( 8 ) + << roIWord << MSG::dec ); + + // RoI type + LVL1::JEPRoIDecoder conv; + int roiType = conv.roiType( roIWord ); + + // Jet ROI + if( roiType == LVL1::TrigT1CaloDefs::JetRoIWordType ) { + // RecRoI + LVL1::RecJetRoI recRoI( roIWord, &jetThresholds ); + + // AOD component + // Convert to ATLAS phi convention + double roiPhi = recRoI.phi(); + if( roiPhi > M_PI ) roiPhi -= 2 * M_PI; + Jet_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFF ); + + // fired Jet thresholds + std::vector< unsigned int >* thrV = recRoI.thresholdsPassed(); + std::vector< unsigned int >::const_iterator itTh = thrV->begin(); + std::vector< unsigned int >::const_iterator itThE = thrV->end(); + for( ; itTh != itThE; ++itTh ) { + double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV; + std::string thrName = "NameNotFound"; + if (!recRoI.isForwardJet()) { + if (jetNames.find(*itTh-1) != jetNames.end()) thrName = jetNames[*itTh-1]; + } + else if (recRoI.eta() > 0) { + if (jfNames.find(*itTh-1) != jfNames.end()) thrName = jfNames[*itTh-1]; + } + else { + if (jbNames.find(*itTh-1) != jbNames.end()) thrName = jbNames[*itTh-1]; + } + + roi.addThresholdValue( thrValue ); + roi.addThresholdName( thrName ); + + ATH_MSG_DEBUG( "Jet Thr : " << thrName + << ", value = " << thrValue ); + } + delete thrV; + + // Jet Cluster ET sums + if (m_retrievedJetTool) { + m_JetTool->formSums(roIWord, &jetInputs); + roi.setET4x4(m_JetTool->ET4x4()*caloTrigScale); + roi.setET6x6(m_JetTool->ET6x6()*caloTrigScale); + roi.setET8x8(m_JetTool->ET8x8()*caloTrigScale); + } + + lvl1ROI->addJetROI(roi); + } + // Jet ET ROI + else if( roiType == LVL1::TrigT1CaloDefs::JetEtRoIWordType ) { + // AOD component + JetET_ROI roi( roIWord, roIWord & 0xF ); + + // fired Jet ET thresholds + for( unsigned int i = 0; i < TrigT1CaloDefs::numOfJetEtSumThresholds; ++i ) { + if( ( roIWord >> i ) & 0x1 ) { + std::string thrName = "NameNotFound"; + if (jeNames.find(i) != jfNames.end()) thrName = jeNames[i]; + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "JetEt Thr : " << thrName ); + } + } + + lvl1ROI->addJetETROI(roi); + } + // EnergySum ROI + else if ( roiType == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) { + uint32_t roiWord0 = roIWord; + ATH_MSG_DEBUG( "ET RoIWord 0 : " << MSG::hex << std::setw( 8 ) + << roiWord0 << MSG::dec ); + ++itJET; + uint32_t roiWord1 = itJET->roIWord(); + ATH_MSG_DEBUG( "ET RoIWord 1 : " << MSG::hex << std::setw( 8 ) + << roiWord1 << MSG::dec ); + ++itJET; + uint32_t roiWord2 = itJET->roIWord(); + ATH_MSG_DEBUG( "ET RoIWord 2 : " << MSG::hex << std::setw( 8 ) + << roiWord2 << MSG::dec ); + + // RecRoI + LVL1::RecEnergyRoI recRoI( roiWord0, roiWord1, roiWord2, &energyThresholds ); + + // Overflow bits + unsigned int overflows = 0; + if (conv.energyOverflow(roiWord0)) overflows |= 0x1; + if (conv.energyOverflow(roiWord1)) overflows |= 0x2; + if (conv.energyOverflow(roiWord2)) overflows |= 0x4; + + // AOD component + EnergySum_ROI roi( roiWord0, roiWord1, roiWord2, + recRoI.energyX() * caloTrigScale, + recRoI.energyY() * caloTrigScale, + recRoI.energyT() * caloTrigScale, + ( roiWord1 >> 16 ) & 0xFF, ( roiWord2 >> 16 ) & 0xFF, + ( roiWord0 >> 16 ) & 0xFF, overflows ); + + // fired summed ET thresholds + std::vector< unsigned int >* thrEtMiss = recRoI.etMissThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThEtMiss = thrEtMiss->begin(); + for( ; itThEtMiss != thrEtMiss->end(); ++itThEtMiss ) { + std::string thrName = "NameNotFound"; + if( xeNames.find( *itThEtMiss - 1 ) != xeNames.end() ) { + thrName = xeNames[ *itThEtMiss - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "ETmiss threshold : " << thrName ); + } + delete thrEtMiss; + + // fired missing ET thresholds + std::vector< unsigned int >* thrSumEt = recRoI.sumEtThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThSumEt = thrSumEt->begin(); + for( ; itThSumEt != thrSumEt->end(); ++itThSumEt ) { + std::string thrName = "NameNotFound"; + if( teNames.find( *itThSumEt - 1 ) != teNames.end() ) { + thrName = teNames[ *itThSumEt - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "SumET threshold : " << thrName ); + } + delete thrSumEt; + + // fired missing ET significance thresholds + std::vector< unsigned int >* thrMETSig = recRoI.mEtSigThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThMETSig = thrMETSig->begin(); + for( ; itThMETSig != thrMETSig->end(); ++itThMETSig ) { + std::string thrName = "NameNotFound"; + if( xsNames.find( *itThMETSig - 1 ) != xsNames.end() ) { + thrName = xsNames[ *itThMETSig - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "METSig threshold : " << thrName ); + } + delete thrMETSig; + + lvl1ROI->addEnergySumROI(roi); + } + } + } + + for( std::map< int, LVL1::JetInput* >::iterator i = jetInputs.begin(); + i != jetInputs.end(); ++i ) { + delete i->second; + } + + return; +} + +void RoIBResultToAOD::addMuonRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "in buildMuonRoI()" ); + + // empty input + if( result == 0 ) return; + + /** Get Muon Thresholds from configSvc. Also fill a map of threshold names while + we are here - will be useful later */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector< TrigConf::TriggerThreshold* > muonThresholds; + std::map< int, std::string > thresholdNames; + for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::muonType() ) { + muonThresholds.push_back( *it ); + thresholdNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + } + + // get Muon ROI + const std::vector< ROIB::MuCTPIRoI >& muonRoIV = result->muCTPIResult().roIVec(); + + // reconstruct ROI + ATH_MSG_DEBUG( "Muon ROI" ); + std::vector< ROIB::MuCTPIRoI >::const_iterator itMU = muonRoIV.begin(); + std::vector< ROIB::MuCTPIRoI >::const_iterator itMUe = muonRoIV.end(); + for ( ; itMU != itMUe; ++itMU ) { + + uint32_t roIWord = itMU->roIWord(); + + ATH_MSG_DEBUG( MSG::hex << std::setw( 8 ) << roIWord ); + + if( ( m_recRPCRoiSvc == false ) || ( m_recTGCRoiSvc == false ) ) { + continue; + } + + // RecRoI + LVL1::RecMuonRoI recRoI( roIWord, m_recRPCRoiSvc.operator->(), + m_recTGCRoiSvc.operator->(), &muonThresholds ); + + double thrValue = recRoI.getThresholdValue() * CLHEP::GeV; + int index = recRoI.getThresholdNumber() - 1; + std::string thrName = "NameNotFound"; + if( thresholdNames.find(index) != thresholdNames.end() ) { + thrName = thresholdNames[ index ]; + } + + // AOD component + Muon_ROI roi( roIWord, recRoI.eta(), recRoI.phi(), thrName, thrValue ); + + lvl1ROI->addMuonROI( roi ); + ATH_MSG_DEBUG( "Muon Thr : " << thrName << ", value = " << thrValue ); + + } // for ( ; itMU != itMUe; ++itMU ) + + return; +} diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h new file mode 100644 index 00000000000..ee85e2ae954 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h @@ -0,0 +1,103 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RoIBResultToAOD.h 452138 2011-08-04 11:10:41Z krasznaa $ +#ifndef ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H +#define ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H + +// Gaudi/Athena include(s): +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ToolHandle.h" +#include "StoreGate/DataHandle.h" + +// Forward declaration(s): +class StoreGateSvc; +class LVL1_ROI; +namespace TrigConf { + class ILVL1ConfigSvc; +} +namespace LVL1 { + class RecMuonRoiSvc; + class IL1EmTauTools; + class IL1JetTools; +} +namespace ROIB { + class RoIBResult; +} + +/** + * @short RoIB result to AOD converter + * + * The RoIBResultToAOD algorithm builds the CTP_Decision and + * LVL1_ROI objects from the LVL1 ROIB::RoIBResult object. + * In addition the TriggerType of the CTP can be rebuild, + * when zero in the input object. + * + * The CTP_Decision and LVL1_ROI objects are stored in ESD/AOD. + * + * $Id: RoIBResultToAOD.h 452138 2011-08-04 11:10:41Z krasznaa $ + * + * @author Tadashi Maeno <Tadashi.Maeno@cern.ch> + * @author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch> + * @author Alan Watson <Alan.Watson@cern.ch> + * @author Wolfgang Ehrenfeld <Wolfgang.Menges@desy.de> + * @author last commit \$Author: watsona $ + * + */ + +class RoIBResultToAOD : public AthAlgorithm { + +public: + RoIBResultToAOD( const std::string& name, ISvcLocator* pSvcLocator ); + + StatusCode initialize(); + StatusCode finalize(); + StatusCode execute(); + +private: + /// build CTP_Decision from CTPResult stored in ROIB::RoIBResult + StatusCode buildCTP_Decision(); + /// add EmTauRoi to LVL1_ROI from EmTauResult stored in ROIB::RoIBResult + void addEmTauRoI(const ROIB::RoIBResult*, LVL1_ROI*); + /// add JetEnergyRoi to LVL1_ROI from JetEnergyResult stored in ROIB::RoIBResult + void addJetEnergyRoI(const ROIB::RoIBResult*, LVL1_ROI*); + /// add MuonRoi to LVL1_ROI from MuCTPIResult stored in ROIB::RoIBResult + void addMuonRoI(const ROIB::RoIBResult*, LVL1_ROI*); + + // services + ServiceHandle<TrigConf::ILVL1ConfigSvc> m_configSvc; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + + ServiceHandle<LVL1::RecMuonRoiSvc> m_recRPCRoiSvc; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + ServiceHandle<LVL1::RecMuonRoiSvc> m_recTGCRoiSvc; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + + // tools + ToolHandle<LVL1::IL1EmTauTools> m_EmTauTool; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + ToolHandle<LVL1::IL1JetTools> m_JetTool; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + bool m_retrievedEmTauTool; + bool m_retrievedJetTool; + + // Data object StoreGate keys + std::string m_TriggerTowerLocation; + std::string m_JetElementLocation; + std::string m_roibInputKey; + std::string m_lvl1RoIOutputKey; + + // properties + bool m_doCalo; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + bool m_doMuon; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + + // trigger items for each TTW bit + std::vector< std::string > m_egammaItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + std::vector< std::string > m_tauhadItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + std::vector< std::string > m_jetItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + std::vector< std::string > m_esumItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + std::vector< std::string > m_highmuItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + std::vector< std::string > m_lowmuItem; //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink + +}; // class RoIBResultToAOD + +#endif // ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx new file mode 100644 index 00000000000..f84c8dec2cb --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx @@ -0,0 +1,851 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RoIBResultToxAOD.cxx 587265 2014-03-12 09:45:45Z krasznaa $ + +// STL include(s): +#include <algorithm> +#include <cmath> + +// Gaudi/Athena include(s): +#include "AthenaKernel/errorcheck.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "EventInfo/EventInfo.h" +#include "EventInfo/EventID.h" +#include "EventInfo/EventType.h" +#include "EventInfo/TriggerInfo.h" + +// LVL1 trigger include(s): +#include "TrigT1Interfaces/TriggerTypeWord.h" +#include "TrigT1Interfaces/RecMuonRoI.h" +#include "TrigT1Interfaces/RecMuonRoiSvc.h" +#include "TrigT1Interfaces/RecEmTauRoI.h" +#include "TrigT1Interfaces/RecJetRoI.h" +#include "TrigT1Interfaces/RecEnergyRoI.h" +#include "TrigT1Interfaces/JEPRoIDecoder.h" +#include "TrigT1Interfaces/TrigT1CaloDefs.h" +#include "TrigT1Result/RoIBResult.h" +#include "TrigT1Result/CTPResult.h" +#include "TrigT1CaloToolInterfaces/IL1EmTauTools.h" +#include "TrigT1CaloToolInterfaces/IL1JetTools.h" +#include "TrigT1CaloEvent/TriggerTowerCollection.h" +#include "TrigT1CaloEvent/JetElementCollection.h" +#include "TrigT1CaloEvent/CPMTower.h" +#include "TrigT1CaloEvent/JetInput.h" +#include "TrigConfL1Data/L1DataDef.h" +#include "TrigConfL1Data/TriggerThreshold.h" + +// Trigger configuration interface includes: +#include "TrigConfL1Data/CTPConfig.h" +#include "TrigConfL1Data/Menu.h" +#include "TrigConfL1Data/TriggerItem.h" + +// Include for the configuration service: +#include "TrigConfInterfaces/ILVL1ConfigSvc.h" + +// LVL1 AOD event include(s): +#include "AnalysisTriggerEvent/CTP_Decision.h" +#include "AnalysisTriggerEvent/LVL1_ROI.h" + +// xAOD include(s): +#include "xAODTrigger/MuonRoIContainer.h" +#include "xAODTrigger/MuonRoIAuxContainer.h" +#include "xAODTrigger/EmTauRoIContainer.h" +#include "xAODTrigger/EmTauRoIAuxContainer.h" +#include "xAODTrigger/EnergySumRoI.h" +#include "xAODTrigger/EnergySumRoIAuxInfo.h" +#include "xAODTrigger/JetEtRoI.h" +#include "xAODTrigger/JetEtRoIAuxInfo.h" +#include "xAODTrigger/JetRoIContainer.h" +#include "xAODTrigger/JetRoIAuxContainer.h" + + +// Local include(s): +#include "RoIBResultToxAOD.h" + +using namespace TrigConf; +using namespace xAODMaker; + +RoIBResultToxAOD::RoIBResultToxAOD( const std::string& name, ISvcLocator* pSvcLocator ) + : AthAlgorithm( name, pSvcLocator ), + m_configSvc( "TrigConf::LVL1ConfigSvc/LVL1ConfigSvc", name ), + m_recRPCRoiSvc( LVL1::ID_RecRpcRoiSvc, name ), + m_recTGCRoiSvc( LVL1::ID_RecTgcRoiSvc, name ), + m_EmTauTool( "LVL1::L1EmTauTools/L1EmTauTools" ), + m_JetTool( "LVL1::L1JetTools/L1JetTools" ), + m_MuCnvTool( "xAODMaker::MuonRoICnvTool/MuonRoICnvTool", this ), + m_EmTauCnvTool( "xAODMaker::EmTauRoICnvTool/EmTauRoICnvTool", this ), + m_EsumCnvTool( "xAODMaker::EnergySumRoICnvTool/EnergySumRoICnvTool", this ), + m_JetEtCnvTool( "xAODMaker::JetEtRoICnvTool/JetEtRoICnvTool", this ), + m_JetCnvTool( "xAODMaker::JetRoICnvTool/JetRoICnvTool", this ) + { + + // services + declareProperty( "LVL1ConfigSvc", m_configSvc, "LVL1 Config Service"); + declareProperty( "RecRpcRoiSvc", m_recRPCRoiSvc, "RPC Rec Roi Service"); + declareProperty( "RecTgcRoiSvc", m_recTGCRoiSvc, "TGC Rec Roi Service"); + + // tools + declareProperty( "L1EmTauTools", m_EmTauTool, + "Tool for calculation of EmTau trigger sums per RoI"); + declareProperty( "L1JetTools", m_JetTool, + "Tool for calculation of Jet cluster sums per RoI"); + + // Properties: input selection + declareProperty( "DoCalo", m_doCalo = true, "Use inputs from Calo system" ); + declareProperty( "DoMuon", m_doMuon = true, "Use inputs from Muon system" ); + + // Properties: rebuilding trigger type + declareProperty( "EGammaItem", m_egammaItem, + "List of LVL1 items for e/gamma trigger type" ); + declareProperty( "TauHadItem", m_tauhadItem, + "List of LVL1 items for tau trigger type" ); + declareProperty( "JetItem", m_jetItem, + "List of LVL1 items for jet trigger type" ); + declareProperty( "ESumItem", m_esumItem, + "List of LVL1 items for energy sum trigger type" ); + declareProperty( "HighMuItem", m_highmuItem, + "List of LVL1 items for high pt muon trigger type" ); + declareProperty( "LowMuItem", m_lowmuItem, + "List of LVL1 items for low pt muon trigger type" ); + + // Properties: StoreGate keys + m_TriggerTowerLocation = LVL1::TrigT1CaloDefs::TriggerTowerLocation; + m_JetElementLocation = LVL1::TrigT1CaloDefs::JetElementLocation; + declareProperty( "TriggerTowerLocation", m_TriggerTowerLocation ) ; + declareProperty( "JetElementLocation", m_JetElementLocation ) ; + declareProperty( "RoIBResultInputKey", m_roibInputKey = "RoIBResult" ); + declareProperty( "LVL1_ROIOutputKey", m_lvl1RoIOutputKey = "LVL1_ROI" ); + + declareProperty( "xAODKeyMu", m_xaodKeyMu = "LVL1MuonRoIs" ); + declareProperty( "xAODKeyEmTau", m_xaodKeyEmTau = "LVL1EmTauRoIs" ); + declareProperty( "xAODKeyEsum", m_xaodKeyEsum = "LVL1EnergySumRoI" ); + declareProperty( "xAODKeyJetEt", m_xaodKeyJetEt = "LVL1JetEtRoI" ); + declareProperty( "xAODKeyJet", m_xaodKeyJet = "LVL1JetRoIs" ); + + m_retrievedEmTauTool = false; + m_retrievedJetTool = false; + +} + +// Initialize +StatusCode RoIBResultToxAOD::initialize() { + + ATH_MSG_INFO( "initializing " << name() + << " - package version " << PACKAGE_VERSION ); + + // Print system info + if( m_doCalo == false ) { + ATH_MSG_WARNING( "Inputs from LVL1 Calo systems switched off" ); + } + if( m_doMuon == false ) { + ATH_MSG_WARNING( "Inputs from LVL1 Muon systems switched off" ); + } + + // Connect to the LVL1ConfigSvc for the trigger configuration: + CHECK( m_configSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_configSvc.typeAndName() ); + + if( m_doMuon ) { + + // Get the RPC RecRoI service + CHECK( m_recRPCRoiSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_recRPCRoiSvc.typeAndName() ); + + // Get the TGC RecRoI service + CHECK( m_recTGCRoiSvc.retrieve() ); + ATH_MSG_DEBUG( "Connected to " << m_recTGCRoiSvc.typeAndName() ); + + } // if (m_doMuon) + + if( m_doCalo ) { + + // Get tools + CHECK( m_EmTauTool.retrieve() ); + ATH_MSG_DEBUG( "Got " << m_EmTauTool.typeAndName() ); + m_retrievedEmTauTool = true; + + CHECK( m_JetTool.retrieve() ); + ATH_MSG_DEBUG( "Got " << m_JetTool.typeAndName() ); + m_retrievedJetTool = true; + + } // if (m_doCalo) + + return StatusCode::SUCCESS; +} + +// finalize +StatusCode RoIBResultToxAOD::finalize() { + + ATH_MSG_INFO( "Finalizing " << name() + << " - package version " << PACKAGE_VERSION ); + + return StatusCode::SUCCESS; +} + +// execute +StatusCode RoIBResultToxAOD::execute() { + + ATH_MSG_DEBUG( "in execute()" ); + + /////////////////////////////////////////////////////////////////////////// + // Trigger Info + + // retrieve event info + const DataHandle< EventInfo > eventInfoBeg; + const DataHandle< EventInfo > eventInfoEnd; + CHECK( evtStore()->retrieve( eventInfoBeg, eventInfoEnd ) ); + if( eventInfoBeg == eventInfoEnd ) { + ATH_MSG_ERROR( "No event info objects" ); + return StatusCode::RECOVERABLE; + } + + // get key + const std::string eventInfoKey = eventInfoBeg.key(); + + // build TriggerInfo + EventInfo* eventInfo = const_cast< EventInfo* >( eventInfoBeg.cptr() ); + TriggerInfo* tInfo = eventInfo->trigger_info(); + TriggerInfo* triggerInfo; + if( tInfo != 0 ) { + triggerInfo = new TriggerInfo( *tInfo ); + } else { + triggerInfo = new TriggerInfo( 0, 0, 0, + std::vector< TriggerInfo::number_type>( 0 ), + std::vector< TriggerInfo::number_type>( 0 ), + std::vector< TriggerInfo::StreamTag>( 0 ) ); + } + + // set TriggerInfo + eventInfo->setTriggerInfo( triggerInfo ); + + // dump + ATH_MSG_DEBUG( MSG::dec << "EventInfo:" << eventInfoKey ); + ATH_MSG_DEBUG( *( eventInfo->event_ID() ) ); + ATH_MSG_DEBUG( "[TimeStamp] = " << eventInfo->event_ID()->time_stamp() ); + ATH_MSG_DEBUG( "[Type] = " << eventInfo->event_type()->user_type() ); + ATH_MSG_DEBUG( "[BitMask]" ); + for( EventType::BitMaskIterator bitIt = eventInfo->event_type()->bit_mask_begin(); + bitIt != eventInfo->event_type()->bit_mask_end(); ++bitIt ) { + ATH_MSG_DEBUG( *bitIt ); + } + + if( triggerInfo != 0 ) { + ATH_MSG_DEBUG( MSG::hex << "[L1ID] = "<< triggerInfo->extendedLevel1ID() ); + ATH_MSG_DEBUG( "[TriggerType] = "<< triggerInfo->level1TriggerType() ); + ATH_MSG_DEBUG( "[L1Info] = "<< triggerInfo->level1TriggerInfo() ); + ATH_MSG_DEBUG( "[L2Info] = "<< triggerInfo->level2TriggerInfo() ); + ATH_MSG_DEBUG( "[EFInfo]" ); + const std::vector< TriggerInfo::number_type >& efInfo = triggerInfo->eventFilterInfo(); + for( std::vector< TriggerInfo::number_type >::const_iterator itEF = efInfo.begin(); + itEF != efInfo.end(); ++itEF ) { + ATH_MSG_DEBUG( *itEF ); + } + } + + /////////////////////////////////////////////////////////////////////////// + // build LVL1 ROI + + LVL1_ROI *lvl1ROI = new LVL1_ROI; + + /////////////////////////////////////////////////////////////////////////// + // retrive L1 result + + const ROIB::RoIBResult *result = 0; + if( evtStore()->retrieve( result, m_roibInputKey ).isFailure() ) { + ATH_MSG_WARNING( "Could not retrieve RoIBResult. Building empty LVL1_ROI" ); + result = 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Muon ROI + + if( m_doMuon == true ) addMuonRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // EmTau ROI + + if( m_doCalo == true ) addEmTauRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // JetEnergy ROI + + if( m_doCalo == true ) addJetEnergyRoI( result, lvl1ROI ); + + /////////////////////////////////////////////////////////////////////////// + // record LVL1 ROI in xAOD format + + CHECK( convertToxAOD(lvl1ROI) ); + + /////////////////////////////////////////////////////////////////////////// + // delete LVL1 ROI + delete lvl1ROI; + + return StatusCode::SUCCESS; +} + +StatusCode RoIBResultToxAOD::buildCTP_Decision() { + + ATH_MSG_DEBUG( "building CTP decision" ); + + CTP_Decision* ctpDecision = new CTP_Decision; + + // retrive L1 result + const ROIB::RoIBResult *result = 0; + if( evtStore()->retrieve( result, m_roibInputKey ).isSuccess() ) { + + // Trigger Type Word + bool triggerTypeLegacyFlag = false; + uint32_t triggerTypeWord = result->cTPResult().header().triggerType(); + + if( triggerTypeWord == 0 ) { // switch to legacy mode + ATH_MSG_DEBUG( "Building TriggerType word" ); + triggerTypeWord = LVL1::TriggerTypeWord::Physics | + LVL1::TriggerTypeWord::PriorityLevel; + triggerTypeLegacyFlag = true; + } + + // store TAV vector in CTP decision object + const std::vector< ROIB::CTPRoI > tav = result->cTPResult().TAV(); + for( size_t i( 0 ); i < tav.size(); ++i ) { + ctpDecision->setWord( i, tav[ i ].roIWord() ); + } + + // search for passed items in TAV vector from CTP result + const std::bitset< 256 > items = ROIB::convertToBitset( tav ); + + ATH_MSG_DEBUG( "Iterating Items on " << m_configSvc->ctpConfig() ); + for(TrigConf::ItemContainer::const_iterator item = m_configSvc->ctpConfig()->menu().items().begin(); + item != m_configSvc->ctpConfig()->menu().items().end(); ++item ) { + ATH_MSG_DEBUG( "try getting item name" ); + if( items[ ( *item )->ctpId() ] ) { + // add item name to CTP_Decision + const std::string& itemName = ( *item )->name(); + ctpDecision->setItem( itemName ); + ATH_MSG_VERBOSE( "Item : " << itemName ); + + if( triggerTypeLegacyFlag ) { + ///////// compute Trigger Type Word + ///////// This is temporary implementation for DC2 and will be moved to + ///////// CTP simulation + // e/gamma + if( m_egammaItem.end() != std::find( m_egammaItem.begin(), m_egammaItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::Egamma; + + // tau/hadron + if( m_tauhadItem.end() != std::find( m_tauhadItem.begin(), m_tauhadItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::TauHdr; + + // jet + if( m_jetItem.end() != std::find( m_jetItem.begin(), m_jetItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::Jet; + + // energy sum + if( m_esumItem.end() != std::find( m_esumItem.begin(), m_esumItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::EnergySum; + + // high pT muon + if( m_highmuItem.end() != std::find( m_highmuItem.begin(), m_highmuItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::HighPtMuon; + + // low pT muon + if( m_lowmuItem.end() != std::find( m_lowmuItem.begin(), m_lowmuItem.end(), + itemName ) ) + triggerTypeWord |= LVL1::TriggerTypeWord::LowPtMuon; + } // if (triggerTypeLegacyFlag) + } // if (items[(*item)->ctpId()]) + } // for + + // set Trigger Type Word + ctpDecision->setTriggerTypeWord( triggerTypeWord ); + ATH_MSG_DEBUG( "CTP_Decision: \n" + ctpDecision->dump() ); + + } else { + ATH_MSG_WARNING( "Could not retrieve RoIBResult, building empty CTP_Decision" ); + } + + // record CTP Decision + CHECK( evtStore()->record( ctpDecision, "CTP_Decision" ) ); + CHECK( evtStore()->setConst( ctpDecision ) ); + + return StatusCode::SUCCESS; +} + +void RoIBResultToxAOD::addEmTauRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "building EmTauRoI" ); + + // empty input + if( result == 0 ) return; + + // Digit scale for calorimeter trigger + float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV; + ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale ); + + /** Get EmTau Thresholds from configSvc. Also fill a map of threshold names while + we are here - will be useful later */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector< TrigConf::TriggerThreshold* > caloThresholds; + std::map< int, std::string > thresholdNames; + for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::emType() || ( *it )->type() == L1DataDef::tauType() ) { + caloThresholds.push_back( *it ); + thresholdNames.insert( std::map< int, std::string >::value_type( ( *it )->thresholdNumber(), ( *it )->name() ) ); + } + } + + // Tool to reconstruct EM/tau cluster & isolation sums + // - need to form tower map for RoI reconstruction + const DataVector< LVL1::TriggerTower >* storedTTs; + std::map< int, LVL1::CPMTower* > cpmtowers; + if( m_retrievedEmTauTool ) { + if( evtStore()->contains< TriggerTowerCollection >( m_TriggerTowerLocation ) ) { + StatusCode sc = evtStore()->retrieve( storedTTs, m_TriggerTowerLocation ); + if( sc.isSuccess() ) m_EmTauTool->mapTowers( storedTTs, &cpmtowers ); + else ATH_MSG_WARNING( "Error retrieving TriggerTowers" ); + } + else ATH_MSG_DEBUG( "No TriggerTowerCollection found at " + << m_TriggerTowerLocation ); + } + + // get EmTau Result + const std::vector< ROIB::EMTauResult >& emtauResult = result->eMTauResult(); + + // reconstruct ROI + ATH_MSG_DEBUG( "EmTau ROI" ); + std::vector< ROIB::EMTauResult >::const_iterator itEMR = emtauResult.begin(); + std::vector< ROIB::EMTauResult >::const_iterator itEMRe = emtauResult.end(); + for( ; itEMR != itEMRe; ++itEMR ) { + const std::vector< ROIB::EMTauRoI >& emtauRoIV = itEMR->roIVec(); + std::vector< ROIB::EMTauRoI >::const_iterator itEM = emtauRoIV.begin(); + std::vector< ROIB::EMTauRoI >::const_iterator itEMe = emtauRoIV.end(); + for( ; itEM != itEMe; ++itEM ) { + + uint32_t roIWord = itEM->roIWord(); + ATH_MSG_DEBUG( "About to create RecEmTauRoI : " << MSG::hex + << std::setw( 8 ) << roIWord << MSG::dec ); + + // RecRoI + LVL1::RecEmTauRoI recRoI( roIWord, &caloThresholds ); + + // AOD component + // ATLAS standard phi convention differs from L1 hardware convention + double roiPhi = recRoI.phi(); + if( roiPhi > M_PI ) roiPhi -= 2 * M_PI; + EmTau_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFFF ); + + // fired thresholds + std::vector< unsigned int >* thrV = recRoI.thresholdsPassed(); + std::vector< unsigned int >::const_iterator itTh = thrV->begin(); + std::vector< unsigned int >::const_iterator itThE = thrV->end(); + for( ; itTh != itThE; ++itTh ) { + double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV; + std::string thrName = "NameNotFound"; + if ( thresholdNames.find( *itTh - 1 ) != thresholdNames.end() ) { + thrName = thresholdNames[ *itTh - 1 ]; + } + + roi.addThresholdValue( thrValue ); + roi.addThresholdName( thrName ); + + ATH_MSG_DEBUG( "EmTau Thr : " << thrName + << ", value = " << thrValue ); + } + delete thrV; + + // Cluster ET values, reconstructed from TriggerTowers + if( m_retrievedEmTauTool ) { + m_EmTauTool->formSums( roIWord, &cpmtowers ); + roi.setCore( m_EmTauTool->Core() * caloTrigScale ); + roi.setEMClus( m_EmTauTool->EMClus() * caloTrigScale ); + roi.setTauClus( m_EmTauTool->TauClus() * caloTrigScale ); + roi.setEMIsol( m_EmTauTool->EMIsol() * caloTrigScale ); + roi.setHadIsol( m_EmTauTool->HadIsol() * caloTrigScale ); + roi.setHadCore( m_EmTauTool->HadCore() * caloTrigScale ); + } + + lvl1ROI->addEmTauROI( roi ); + } + } + + for( std::map< int, LVL1::CPMTower* >::iterator i = cpmtowers.begin(); + i != cpmtowers.end(); ++i ) delete i->second; + + return; +} + +void RoIBResultToxAOD::addJetEnergyRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "building JetEnergyRoI" ); + + // empty input + if( result == 0 ) return; + + // Digit scale for calorimeter trigger + float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV; + ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale ); + + /** Get Jet/Energy Thresholds from configSvc. Also fill maps of threshold names while + we are here - will be useful later. + + Unfortunately there are 3 types of jet threshold and 3 types of ET trigger threshold, + so this bit doesn't look very elegant */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector<TrigConf::TriggerThreshold*> jetThresholds; + std::vector<TrigConf::TriggerThreshold*> energyThresholds; + std::vector<TrigConf::TriggerThreshold*> jetEnergyThresholds; + std::map<int, std::string> jetNames; + std::map<int, std::string> jfNames; + std::map<int, std::string> jbNames; + std::map<int, std::string> xeNames; + std::map<int, std::string> teNames; + std::map<int, std::string> xsNames; + std::map<int, std::string> jeNames; + + for( std::vector<TrigConf::TriggerThreshold*>::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::jetType() ) { + jetThresholds.push_back( *it ); + jetNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jfType() ) { + jetThresholds.push_back( *it ); + jfNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jbType() ) { + jetThresholds.push_back( *it ); + jbNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::xeType() ) { + energyThresholds.push_back( *it ); + xeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::teType() ) { + energyThresholds.push_back( *it ); + teNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::xsType() ) { + energyThresholds.push_back( *it ); + xsNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + else if( ( *it )->type() == L1DataDef::jeType() ) { + jetEnergyThresholds.push_back( *it ); + jeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + } + + // Tool to reconstruct Jet cluster ET sums + // - form input map ready for analysis + const DataVector< LVL1::JetElement >* storedJEs; + std::map< int, LVL1::JetInput* > jetInputs; + if( m_retrievedJetTool ) { + if( evtStore()->contains< JetElementCollection >( m_JetElementLocation ) ) { + StatusCode sc = evtStore()->retrieve( storedJEs, m_JetElementLocation ); + if( sc.isSuccess() ) m_JetTool->mapJetInputs( storedJEs, &jetInputs ); + else ATH_MSG_WARNING( "Error retrieving JetElements" ); + } + else ATH_MSG_DEBUG( "No JetElementCollection found at " + << m_JetElementLocation ); + } + + // get JetEnergy Result + const std::vector< ROIB::JetEnergyResult >& jetenergyResult = result->jetEnergyResult(); + + // reconstruct ROI + std::vector< ROIB::JetEnergyResult >::const_iterator itJETR = jetenergyResult.begin(); + std::vector< ROIB::JetEnergyResult >::const_iterator itJETRe = jetenergyResult.end(); + for( ; itJETR != itJETRe; ++itJETR ) { + const std::vector< ROIB::JetEnergyRoI >& jetenergyRoIV = itJETR->roIVec(); + std::vector< ROIB::JetEnergyRoI >::const_iterator itJET = jetenergyRoIV.begin(); + std::vector< ROIB::JetEnergyRoI >::const_iterator itJETe = jetenergyRoIV.end(); + for( ; itJET != itJETe; ++itJET ) { + uint32_t roIWord = itJET->roIWord(); + + ATH_MSG_DEBUG( "Jet RoI, RoIWord = " << MSG::hex << std::setw( 8 ) + << roIWord << MSG::dec ); + + // RoI type + LVL1::JEPRoIDecoder conv; + int roiType = conv.roiType( roIWord ); + + // Jet ROI + if( roiType == LVL1::TrigT1CaloDefs::JetRoIWordType ) { + // RecRoI + LVL1::RecJetRoI recRoI( roIWord, &jetThresholds ); + + // AOD component + // Convert to ATLAS phi convention + double roiPhi = recRoI.phi(); + if( roiPhi > M_PI ) roiPhi -= 2 * M_PI; + Jet_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFF ); + + // fired Jet thresholds + std::vector< unsigned int >* thrV = recRoI.thresholdsPassed(); + std::vector< unsigned int >::const_iterator itTh = thrV->begin(); + std::vector< unsigned int >::const_iterator itThE = thrV->end(); + for( ; itTh != itThE; ++itTh ) { + double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV; + std::string thrName = "NameNotFound"; + if (!recRoI.isForwardJet()) { + if (jetNames.find(*itTh-1) != jetNames.end()) thrName = jetNames[*itTh-1]; + } + else if (recRoI.eta() > 0) { + if (jfNames.find(*itTh-1) != jfNames.end()) thrName = jfNames[*itTh-1]; + } + else { + if (jbNames.find(*itTh-1) != jbNames.end()) thrName = jbNames[*itTh-1]; + } + + roi.addThresholdValue( thrValue ); + roi.addThresholdName( thrName ); + + ATH_MSG_DEBUG( "Jet Thr : " << thrName + << ", value = " << thrValue ); + } + delete thrV; + + // Jet Cluster ET sums + if (m_retrievedJetTool) { + m_JetTool->formSums(roIWord, &jetInputs); + roi.setET4x4(m_JetTool->ET4x4()*caloTrigScale); + roi.setET6x6(m_JetTool->ET6x6()*caloTrigScale); + roi.setET8x8(m_JetTool->ET8x8()*caloTrigScale); + } + + lvl1ROI->addJetROI(roi); + } + // Jet ET ROI + else if( roiType == LVL1::TrigT1CaloDefs::JetEtRoIWordType ) { + // AOD component + JetET_ROI roi( roIWord, roIWord & 0xF ); + + // fired Jet ET thresholds + for( unsigned int i = 0; i < TrigT1CaloDefs::numOfJetEtSumThresholds; ++i ) { + if( ( roIWord >> i ) & 0x1 ) { + std::string thrName = "NameNotFound"; + if (jeNames.find(i) != jfNames.end()) thrName = jeNames[i]; + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "JetEt Thr : " << thrName ); + } + } + + lvl1ROI->addJetETROI(roi); + } + // EnergySum ROI + else if ( roiType == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) { + uint32_t roiWord0 = roIWord; + ATH_MSG_DEBUG( "ET RoIWord 0 : " << MSG::hex << std::setw( 8 ) + << roiWord0 << MSG::dec ); + ++itJET; + uint32_t roiWord1 = itJET->roIWord(); + ATH_MSG_DEBUG( "ET RoIWord 1 : " << MSG::hex << std::setw( 8 ) + << roiWord1 << MSG::dec ); + ++itJET; + uint32_t roiWord2 = itJET->roIWord(); + ATH_MSG_DEBUG( "ET RoIWord 2 : " << MSG::hex << std::setw( 8 ) + << roiWord2 << MSG::dec ); + + // RecRoI + LVL1::RecEnergyRoI recRoI( roiWord0, roiWord1, roiWord2, &energyThresholds ); + + // Overflow bits + unsigned int overflows = 0; + if (conv.energyOverflow(roiWord0)) overflows |= 0x1; + if (conv.energyOverflow(roiWord1)) overflows |= 0x2; + if (conv.energyOverflow(roiWord2)) overflows |= 0x4; + + // AOD component + EnergySum_ROI roi( roiWord0, roiWord1, roiWord2, + recRoI.energyX() * caloTrigScale, + recRoI.energyY() * caloTrigScale, + recRoI.energyT() * caloTrigScale, + ( roiWord1 >> 16 ) & 0xFF, ( roiWord2 >> 16 ) & 0xFF, + ( roiWord0 >> 16 ) & 0xFF, overflows ); + + // fired summed ET thresholds + std::vector< unsigned int >* thrEtMiss = recRoI.etMissThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThEtMiss = thrEtMiss->begin(); + for( ; itThEtMiss != thrEtMiss->end(); ++itThEtMiss ) { + std::string thrName = "NameNotFound"; + if( xeNames.find( *itThEtMiss - 1 ) != xeNames.end() ) { + thrName = xeNames[ *itThEtMiss - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "ETmiss threshold : " << thrName ); + } + delete thrEtMiss; + + // fired missing ET thresholds + std::vector< unsigned int >* thrSumEt = recRoI.sumEtThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThSumEt = thrSumEt->begin(); + for( ; itThSumEt != thrSumEt->end(); ++itThSumEt ) { + std::string thrName = "NameNotFound"; + if( teNames.find( *itThSumEt - 1 ) != teNames.end() ) { + thrName = teNames[ *itThSumEt - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "SumET threshold : " << thrName ); + } + delete thrSumEt; + + // fired missing ET significance thresholds + std::vector< unsigned int >* thrMETSig = recRoI.mEtSigThresholdsPassed(); + std::vector< unsigned int >::const_iterator itThMETSig = thrMETSig->begin(); + for( ; itThMETSig != thrMETSig->end(); ++itThMETSig ) { + std::string thrName = "NameNotFound"; + if( xsNames.find( *itThMETSig - 1 ) != xsNames.end() ) { + thrName = xsNames[ *itThMETSig - 1 ]; + } + roi.addThreshold( thrName ); + ATH_MSG_DEBUG( "METSig threshold : " << thrName ); + } + delete thrMETSig; + + lvl1ROI->addEnergySumROI(roi); + } + } + } + + for( std::map< int, LVL1::JetInput* >::iterator i = jetInputs.begin(); + i != jetInputs.end(); ++i ) { + delete i->second; + } + + return; +} + +void RoIBResultToxAOD::addMuonRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) { + + ATH_MSG_DEBUG( "in buildMuonRoI()" ); + + // empty input + if( result == 0 ) return; + + /** Get Muon Thresholds from configSvc. Also fill a map of threshold names while + we are here - will be useful later */ + + std::vector< TrigConf::TriggerThreshold* > thresholds = + m_configSvc->ctpConfig()->menu().thresholdVector(); + std::vector< TrigConf::TriggerThreshold* > muonThresholds; + std::map< int, std::string > thresholdNames; + for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin(); + it != thresholds.end(); ++it ) { + if( ( *it )->type() == L1DataDef::muonType() ) { + muonThresholds.push_back( *it ); + thresholdNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name())); + } + } + + // get Muon ROI + const std::vector< ROIB::MuCTPIRoI >& muonRoIV = result->muCTPIResult().roIVec(); + + // reconstruct ROI + ATH_MSG_DEBUG( "Muon ROI" ); + std::vector< ROIB::MuCTPIRoI >::const_iterator itMU = muonRoIV.begin(); + std::vector< ROIB::MuCTPIRoI >::const_iterator itMUe = muonRoIV.end(); + for ( ; itMU != itMUe; ++itMU ) { + + uint32_t roIWord = itMU->roIWord(); + + ATH_MSG_DEBUG( MSG::hex << std::setw( 8 ) << roIWord ); + + if( ( m_recRPCRoiSvc == false ) || ( m_recTGCRoiSvc == false ) ) { + continue; + } + + // RecRoI + LVL1::RecMuonRoI recRoI( roIWord, m_recRPCRoiSvc.operator->(), + m_recTGCRoiSvc.operator->(), &muonThresholds ); + + double thrValue = recRoI.getThresholdValue() * CLHEP::GeV; + int index = recRoI.getThresholdNumber() - 1; + std::string thrName = "NameNotFound"; + if( thresholdNames.find(index) != thresholdNames.end() ) { + thrName = thresholdNames[ index ]; + } + + // AOD component + Muon_ROI roi( roIWord, recRoI.eta(), recRoI.phi(), thrName, thrValue ); + + lvl1ROI->addMuonROI( roi ); + ATH_MSG_DEBUG( "Muon Thr : " << thrName << ", value = " << thrValue ); + + } // for ( ; itMU != itMUe; ++itMU ) + + return; +} + +StatusCode RoIBResultToxAOD::convertToxAOD(LVL1_ROI* aod){ + + ATH_MSG_DEBUG( "converting to xAOD" ); + ATH_MSG_DEBUG( "number of Muon RoIs: " << aod->getMuonROIs().size() ); + ATH_MSG_DEBUG( "number of EmTau RoIs: " << aod->getEmTauROIs().size() ); + ATH_MSG_DEBUG( "number of Jet RoIs: " << aod->getJetROIs().size() ); + ATH_MSG_DEBUG( "number of JetEt RoIs: " << aod->getJetEtROIs().size() ); + ATH_MSG_DEBUG( "number of Esum RoIs: " << aod->getEnergySumROIs().size() ); + + + //////////////////////////////// + /// Muon RoIs + xAOD::MuonRoIAuxContainer* mu_aux = new xAOD::MuonRoIAuxContainer(); + xAOD::MuonRoIContainer* mu_xaod = new xAOD::MuonRoIContainer(); + mu_xaod->setStore( mu_aux ); + + CHECK( m_MuCnvTool->convert( aod, mu_xaod ) ); + CHECK( evtStore()->record( mu_aux, m_xaodKeyMu + "Aux." ) ); + CHECK( evtStore()->record( mu_xaod, m_xaodKeyMu ) ); + + //////////////////////////////// + /// EmTau RoIs + + xAOD::EmTauRoIAuxContainer* emtau_aux = new xAOD::EmTauRoIAuxContainer(); + xAOD::EmTauRoIContainer* emtau_xaod = new xAOD::EmTauRoIContainer(); + emtau_xaod->setStore( emtau_aux ); + + CHECK( m_EmTauCnvTool->convert( aod, emtau_xaod ) ); + CHECK( evtStore()->record( emtau_aux, m_xaodKeyEmTau + "Aux." ) ); + CHECK( evtStore()->record( emtau_xaod, m_xaodKeyEmTau ) ); + + //////////////////////////////// + /// EnergySum RoIs + xAOD::EnergySumRoIAuxInfo* esum_aux = new xAOD::EnergySumRoIAuxInfo(); + xAOD::EnergySumRoI* esum_xaod = new xAOD::EnergySumRoI(); + esum_xaod->setStore( esum_aux ); + + CHECK( m_EsumCnvTool->convert( aod, esum_xaod ) ); + CHECK( evtStore()->record( esum_aux, m_xaodKeyEsum + "Aux." ) ); + CHECK( evtStore()->record( esum_xaod, m_xaodKeyEsum ) ); + + //////////////////////////////// + /// JetEt RoIs + xAOD::JetEtRoIAuxInfo* jetet_aux = new xAOD::JetEtRoIAuxInfo(); + xAOD::JetEtRoI* jetet_xaod = new xAOD::JetEtRoI(); + jetet_xaod->setStore( jetet_aux ); + + CHECK( m_JetEtCnvTool->convert( aod, jetet_xaod ) ); + CHECK( evtStore()->record( jetet_aux, m_xaodKeyJetEt + "Aux." ) ); + CHECK( evtStore()->record( jetet_xaod, m_xaodKeyJetEt ) ); + + //////////////////////////////// + /// Jet RoIs + xAOD::JetRoIAuxContainer* jet_aux = new xAOD::JetRoIAuxContainer(); + xAOD::JetRoIContainer* jet_xaod = new xAOD::JetRoIContainer(); + jet_xaod->setStore( jet_aux ); + + CHECK( m_JetCnvTool->convert( aod, jet_xaod ) ); + CHECK( evtStore()->record( jet_aux, m_xaodKeyJet + "Aux." ) ); + CHECK( evtStore()->record( jet_xaod, m_xaodKeyJet ) ); + + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h new file mode 100644 index 00000000000..a4923b847da --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h @@ -0,0 +1,128 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: RoIBResultToxAOD.h 587265 2014-03-12 09:45:45Z krasznaa $ +#ifndef ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H +#define ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H + +// Gaudi/Athena include(s): +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ToolHandle.h" +#include "StoreGate/DataHandle.h" + +// xAOD include(s): +#include "xAODTriggerCnv/IMuonRoICnvTool.h" +#include "xAODTriggerCnv/IEmTauRoICnvTool.h" +#include "xAODTriggerCnv/IEnergySumRoICnvTool.h" +#include "xAODTriggerCnv/IJetEtRoICnvTool.h" +#include "xAODTriggerCnv/IJetRoICnvTool.h" + +// Forward declaration(s): +class StoreGateSvc; +class LVL1_ROI; +namespace TrigConf { + class ILVL1ConfigSvc; +} +namespace LVL1 { + class RecMuonRoiSvc; + class IL1EmTauTools; + class IL1JetTools; +} +namespace ROIB { + class RoIBResult; +} + +/** + * @short RoIB result to xAOD converter + * + * This is a slightly adapted version of the original RoIBResultToAOD + * algorithm. Going the route through the LVL1_ROI structure was + * needed due to the interface of the AOD->xAOD ROI converters + * + * The RoIBResultToxAOD algorithm builds the CTP_Decision and + * LVL1_ROI objects from the LVL1 ROIB::RoIBResult object. + * In addition the TriggerType of the CTP can be rebuild, + * when zero in the input object. + * + * The CTP_Decision and LVL1_ROI objects are stored in ESD/AOD. + * + * $Id: RoIBResultToxAOD.h 587265 2014-03-12 09:45:45Z krasznaa $ + * + * @author Tadashi Maeno <Tadashi.Maeno@cern.ch> + * @author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch> + * @author Alan Watson <Alan.Watson@cern.ch> + * @author Wolfgang Ehrenfeld <Wolfgang.Menges@desy.de> + * @author last commit \$Author: watsona $ + * + */ +class RoIBResultToxAOD : public AthAlgorithm { + +public: + RoIBResultToxAOD( const std::string& name, ISvcLocator* pSvcLocator ); + + StatusCode initialize(); + StatusCode finalize(); + StatusCode execute(); + +private: + /// build CTP_Decision from CTPResult stored in ROIB::RoIBResult + StatusCode buildCTP_Decision(); + /// add EmTauRoi to LVL1_ROI from EmTauResult stored in ROIB::RoIBResult + void addEmTauRoI(const ROIB::RoIBResult*, LVL1_ROI*); + /// add JetEnergyRoi to LVL1_ROI from JetEnergyResult stored in ROIB::RoIBResult + void addJetEnergyRoI(const ROIB::RoIBResult*, LVL1_ROI*); + /// add MuonRoi to LVL1_ROI from MuCTPIResult stored in ROIB::RoIBResult + void addMuonRoI(const ROIB::RoIBResult*, LVL1_ROI*); + /// convert AOD ROI objects to xAOD objects + StatusCode convertToxAOD(LVL1_ROI*); + + // services + ServiceHandle<TrigConf::ILVL1ConfigSvc> m_configSvc; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + + ServiceHandle<LVL1::RecMuonRoiSvc> m_recRPCRoiSvc; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + ServiceHandle<LVL1::RecMuonRoiSvc> m_recTGCRoiSvc; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + + // tools + ToolHandle<LVL1::IL1EmTauTools> m_EmTauTool; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + ToolHandle<LVL1::IL1JetTools> m_JetTool; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + bool m_retrievedEmTauTool; + bool m_retrievedJetTool; + + // xAOD conversion tools: + std::string m_xaodKeyMu; + std::string m_xaodKeyEmTau; + std::string m_xaodKeyEsum; + std::string m_xaodKeyJetEt; + std::string m_xaodKeyJet; + + ToolHandle< xAODMaker::IMuonRoICnvTool > m_MuCnvTool; + ToolHandle< xAODMaker::IEmTauRoICnvTool > m_EmTauCnvTool; + ToolHandle< xAODMaker::IEnergySumRoICnvTool > m_EsumCnvTool; + ToolHandle< xAODMaker::IJetEtRoICnvTool > m_JetEtCnvTool; + ToolHandle< xAODMaker::IJetRoICnvTool > m_JetCnvTool; + + // Data object StoreGate keys + std::string m_TriggerTowerLocation; + std::string m_JetElementLocation; + std::string m_roibInputKey; + std::string m_lvl1RoIOutputKey; + + // properties + bool m_doCalo; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + bool m_doMuon; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + + // trigger items for each TTW bit + std::vector< std::string > m_egammaItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + std::vector< std::string > m_tauhadItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + std::vector< std::string > m_jetItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + std::vector< std::string > m_esumItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + std::vector< std::string > m_highmuItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + std::vector< std::string > m_lowmuItem; //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink + +}; // class RoIBResultToxAOD + +#endif // ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx new file mode 100644 index 00000000000..c2ef5a4e1e9 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx @@ -0,0 +1,25 @@ +// $Id: AnalysisTriggerAlgs_entries.cxx 587265 2014-03-12 09:45:45Z krasznaa $ + +// Gaudi/Athena include(s): +#include "GaudiKernel/DeclareFactoryEntries.h" + +// Local include(s): +#include "../RoIBResultToAOD.h" +#include "../RoIBResultToxAOD.h" +#include "../MuCTPI_RDOToRoIBResult.h" + +// +// Declare the algorithm(s): +// +DECLARE_ALGORITHM_FACTORY( RoIBResultToxAOD ) +DECLARE_ALGORITHM_FACTORY( RoIBResultToAOD ) +DECLARE_ALGORITHM_FACTORY( MuCTPI_RDOToRoIBResult ) + + +DECLARE_FACTORY_ENTRIES( AnalysisTriggerAlgs ) { + + DECLARE_ALGORITHM( RoIBResultToAOD ) + DECLARE_ALGORITHM( RoIBResultToxAOD ) + DECLARE_ALGORITHM( MuCTPI_RDOToRoIBResult ) + +} diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx new file mode 100644 index 00000000000..5db77df46b5 --- /dev/null +++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx @@ -0,0 +1,2 @@ +#include "GaudiKernel/LoadFactoryEntries.h" +LOAD_FACTORY_ENTRIES(AnalysisTriggerAlgs) -- GitLab