diff --git a/Projects/AnalysisBase/package_filters.txt b/Projects/AnalysisBase/package_filters.txt index 6c7c2e836e82bf94d99461e507bbdfd51c0b8b30..274072529144919e58a7912e9b1cea9cfc2db2e6 100644 --- a/Projects/AnalysisBase/package_filters.txt +++ b/Projects/AnalysisBase/package_filters.txt @@ -116,6 +116,7 @@ + Trigger/TrigConfiguration/TrigConfHLTUtils + Trigger/TrigConfiguration/TrigConfInterfaces + Trigger/TrigConfiguration/TrigConfL1Data ++ Trigger/TrigConfiguration/TrigConfData + Trigger/TrigConfiguration/TrigConfxAOD + Trigger/TrigEvent/TrigDecisionInterface + Trigger/TrigEvent/TrigNavStructure diff --git a/Reconstruction/RecExample/RecExPers/share/RecoOutputMetadataList_jobOptions.py b/Reconstruction/RecExample/RecExPers/share/RecoOutputMetadataList_jobOptions.py index fad08cd70eaa31018277e5b185c71b3bf2c420fd..0918ec942bb21ff03ecf940c90f4913915b3ae13 100644 --- a/Reconstruction/RecExample/RecExPers/share/RecoOutputMetadataList_jobOptions.py +++ b/Reconstruction/RecExample/RecExPers/share/RecoOutputMetadataList_jobOptions.py @@ -13,6 +13,8 @@ if metadata['eventTypes'][0] == 'IS_SIMULATION' \ recoMetadataItemList = CfgItemList("RecoMetadata", items = ["xAOD::TriggerMenuContainer#*", "xAOD::TriggerMenuAuxContainer#*", + "xAOD::TriggerMenuJsonContainer#*", + "xAOD::TriggerMenuJsonAuxContainer#*", "IOVMetaDataContainer#*", "xAOD::LumiBlockRangeContainer#*", "xAOD::LumiBlockRangeAuxContainer#*", diff --git a/Trigger/TrigConfiguration/TrigConfData/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfData/CMakeLists.txt index 03bfa94ae99dcd291fffc95c338c08a47c03289b..33e0694865612efdeba2e96808e8000fbd5771b3 100644 --- a/Trigger/TrigConfiguration/TrigConfData/CMakeLists.txt +++ b/Trigger/TrigConfiguration/TrigConfData/CMakeLists.txt @@ -3,6 +3,12 @@ # Declare the package name: atlas_subdir( TrigConfData ) +# Extra dependencies, based on the environment: +set( extra_libs ) +if( NOT XAOD_STANDALONE ) + set( extra_libs AthenaKernel ) +endif() + # External dependencies: find_package( Boost ) @@ -12,7 +18,7 @@ atlas_add_library ( TrigConfData TrigConfData/*.h src/*.cxx PUBLIC_HEADERS TrigConfData INCLUDE_DIRS ${Boost_INCLUDE_DIRS} - LINK_LIBRARIES ${Boost_LIBRARIES} AthenaKernel CxxUtils + LINK_LIBRARIES ${Boost_LIBRARIES} ${extra_libs} CxxUtils ) # standalone library for use by detector software: diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h index 29b2a9d3622fe9d8356c6acf3838c733d472041f..33dbd009dc9bf801b1b60fea729b20e5c2b15864 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/DataStructure.h @@ -223,6 +223,7 @@ namespace TrigConf { } #ifndef TRIGCONF_STANDALONE +#ifndef XAOD_STANDALONE #include "AthenaKernel/CLASS_DEF.h" CLASS_DEF( TrigConf::DataStructure , 98904516 , 1 ) @@ -231,6 +232,7 @@ CLASS_DEF( TrigConf::DataStructure , 98904516 , 1 ) CONDCONT_DEF( TrigConf::DataStructure , 265887802 ); #endif +#endif #endif diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h index 628e64a4e117a4cd611ed095b54fbd53162d82df..5dcac70ba05d1aa962a00cbf139785f4ae427b13 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTMenu.h @@ -80,6 +80,7 @@ namespace TrigConf { } #ifndef TRIGCONF_STANDALONE +#ifndef XAOD_STANDALONE #include "AthenaKernel/CLASS_DEF.h" CLASS_DEF( TrigConf::HLTMenu , 24176960 , 1 ) @@ -87,6 +88,7 @@ CLASS_DEF( TrigConf::HLTMenu , 24176960 , 1 ) #include "AthenaKernel/CondCont.h" CONDCONT_DEF( TrigConf::HLTMenu , 155284098 ); +#endif #endif #endif diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h index 5845a78f5ec5b46a63ea1fe18cd91cfb45d9a2c4..42b98372994a8b085e1edac1244230f5e55b43bc 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/HLTPrescalesSet.h @@ -74,6 +74,7 @@ namespace TrigConf { } #ifndef TRIGCONF_STANDALONE +#ifndef XAOD_STANDALONE #include "AthenaKernel/CLASS_DEF.h" CLASS_DEF( TrigConf::HLTPrescalesSet , 134177107 , 1 ) @@ -81,6 +82,7 @@ CLASS_DEF( TrigConf::HLTPrescalesSet , 134177107 , 1 ) #include "AthenaKernel/CondCont.h" CONDCONT_DEF( TrigConf::HLTPrescalesSet , 130966407 ); +#endif #endif #endif diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h index 719e4ed293f383dc90870483347b2fcf45c376fc..8bf39b073a6f486b60c60d2ce6cf9acf086bde8a 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1Menu.h @@ -176,6 +176,7 @@ namespace TrigConf { } #ifndef TRIGCONF_STANDALONE +#ifndef XAOD_STANDALONE #include "AthenaKernel/CLASS_DEF.h" CLASS_DEF( TrigConf::L1Menu , 26419484 , 1 ) @@ -183,6 +184,7 @@ CLASS_DEF( TrigConf::L1Menu , 26419484 , 1 ) #include "AthenaKernel/CondCont.h" CONDCONT_DEF( TrigConf::L1Menu , 11747932 ); +#endif #endif #endif diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h index 54af67b0f445a3ecdbeaab057e76c1b7380f0f81..553b647807dc9a5a7625edd7de6164b9a80fe6b3 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/L1PrescalesSet.h @@ -69,6 +69,7 @@ namespace TrigConf { } #ifndef TRIGCONF_STANDALONE +#ifndef XAOD_STANDALONE #include "AthenaKernel/CLASS_DEF.h" CLASS_DEF( TrigConf::L1PrescalesSet , 146597935 , 1 ) @@ -76,6 +77,7 @@ CLASS_DEF( TrigConf::L1PrescalesSet , 146597935 , 1 ) #include "AthenaKernel/CondCont.h" CONDCONT_DEF( TrigConf::L1PrescalesSet , 124562173 ); +#endif #endif #endif diff --git a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/TSCheckMacros.h b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/TSCheckMacros.h index d97b27266891d43a9c5031ac796b0836fb919172..a329c66ba5d92ee388758827a21a749ecee46c4f 100644 --- a/Trigger/TrigConfiguration/TrigConfData/TrigConfData/TSCheckMacros.h +++ b/Trigger/TrigConfiguration/TrigConfData/TrigConfData/TSCheckMacros.h @@ -11,12 +11,16 @@ #define ATLAS_THREAD_SAFE [[gnu::thread_safe]] #else #define ATLAS_THREAD_SAFE -#endif +#endif // ATLAS_GCC_CHECKERS #else +#ifdef XAOD_STANDALONE +#define ATLAS_THREAD_SAFE +#else #include "CxxUtils/checker_macros.h" +#endif // XAOD_STANDALONE -#endif +#endif // TRIGCONF_STANDALONE -#endif +#endif // TRIGCONFDATA_TSCHECKMACROS_H diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt index 31390aa07cfd5871b1648fde13d68fd7a87cbfda..378908ea5814d47d35ca8a1ad4b55dbe61605e8c 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt +++ b/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt @@ -3,17 +3,20 @@ # Declare the package name: atlas_subdir( TrigConfxAOD ) +find_package( Boost ) + # Libraries in the package: atlas_add_library( TrigConfxAODLib TrigConfxAOD/*.h Root/*.cxx PUBLIC_HEADERS TrigConfxAOD - LINK_LIBRARIES AsgTools xAODTrigger TrigConfL1Data TrigConfHLTData + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} + LINK_LIBRARIES AsgTools xAODTrigger TrigConfL1Data TrigConfHLTData TrigConfData ${Boost_LIBRARIES} TrigConfInterfaces ) if( NOT XAOD_STANDALONE ) atlas_add_component( TrigConfxAOD src/*.h src/*.cxx src/components/*.cxx - LINK_LIBRARIES AthenaBaseComps AthenaKernel StoreGateLib GaudiKernel TrigConfData + LINK_LIBRARIES AthenaBaseComps AthenaKernel StoreGateLib GaudiKernel TrigConfxAODLib ) endif() diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/Root/prepareTriggerMenu.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/Root/prepareTriggerMenu.cxx index 86f3999fc2dfa295647a68d1fd5cc6a4adffe3e4..51fbb0cbcfddb0580c7577255cd22da7c5388169 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/Root/prepareTriggerMenu.cxx +++ b/Trigger/TrigConfiguration/TrigConfxAOD/Root/prepareTriggerMenu.cxx @@ -16,6 +16,15 @@ #include "TrigConfHLTData/HLTTriggerElement.h" #include "TrigConfHLTData/HLTSignature.h" +#include "TrigConfData/HLTMenu.h" +#include "TrigConfData/L1Menu.h" +#include "TrigConfData/HLTPrescalesSet.h" +#include "TrigConfData/L1PrescalesSet.h" +#include "TrigConfData/L1BunchGroupSet.h" + +#include "TrigConfData/HLTChain.h" +#include "TrigConfData/L1Item.h" + // Local include(s): #include "TrigConfxAOD/tools/prepareTriggerMenu.h" @@ -235,7 +244,7 @@ namespace TrigConf { } // Let the user know what happened: - msg << MSG::INFO << "Loaded configuration:" << endmsg; + msg << MSG::INFO << "Loaded xAOD::TriggerMenu configuration:" << endmsg; msg << MSG::INFO << " SMK = " << menu->smk() << ", L1PSK = " << menu->l1psk() << ", HLTPSK = " << menu->hltpsk() << endmsg; @@ -244,4 +253,131 @@ namespace TrigConf { return StatusCode::SUCCESS; } + /// Load JSON derived data into legacy structures to maintain + /// compatiblity with existing code. + /// + /// @param loadedHlt The incoming HLT trigger menu object to translate + /// @param loadedL1 The incoming L1 trigger menu object to translate + /// @param loadedHltps The incoming HLT prescales menu object to translate + /// @param loadedL1ps The incoming L1 prescales menu object to translate + /// @param loadedBg The incoming bunchgroup object to translate + /// @param ctpConfig The LVL1 configuration object to fill + /// @param chainList The HLT configuration object to fill + /// @param bgSet The bunch structure configuration object to fill + /// @param msg MsgStream to print messages to + /// @returns <code>StatusCode::SUCCESS</code> if successful, + /// <code>StatusCode::FAILURE</code> if not + /// + StatusCode prepareTriggerMenu(const HLTMenu& loadedHlt, + const L1Menu& loadedL1, + const HLTPrescalesSet& loadedHltps, + const L1PrescalesSet& loadedL1ps, + const L1BunchGroupSet& /*loadedBgSet unused so far*/, + CTPConfig& ctpConfig, + HLTChainList& chainList, + HLTSequenceList& sequenceList, + BunchGroupSet& /*bgSet unused so far*/, + MsgStream& msg ) { + + // Clear the current LVL1 configuration: + ctpConfig.menu().clear(); + ctpConfig.clearPrescaleSets(); + ctpConfig.prescaleSet().resize( 512 ); + + // Fill the LVL1 configuration: + for (const L1Item& loadedItem : loadedL1) { + TriggerItem* item = new TriggerItem(); + item->setName( loadedItem.name() ); + item->setCtpId( loadedItem.ctpId() ); + ctpConfig.menu().addTriggerItem( item ); + + const L1PrescalesSet::L1Prescale& loadedPrescale = loadedL1ps.prescale( loadedItem.name() ); + ctpConfig.prescaleSet().setPrescale( loadedItem.ctpId(), static_cast< float >( loadedPrescale.prescale ) ); + ctpConfig.prescaleSet().setPrescale( loadedItem.ctpId(), static_cast< float >( 1.0 ) ); + + if( msg.level() <= MSG::VERBOSE ) { + msg << MSG::VERBOSE << "L1 item " << loadedItem.name() + << " has ctpid " << loadedItem.ctpId() + << " and prescale " << static_cast< float >( loadedPrescale.prescale ) + << endmsg; + } + } + + // Clear the current HLT configuration: + chainList.clear(); + sequenceList.clear(); + + // Fill the HLT configuration: + for (const Chain& loadedChain : loadedHlt) { + // Figure out which level this chain is from: + std::string level = ""; + if( loadedChain.name().find( "L2_" ) == 0 ) { + level = "L2"; + } else if( loadedChain.name().find( "EF_" ) == 0 ) { + level = "EF"; + } else if( loadedChain.name().find( "HLT_" ) == 0 ) { + level = "HLT"; + } else { + msg << MSG::WARNING << "prepareTriggerMenu(...): " + << "Couldn't figure out 'level' for chain: " + << loadedChain.name() << endmsg; + } + // An empty signature list for the chain: + // This is not populated from JSON data + std::vector< HLTSignature* > signatures; + + // Create the chain object: + HLTChain* chain = new HLTChain( loadedChain.name(), + loadedChain.counter(), + 1, // Chain version not important + level, + loadedChain.l1item(), // L1 seeds (string) + -1, // Lower chain ID not important + signatures ); // Note: Empty + + const HLTPrescalesSet::HLTPrescale& loadedPrescale = loadedHltps.prescale( loadedChain.name() ); + chain->set_rerun_prescale( -1.0 ); // Not used in R3 + chain->set_pass_through( -1.0 ); // Not used in R3 + chain->set_prescale( loadedPrescale.prescale ); + + // Add it to the list of chains: + if( ! chainList.addHLTChain( chain ) ) { + msg << MSG::FATAL << "prepareTriggerMenu(...): " + << "Couldn't add chain \"" << chain->name() + << "\"" << endmsg; + delete chain; + return StatusCode::FAILURE; + } + } + + // Do not add sequence info to legacy structures (format is different) + + // Bunchgroup data is TODO + // // Create a new BunchGroupSet object, since an existing one can't be + // // modified... :-/ + // BunchGroupSet bgSetNew; + + // // Fill it with info: + // for( size_t i = 0; i < loadedBgSet.size(); ++i ) { + + // const L1BunchGroup& loadedBg = loadedBgSet.getBunchGroup(i); + + // // Create a BunchGroup object: + // BunchGroup bg; + // bg.setInternalNumber( i ); + // // TODO - need to call bg.addBunch( B ); for each bunch + // // Might need to make some changes to L1BunchGroupSet to make this more efficient + + // // Add it to the set: + // bgSetNew.addBunchGroup( bg ); + // } + + // // Replace the current bunch-group set with the new one: + // bgSet = bgSetNew; + + // Return gracefully: + return StatusCode::SUCCESS; + } + + } // namespace TrigConf diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/Root/xAODConfigTool.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/Root/xAODConfigTool.cxx index a47c1e92e09787e8cc5999fba1ba0661e53a8df4..51b16f838ca411ef533e7222e9b88f5dfa92c9e4 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/Root/xAODConfigTool.cxx +++ b/Trigger/TrigConfiguration/TrigConfxAOD/Root/xAODConfigTool.cxx @@ -11,18 +11,21 @@ #include "TrigConfL1Data/BunchGroup.h" #include "TrigConfHLTData/HLTSequenceList.h" -// xAOD include(s): -#include "xAODTrigger/TrigConfKeys.h" - // Local include(s): #include "TrigConfxAOD/xAODConfigTool.h" #include "TrigConfxAOD/tools/prepareTriggerMenu.h" #include "TrigConfxAOD/tools/xAODKeysMatch.h" +// Boost includes +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> + namespace TrigConf { struct xAODConfigTool::Impl { + /// Note: The run 3 JSON derives objects below are used to + /// additionally populate these objects for interface backwards compatibility /// The "translated" LVL1 configuration object CTPConfig m_ctpConfig; /// The "translated" HLT configuration object @@ -31,15 +34,39 @@ namespace TrigConf { HLTSequenceList m_sequenceList; /// The "translated" bunch group set object BunchGroupSet m_bgSet; + + /// The JSON decoded Run3 HLT menu + HLTMenu m_currentHlt; + /// The JSON decoded Run3 L1 menu + L1Menu m_currentL1; + /// The JSON decoded current HLT prescales set + HLTPrescalesSet m_currentHltps; + /// The JSON decoded current L1 prescales set + L1PrescalesSet m_currentL1ps; + /// The JSON decoded current Bunchgroup configuration + L1BunchGroupSet m_currentBg; }; xAODConfigTool::xAODConfigTool( const std::string& name ) : asg::AsgMetadataTool( name ), - m_tmc( 0 ), m_menu( 0 ), + m_tmc( nullptr ), + m_hltJson( nullptr), m_l1Json( nullptr ), + m_hltpsJson( nullptr ), m_l1psJson( nullptr ), m_bgJson( nullptr ), + m_menu( nullptr ), + m_currentHltJson( nullptr ), m_currentL1Json( nullptr ), + m_currentHltpsJson( nullptr ), m_currentL1psJson( nullptr ), m_currentBgJson( nullptr ), + m_triggerMenuContainerAvailable(false), + m_menuJSONContainerAvailable(false), m_impl (std::make_unique<Impl>()) { declareProperty( "EventObjectName", m_eventName = "TrigConfKeys" ); - declareProperty( "MetaObjectName", m_metaName = "TriggerMenu" ); + declareProperty( "MetaObjectName", m_metaName_run2 = "TriggerMenu" ); + + declareProperty( "JSONMetaObjectNameHLT", m_metaNameJSON_hlt = "TriggerMenuJson_HLT" ); + declareProperty( "JSONMetaObjectNameL1", m_metaNameJSON_l1 = "TriggerMenuJson_L1" ); + declareProperty( "JSONMetaObjectNameHLTPS", m_metaNameJSON_hltps = "TriggerMenuJson_HLTPS" ); + declareProperty( "JSONMetaObjectNameL1PS", m_metaNameJSON_l1ps = "TriggerMenuJson_L1PS" ); + declareProperty( "JSONMetaObjectNameBunchgroup", m_metaNameJSON_bg = "TriggerMenuJson_BG" ); } xAODConfigTool::~xAODConfigTool() @@ -51,19 +78,37 @@ namespace TrigConf { // Greet the user: ATH_MSG_INFO( "Initialising..." ); ATH_MSG_DEBUG( "EventObjectName = " << m_eventName ); - ATH_MSG_DEBUG( "MetaObjectName = " << m_metaName ); + ATH_MSG_DEBUG( "-- Run 2 AOD Configuration Settings"); + ATH_MSG_DEBUG( "MetaObjectName = " << m_metaName_run2 ); + ATH_MSG_DEBUG( "-- Run 3 AOD Configuration Settings"); + ATH_MSG_DEBUG( "JSONMetaObjectNameHLT = " << m_metaNameJSON_hlt ); + ATH_MSG_DEBUG( "JSONMetaObjectNameL1 = " << m_metaNameJSON_l1 ); + ATH_MSG_DEBUG( "JSONMetaObjectNameHLTPS = " << m_metaNameJSON_hltps ); + ATH_MSG_DEBUG( "JSONMetaObjectNameL1PS = " << m_metaNameJSON_l1ps ); + ATH_MSG_DEBUG( "JSONMetaObjectNameBunchgroup = " << m_metaNameJSON_bg ); // Reset the pointers: - m_tmc = 0; m_menu = 0; + m_tmc = nullptr; + m_menu = nullptr; + // + m_hltJson = nullptr; + m_l1Json = nullptr; + m_hltpsJson = nullptr; + m_l1psJson = nullptr; + m_bgJson = nullptr; + m_currentHltJson = nullptr; + m_currentL1Json = nullptr; + m_currentHltpsJson = nullptr; + m_currentL1psJson = nullptr; + m_currentBgJson = nullptr; // Return gracefully: return StatusCode::SUCCESS; } const CTPConfig* xAODConfigTool::ctpConfig() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_ctpConfig.menu().size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } @@ -73,9 +118,8 @@ namespace TrigConf { } const BunchGroupSet* xAODConfigTool::bunchGroupSet() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_bgSet.bunchGroups().size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } @@ -85,33 +129,38 @@ namespace TrigConf { } uint32_t xAODConfigTool::lvl1PrescaleKey() const { + if ( m_menuJSONContainerAvailable ) { - // Check if the object is well prepared: - if( ! m_menu ) { - ATH_MSG_FATAL( "Trigger menu not loaded" ); - throw std::runtime_error( "Tool not initialised correctly" ); - } + return m_currentL1psJson->key(); + + } else { + + // Check if the object is well prepared: + if( ! m_menu ) { + ATH_MSG_FATAL( "Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } - // Return the key from the metadata object: - return m_menu->l1psk(); + // Return the key from the metadata object: + return m_menu->l1psk(); + + } } const HLTChainList* xAODConfigTool::chainList() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_chainList.size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } - // Return the pointer: + // Return the object: return &m_impl->m_chainList; } const HLTChainList& xAODConfigTool::chains() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_chainList.size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } @@ -121,21 +170,19 @@ namespace TrigConf { } const HLTSequenceList* xAODConfigTool::sequenceList() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_sequenceList.size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } - // Return the pointer: + // Return the object: return &m_impl->m_sequenceList; } const HLTSequenceList& xAODConfigTool::sequences() const { - // Check if the object is well prepared: - if( ! m_menu ) { + if( m_impl->m_sequenceList.size() == 0 ) { ATH_MSG_FATAL( "Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } @@ -145,27 +192,81 @@ namespace TrigConf { } uint32_t xAODConfigTool::masterKey() const { + if (m_menuJSONContainerAvailable) { - // Check if the object is well prepared: - if( ! m_menu ) { - ATH_MSG_FATAL( "Trigger menu not loaded" ); + return m_currentHltJson->key(); + + } else { + + // Check if the object is well prepared: + if( ! m_menu ) { + ATH_MSG_FATAL( "Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } + + // Return the key from the metadata object: + return m_menu->smk(); + + } + } + + uint32_t xAODConfigTool::hltPrescaleKey() const { + if (m_menuJSONContainerAvailable) { + + return m_currentHltpsJson->key(); + + } else { + + // Check if the object is well prepared: + if( ! m_menu ) { + ATH_MSG_FATAL( "Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } + + // Return the key from the metadata object: + return m_menu->hltpsk(); + + } + } + + const HLTMenu& xAODConfigTool::hltMenu() const { + if( ! m_menuJSONContainerAvailable ) { + ATH_MSG_FATAL( "Run 3 format Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } + return m_impl->m_currentHlt; + } - // Return the key from the metadata object: - return m_menu->smk(); + const L1Menu& xAODConfigTool::l1Menu() const { + if( ! m_menuJSONContainerAvailable ) { + ATH_MSG_FATAL( "Run 3 format Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } + return m_impl->m_currentL1; } - uint32_t xAODConfigTool::hltPrescaleKey() const { + const HLTPrescalesSet& xAODConfigTool::hltPrescalesSet() const { + if( ! m_menuJSONContainerAvailable ) { + ATH_MSG_FATAL( "Run 3 format Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } + return m_impl->m_currentHltps; + } - // Check if the object is well prepared: - if( ! m_menu ) { - ATH_MSG_FATAL( "Trigger menu not loaded" ); + const L1PrescalesSet& xAODConfigTool::l1PrescalesSet() const { + if( ! m_menuJSONContainerAvailable ) { + ATH_MSG_FATAL( "Run 3 format Trigger menu not loaded" ); throw std::runtime_error( "Tool not initialised correctly" ); } + return m_impl->m_currentL1ps; + } - // Return the key from the metadata object: - return m_menu->hltpsk(); + const L1BunchGroupSet& xAODConfigTool::l1BunchGroupSet() const { + if( ! m_menuJSONContainerAvailable ) { + ATH_MSG_FATAL( "Run 3 format Trigger menu not loaded" ); + throw std::runtime_error( "Tool not initialised correctly" ); + } + return m_impl->m_currentBg; } StatusCode xAODConfigTool::beginInputFile() { @@ -173,30 +274,107 @@ namespace TrigConf { // Tell the user what's happening: ATH_MSG_DEBUG( "Loading the trigger menu from a new input file" ); - // Read the metadata object: - m_tmc = 0; - ATH_CHECK( inputMetaStore()->retrieve( m_tmc, m_metaName ) ); + // Try to read the R2 metadata object: + m_tmc = nullptr; + m_triggerMenuContainerAvailable = true; + if( inputMetaStore()->retrieve( m_tmc, m_metaName_run2 ).isFailure() ) { + m_triggerMenuContainerAvailable = false; + } + + // Try to read the R3 metadata object: + m_hltJson = nullptr; + m_l1Json = nullptr; + m_hltpsJson = nullptr; + m_l1psJson = nullptr; + m_bgJson = nullptr; + m_menuJSONContainerAvailable = true; + if( inputMetaStore()->retrieve( m_hltJson, m_metaNameJSON_hlt ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( inputMetaStore()->retrieve( m_l1Json, m_metaNameJSON_l1 ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( inputMetaStore()->retrieve( m_hltpsJson, m_metaNameJSON_hltps ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( inputMetaStore()->retrieve( m_l1psJson, m_metaNameJSON_l1ps ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + // if( inputMetaStore()->retrieve( m_bgJson, m_metaNameJSON_bg ).isFailure() ) { + // m_menuJSONContainerAvailable = false; + // } + - // A little sanity check: - if( ! m_tmc->size() ) { - // This can happen when we encounter empty input files. In which - // case we should not bail, but continue, and only bail if by the - // start of an event, we still don't see any configurations. + if( !m_triggerMenuContainerAvailable && !m_menuJSONContainerAvailable ) { ATH_MSG_WARNING( "No trigger configurations are available on " "the input" ); return StatusCode::SUCCESS; } - // Point the menu pointer to the first element by default: - m_menu = m_tmc->at( 0 ); - // Cache the menu's configuration: - ATH_CHECK( prepareTriggerMenu( m_menu, m_impl->m_ctpConfig, - m_impl->m_chainList, - m_impl->m_sequenceList, - m_impl->m_bgSet, msg() ) ); + // Prefer run three format, if available + if (m_menuJSONContainerAvailable) { + + // A little sanity check: + if( m_hltJson->size() == 0 ) { + // This can happen when we encounter empty input files. In which + // case we should not bail, but continue, and only bail if by the + // start of an event, we still don't see any configurations. + ATH_MSG_WARNING( "No trigger configurations are available on " + "the input" ); + return StatusCode::SUCCESS; + } + + // Load the first elements by default + ATH_CHECK( m_hltJson->size() > 0 ); + ATH_CHECK( m_l1Json->size() > 0 ); + ATH_CHECK( m_hltpsJson->size() > 0 ); + ATH_CHECK( m_l1psJson->size() > 0 ); + // ATH_CHECK( m_bgJson->size() > 0 ); + + m_currentHltJson = m_hltJson->at( 0 ); + m_currentL1Json = m_l1Json->at( 0 ); + m_currentHltpsJson = m_hltpsJson->at( 0 ); + m_currentL1psJson = m_l1psJson->at( 0 ); + // m_currentBgJson = m_bgJson->at( 0 ); + + ATH_CHECK( loadPtrees() ); + + ATH_CHECK( prepareTriggerMenu( m_impl->m_currentHlt, + m_impl->m_currentL1, + m_impl->m_currentHltps, + m_impl->m_currentL1ps, + m_impl->m_currentBg, + m_impl->m_ctpConfig, + m_impl->m_chainList, + m_impl->m_sequenceList, + m_impl->m_bgSet, msg() ) ); - // Return gracefully: - return StatusCode::SUCCESS; + return StatusCode::SUCCESS; + + } else if (m_triggerMenuContainerAvailable) { + + // A little sanity check: + if( m_tmc->size() == 0 ) { + // This can happen when we encounter empty input files. In which + // case we should not bail, but continue, and only bail if by the + // start of an event, we still don't see any configurations. + ATH_MSG_WARNING( "No trigger configurations are available on " + "the input" ); + return StatusCode::SUCCESS; + } + + m_menu = m_tmc->at( 0 ); + // Cache the menu's configuration: + ATH_CHECK( prepareTriggerMenu( m_menu, m_impl->m_ctpConfig, + m_impl->m_chainList, + m_impl->m_sequenceList, + m_impl->m_bgSet, msg() ) ); + + return StatusCode::SUCCESS; + } + + ATH_MSG_ERROR( "Both m_menuJSONContainerAvailable and m_triggerMenuContainerAvailable are false"); + return StatusCode::FAILURE; // Should never get here as checked that one or the other is true above } StatusCode xAODConfigTool::beginEvent() { @@ -205,14 +383,27 @@ namespace TrigConf { // mode at the very beginning of the application. (Depending on the // creation order of the objects.) So make sure that we have the // configuration objects at hand... - if( ( ! m_tmc ) || ( ! m_menu ) ) { + if( !m_triggerMenuContainerAvailable and !m_menuJSONContainerAvailable ) { ATH_CHECK( beginInputFile() ); } // Read the current event's trigger keys: - const xAOD::TrigConfKeys* keys = 0; + const xAOD::TrigConfKeys* keys = nullptr; ATH_CHECK( evtStore()->retrieve( keys, m_eventName ) ); + // Prefer Run 3 data if available + if (m_menuJSONContainerAvailable) { + return beginEvent_Run3(keys); + } else if (m_triggerMenuContainerAvailable) { + return beginEvent_Run2(keys); + } + + ATH_MSG_ERROR( "Both m_menuJSONContainerAvailable and m_triggerMenuContainerAvailable are false"); + return StatusCode::FAILURE; + + } + + StatusCode xAODConfigTool::beginEvent_Run2(const xAOD::TrigConfKeys* keys) { // Check if we have the correct menu already: if( m_menu && xAODKeysMatch( keys, m_menu ) ) { return StatusCode::SUCCESS; @@ -242,4 +433,98 @@ namespace TrigConf { return StatusCode::FAILURE; } + StatusCode xAODConfigTool::beginEvent_Run3(const xAOD::TrigConfKeys* keys) { + // Check if we have the correct menu already: + bool validConfig = true; + if (m_currentHltJson->key() != keys->smk()) { + validConfig = false; + } + if (m_currentL1Json->key() != keys->smk()) { + validConfig = false; + } + if (m_currentHltpsJson->key() != keys->hltpsk()) { + validConfig = false; + } + if (m_currentL1psJson->key() != keys->l1psk()) { + validConfig = false; + } + // if (m_currentBgJson->key() != TODO) { + // validConfig = false; + // } + + if (validConfig) { + return StatusCode::SUCCESS; + } + + // If not, load correct JSON menus from their respective containers, matching against the event's keys ... + ATH_CHECK( loadJsonByKey("HLT Menu", m_hltJson, keys->smk(), m_currentHltJson) ); + ATH_CHECK( loadJsonByKey("L1 Menu", m_l1Json, keys->smk(), m_currentL1Json) ); + ATH_CHECK( loadJsonByKey("HLT Prescales", m_hltpsJson, keys->hltpsk(), m_currentHltpsJson) ); + ATH_CHECK( loadJsonByKey("L1 Prescales", m_l1psJson, keys->l1psk(), m_currentL1psJson) ); + // ATH_CHECK( loadJsonByKey("Bunchgroups", m_bgJson, TODO, m_currentBgJson) ); + + // ... and from these serialised JSON strings, populate the ptree data structures... + ATH_CHECK( loadPtrees() ); // R3 interfaces now active + // ... and finally populate the legacy interface from the ptree data + ATH_CHECK( prepareTriggerMenu( m_impl->m_currentHlt, + m_impl->m_currentL1, + m_impl->m_currentHltps, + m_impl->m_currentL1ps, + m_impl->m_currentBg, + m_impl->m_ctpConfig, + m_impl->m_chainList, + m_impl->m_sequenceList, + m_impl->m_bgSet, msg() ) ); // R2 interfaces now active + + return StatusCode::SUCCESS; + } + + StatusCode xAODConfigTool::loadJsonByKey(const std::string& humanName, + const xAOD::TriggerMenuJsonContainer* metaContainer, + const uint32_t keyToCheck, + const xAOD::TriggerMenuJson*& ptrToSet) + { + xAOD::TriggerMenuJsonContainer::const_iterator menu_itr = metaContainer->begin(); + xAOD::TriggerMenuJsonContainer::const_iterator menu_end = metaContainer->end(); + for( ; menu_itr != menu_end; ++menu_itr ) { + // Check if this is the menu we're looking for: + if( keyToCheck != (*menu_itr)->key() ) continue; + ptrToSet = *menu_itr; + return StatusCode::SUCCESS; + } + + ATH_MSG_FATAL("Couldn't find configuration for current event" + << ", Requested key=" << keyToCheck + << ", Requested menu=" << humanName); + return StatusCode::FAILURE; + } + + StatusCode xAODConfigTool::loadPtrees() { + ATH_CHECK( loadPtree("HLT Menu", m_currentHltJson, m_impl->m_currentHlt) ); + ATH_CHECK( loadPtree("L1 Menu", m_currentL1Json, m_impl->m_currentL1) ); + ATH_CHECK( loadPtree("HLT Prescales", m_currentHltpsJson, m_impl->m_currentHltps) ); + ATH_CHECK( loadPtree("L1 Prescales", m_currentL1psJson, m_impl->m_currentL1ps) ); + // ATH_CHECK( loadPtree("Bunchgroups", m_currentBgJson, m_impl->m_currentBg) ); + return StatusCode::SUCCESS; + } + + StatusCode xAODConfigTool::loadPtree(const std::string& humanName, + const xAOD::TriggerMenuJson* menu, + DataStructure& dataStructure) + { + std::stringstream rawData; + rawData << menu->payload(); + dataStructure.clear(); + try { + boost::property_tree::ptree pt; + boost::property_tree::read_json(rawData, pt); + dataStructure.setData(std::move(pt)); + } catch (const boost::property_tree::json_parser_error& e) { + ATH_MSG_FATAL("Unable to decode a JSON trigger menu metadata payload for " << humanName << " with key " << menu->key()); + ATH_MSG_FATAL(e.what()); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + } // namespace TrigConf diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/tools/prepareTriggerMenu.h b/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/tools/prepareTriggerMenu.h index 08453573b75a0c47bae3dcd1ef3f0b63b65486ee..a92f2b3be65b5caf5dce2eacff0e599a1a7833f6 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/tools/prepareTriggerMenu.h +++ b/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/tools/prepareTriggerMenu.h @@ -22,18 +22,34 @@ namespace TrigConf { // Forward declaration(s): class CTPConfig; class HLTChainList; - class HLTSequenceList; + class HLTSequenceList; class BunchGroupSet; + class HLTMenu; + class L1Menu; + class HLTPrescalesSet; + class L1PrescalesSet; + class L1BunchGroupSet; - /// Function providing translation for the transient configuration + /// Function providing translation for the transient configuration from the R2 AOD format StatusCode prepareTriggerMenu( const xAOD::TriggerMenu* menu, CTPConfig& ctpConfig, HLTChainList& chainList, - HLTSequenceList& sequenceList, + HLTSequenceList& sequenceList, BunchGroupSet& bgSet, MsgStream& msg ); + StatusCode prepareTriggerMenu(const HLTMenu& loadedHlt, + const L1Menu& loadedL1, + const HLTPrescalesSet& loadedHltps, + const L1PrescalesSet& loadedL1ps, + const L1BunchGroupSet& loadedBgSet, + CTPConfig& ctpConfig, + HLTChainList& chainList, + HLTSequenceList& sequenceList, + BunchGroupSet& bgSet, + MsgStream& msg ); + } // namespace TrigConf #endif // TRIGCONFXAOD_TOOLS_PREPARETRIGGERMENU_H diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/xAODConfigTool.h b/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/xAODConfigTool.h index dae82ccd6042f8f19890de9b74c335b22b30ec5f..a2727d5b3bc97c6a9701a9ccbd12f77aec434289 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/xAODConfigTool.h +++ b/Trigger/TrigConfiguration/TrigConfxAOD/TrigConfxAOD/xAODConfigTool.h @@ -12,16 +12,29 @@ #include "AsgTools/AsgMetadataTool.h" // Trigger configuration include(s): +// Run 2 / legacy structures #include "TrigConfInterfaces/ITrigConfigTool.h" #include "TrigConfL1Data/CTPConfig.h" #include "TrigConfL1Data/BunchGroupSet.h" #include "TrigConfHLTData/HLTChainList.h" #include "TrigConfHLTData/HLTSequenceList.h" +// Run 3 structures +#include "TrigConfData/HLTMenu.h" +#include "TrigConfData/L1Menu.h" +#include "TrigConfData/HLTPrescalesSet.h" +#include "TrigConfData/L1PrescalesSet.h" +#include "TrigConfData/L1BunchGroupSet.h" +#include "TrigConfData/DataStructure.h" // xAOD include(s): #include "xAODTrigger/TriggerMenu.h" #include "xAODTrigger/TriggerMenuContainer.h" +#include "xAODTrigger/TriggerMenuJson.h" +#include "xAODTrigger/TriggerMenuJsonContainer.h" + +#include "xAODTrigger/TrigConfKeys.h" + namespace TrigConf { /// Trigger configuration metadata tool for xAOD analysis @@ -96,6 +109,26 @@ namespace TrigConf { /// @} + /// @name Impliment the JSON config interface. TODO - add this to an abstract interface + /// @{ + + /// Returns the JSON configured HLTMenu ptree + const HLTMenu& hltMenu() const; + + /// Returns the JSON configured L1 ptree + const L1Menu& l1Menu() const; + + /// Returns the JSON configured HLT prescales ptree + const HLTPrescalesSet& hltPrescalesSet() const; + + /// Returns the JSON configured L1 prescales ptree + const L1PrescalesSet& l1PrescalesSet() const; + + /// Returns the JSON configured bunchgroup ptree + const L1BunchGroupSet& l1BunchGroupSet() const; + + /// @} + protected: /// @name Callback function(s) from AsgMetadataTool /// @{ @@ -106,18 +139,68 @@ namespace TrigConf { /// Function called when a new event is loaded virtual StatusCode beginEvent(); + /// Internal call to check / load from a file with Run2 metadata + StatusCode beginEvent_Run2(const xAOD::TrigConfKeys* keys); + + /// Internal call to check / load from a file with Run3 metadata + StatusCode beginEvent_Run3(const xAOD::TrigConfKeys* keys); + /// @} private: + + /// @name Run 3 helper functions + /// @{ + + /// Locates a Run3 TriggerMenuJson object inside a container by key. Loads it into the m_currentXXXJson ptr + StatusCode loadJsonByKey(const std::string& humanName, + const xAOD::TriggerMenuJsonContainer* metaContainer, + const uint32_t keyToCheck, + const xAOD::TriggerMenuJson*& ptrToSet); + + /// Load all m_currentXXXJson serialised JSON data into ptrees inside m_impl + StatusCode loadPtrees(); + + /// Load single m_currentXXXJson serialised JSON data into ptree + StatusCode loadPtree(const std::string& humanName, + const xAOD::TriggerMenuJson* menu, + DataStructure& dataStructure); + + /// @} + /// Key for the event-level configuration identifier object std::string m_eventName; - /// Key for the trigger configuration metadata object - std::string m_metaName; - - /// The configuration object of the current input file + /// Key for the trigger configuration metadata object (Run 2) + std::string m_metaName_run2; + /// Key for the trigger configuration metadata objects (Run 3) + std::string m_metaNameJSON_hlt; + std::string m_metaNameJSON_l1; + std::string m_metaNameJSON_hltps; + std::string m_metaNameJSON_l1ps; + std::string m_metaNameJSON_bg; + + /// The configuration object of the current input file (for Run2 AOD) const xAOD::TriggerMenuContainer* m_tmc; - /// The active configuration for the current event + /// The configuration object of the current input file (for Run3 AOD) + const xAOD::TriggerMenuJsonContainer* m_hltJson; + const xAOD::TriggerMenuJsonContainer* m_l1Json; + const xAOD::TriggerMenuJsonContainer* m_hltpsJson; + const xAOD::TriggerMenuJsonContainer* m_l1psJson; + const xAOD::TriggerMenuJsonContainer* m_bgJson; + + /// The active configuration for the current event (For Run2 AOD) const xAOD::TriggerMenu* m_menu; + /// The active configuration for the current event (For Run3 AOD) + const xAOD::TriggerMenuJson* m_currentHltJson; + const xAOD::TriggerMenuJson* m_currentL1Json; + const xAOD::TriggerMenuJson* m_currentHltpsJson; + const xAOD::TriggerMenuJson* m_currentL1psJson; + const xAOD::TriggerMenuJson* m_currentBgJson; + + /// Is decoded R2 format data available? + bool m_triggerMenuContainerAvailable; + /// Is decoded R3 format data available? + bool m_menuJSONContainerAvailable; // A few members moved to an impl class to hide them from cling. // Otherwise, we get warnings about the use of boost::multi_index diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.cxx index 819164ebbbaae344b5348712eb5089bd1bd6d9ac..5ecb14cd5089cbe8f8df3f9b06543ed14757d77b 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.cxx +++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.cxx @@ -19,6 +19,10 @@ #include "TrigConfxAOD/tools/prepareTriggerMenu.h" #include "TrigConfxAOD/tools/xAODKeysMatch.h" +// Boost includes +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> + namespace TrigConf { xAODConfigSvc::xAODConfigSvc( const std::string& name, ISvcLocator* svcLoc ) @@ -26,7 +30,9 @@ namespace TrigConf { m_stopOnFailure( true ), m_isInFailure( false ), m_tmcAux( nullptr ), m_tmc( nullptr ), m_menu(), m_ctpConfig(), m_chainList(), m_sequenceList(), m_bgSet(), - m_metaStore( "InputMetaDataStore", name ) { + m_metaStore( "InputMetaDataStore", name ), + m_triggerMenuContainerAvailable( false ), + m_menuJSONContainerAvailable( false ) { } @@ -49,10 +55,32 @@ namespace TrigConf { incSvc->addListener( this, IncidentType::BeginInputFile, 0, m_stopOnFailure ); + // Internal holder for R2 payloads m_tmcAux = std::make_unique<xAOD::TriggerMenuAuxContainer>(); m_tmc = std::make_unique<xAOD::TriggerMenuContainer>(); m_tmc->setStore( m_tmcAux.get() ); + // Internal holders for R3 payloads + m_hltJsonAux = std::make_unique<xAOD::TriggerMenuJsonAuxContainer>(); + m_hltJson = std::make_unique<xAOD::TriggerMenuJsonContainer>(); + m_hltJson->setStore( m_hltJsonAux.get() ); + + m_l1JsonAux = std::make_unique<xAOD::TriggerMenuJsonAuxContainer>(); + m_l1Json = std::make_unique<xAOD::TriggerMenuJsonContainer>(); + m_l1Json->setStore( m_l1JsonAux.get() ); + + m_hltpsJsonAux = std::make_unique<xAOD::TriggerMenuJsonAuxContainer>(); + m_hltpsJson = std::make_unique<xAOD::TriggerMenuJsonContainer>(); + m_hltpsJson->setStore( m_hltpsJsonAux.get() ); + + m_l1psJsonAux = std::make_unique<xAOD::TriggerMenuJsonAuxContainer>(); + m_l1psJson = std::make_unique<xAOD::TriggerMenuJsonContainer>(); + m_l1psJson->setStore( m_l1psJsonAux.get() ); + + m_bgJsonAux = std::make_unique<xAOD::TriggerMenuJsonAuxContainer>(); + m_bgJson = std::make_unique<xAOD::TriggerMenuJsonContainer>(); + m_bgJson->setStore( m_bgJsonAux.get() ); + // Reset the internal flag: m_isInFailure = false; @@ -97,19 +125,25 @@ namespace TrigConf { } uint32_t xAODConfigSvc::lvl1PrescaleKey() const { + if (m_menuJSONContainerAvailable) { - // Check that we know the configuration already: - if( ! m_menu.get()->m_ptr ) { - REPORT_MESSAGE( MSG::ERROR ) - << "Trigger menu not yet known. Configuration key not returned."; - throw GaudiException( "Service not initialised correctly", - "TrigConf::xAODConfigSvc::lvl1PrescaleKey", - StatusCode::FAILURE ); - return 0; - } + return m_currentL1psJson.get()->m_ptr->key(); - // Return the key from the slot-specific metadata object: - return m_menu.get()->m_ptr->l1psk(); + } else { + + // Check that we know the configuration already: + if( ! m_menu.get()->m_ptr ) { + REPORT_MESSAGE( MSG::ERROR ) + << "Trigger menu not yet known. Configuration key not returned."; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::lvl1PrescaleKey", + StatusCode::FAILURE ); + return 0; + } + + // Return the key from the slot-specific metadata object: + return m_menu.get()->m_ptr->l1psk(); + } } const HLTChainList* xAODConfigSvc::chainList() const { @@ -173,35 +207,99 @@ namespace TrigConf { } uint32_t xAODConfigSvc::masterKey() const { + if (m_menuJSONContainerAvailable) { - // Check that we know the configuration already: - if( ! m_menu.get()->m_ptr ) { - REPORT_MESSAGE( MSG::FATAL ) - << "Trigger menu not yet known. Configuration key not returned."; + return m_currentHltJson.get()->m_ptr->key(); + + } else { + + // Check that we know the configuration already: + if( ! m_menu.get()->m_ptr ) { + REPORT_MESSAGE( MSG::FATAL ) + << "Trigger menu not yet known. Configuration key not returned."; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::masterKey", + StatusCode::FAILURE ); + return 0; + } + + // Return the key from the slot-specific metadata object: + return m_menu.get()->m_ptr->smk(); + + } + } + + uint32_t xAODConfigSvc::hltPrescaleKey() const { + if (m_menuJSONContainerAvailable) { + + return m_currentHltpsJson.get()->m_ptr->key(); + + } else { + + // Check that we know the configuration already: + if( ! m_menu.get()->m_ptr ) { + REPORT_MESSAGE( MSG::FATAL ) + << "Trigger menu not yet known. Configuration key not returned."; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::hltPrescaleKey", + StatusCode::FAILURE ); + return 0; + } + + // Return the key from the slot-specific metadata object: + return m_menu.get()->m_ptr->hltpsk(); + + } + } + + const HLTMenu& xAODConfigSvc::hltMenu(const EventContext& ctx) const { + if (!m_menuJSONContainerAvailable) { + REPORT_MESSAGE( MSG::FATAL ) << "Run 3 hltMenu JSON not loaded." << endmsg; throw GaudiException( "Service not initialised correctly", - "TrigConf::xAODConfigSvc::masterKey", + "TrigConf::xAODConfigSvc::hltMenu", StatusCode::FAILURE ); - return 0; } + return *(m_currentHlt.get(ctx)); + } - // Return the key from the slot-specific metadata object: - return m_menu.get()->m_ptr->smk(); + const L1Menu& xAODConfigSvc::l1Menu(const EventContext& ctx) const { + if (!m_menuJSONContainerAvailable) { + REPORT_MESSAGE( MSG::FATAL ) << "Run 3 l1Menu JSON not loaded." << endmsg; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::l1Menu", + StatusCode::FAILURE ); + } + return *(m_currentL1.get(ctx)); } - uint32_t xAODConfigSvc::hltPrescaleKey() const { + const HLTPrescalesSet& xAODConfigSvc::hltPrescalesSet(const EventContext& ctx) const { + if (!m_menuJSONContainerAvailable) { + REPORT_MESSAGE( MSG::FATAL ) << "Run 3 hltPrescalesSet JSON not loaded." << endmsg; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::hltPrescalesSet", + StatusCode::FAILURE ); + } + return *(m_currentHltps.get(ctx)); + } - // Check that we know the configuration already: - if( ! m_menu.get()->m_ptr ) { - REPORT_MESSAGE( MSG::FATAL ) - << "Trigger menu not yet known. Configuration key not returned."; + const L1PrescalesSet& xAODConfigSvc::l1PrescalesSet(const EventContext& ctx) const { + if (!m_menuJSONContainerAvailable) { + REPORT_MESSAGE( MSG::FATAL ) << "Run 3 l1PrescalesSet JSON not loaded." << endmsg; throw GaudiException( "Service not initialised correctly", - "TrigConf::xAODConfigSvc::hltPrescaleKey", + "TrigConf::xAODConfigSvc::l1PrescalesSet", StatusCode::FAILURE ); - return 0; } + return *(m_currentL1ps.get(ctx)); + } - // Return the key from the slot-specific metadata object: - return m_menu.get()->m_ptr->hltpsk(); + const L1BunchGroupSet& xAODConfigSvc::l1BunchGroupSet(const EventContext& ctx) const { + if (!m_menuJSONContainerAvailable) { + REPORT_MESSAGE( MSG::FATAL ) << "Run 3 l1BunchGroupSet JSON not loaded." << endmsg; + throw GaudiException( "Service not initialised correctly", + "TrigConf::xAODConfigSvc::l1BunchGroupSet", + StatusCode::FAILURE ); + } + return *(m_currentBg.get(ctx)); } StatusCode xAODConfigSvc::queryInterface( const InterfaceID& riid, @@ -288,41 +386,149 @@ namespace TrigConf { StatusCode xAODConfigSvc::readMetadata() { - // Read the metadata object... - const xAOD::TriggerMenuContainer* input = nullptr; - if( m_metaStore->retrieve( input, m_metaName ).isFailure() ) { + // Only one thread at a time is allowed to process a new file being opened + // and this should only happen when it is not being iterated over + // as part of the BeginEvent incident. + std::unique_lock lockUnique(m_sharedMutex); + + m_triggerMenuContainerAvailable = true; + m_menuJSONContainerAvailable = true; + + // Read the R2 metadata object... + const xAOD::TriggerMenuContainer* input_tmc = nullptr; + if( m_metaStore->retrieve( input_tmc, m_metaName ).isFailure() ) { + m_triggerMenuContainerAvailable = false; + } + + // Read the R3 metadata object... + const xAOD::TriggerMenuJsonContainer* input_hlt = nullptr; + const xAOD::TriggerMenuJsonContainer* input_l1 = nullptr; + const xAOD::TriggerMenuJsonContainer* input_hltps = nullptr; + const xAOD::TriggerMenuJsonContainer* input_l1ps = nullptr; + // const xAOD::TriggerMenuJsonContainer* input_bg = nullptr; + if( m_metaStore->retrieve( input_hlt, m_metaNameJSON_hlt ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( m_metaStore->retrieve( input_l1, m_metaNameJSON_l1 ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( m_metaStore->retrieve( input_hltps, m_metaNameJSON_hltps ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + if( m_metaStore->retrieve( input_l1ps, m_metaNameJSON_l1ps ).isFailure() ) { + m_menuJSONContainerAvailable = false; + } + // if( m_metaStore->retrieve( input_bg, m_metaNameJSON_bg ).isFailure() ) { + // m_menuJSONContainerAvailable = false; + // } + + if (!m_triggerMenuContainerAvailable && !m_menuJSONContainerAvailable) { // Update the internal flag: m_isInFailure = true; // Decide what to do: if( m_stopOnFailure ) { - REPORT_MESSAGE( MSG::FATAL ) - << "Couldn't retrieve xAOD::TriggerMenuContainer"; + REPORT_MESSAGE( MSG::FATAL ) << "Couldn't retrieve xAOD::TriggerMenuContainer or xAOD::TriggerMenuJsonContainer(s)" << endmsg; return StatusCode::FAILURE; } else { - REPORT_MESSAGE( MSG::INFO ) << "Couldn't retrieve xAOD::TriggerMenuContainer" << endmsg; + REPORT_MESSAGE( MSG::WARNING ) << "Couldn't retrieve xAOD::TriggerMenuContainer or xAOD::TriggerMenuJsonContainer(s)" << endmsg; + return StatusCode::SUCCESS; + } + } + + // From file #2 and onwards, check for mixed-messages from the input files. + // Note from the check just above, we know that we have at least one type of data available on this input file + // + // We do this as we currently have just two "available" flags, for the two data formats. Not two per slot + if (m_tmc->size() > 0 && !m_triggerMenuContainerAvailable && m_menuJSONContainerAvailable) { + m_isInFailure = true; + m_triggerMenuContainerAvailable = false; + m_menuJSONContainerAvailable = false; + if( m_stopOnFailure ) { + REPORT_MESSAGE( MSG::FATAL ) + << "In this input file we found xAOD::TriggerMenuJsonContainer(s), but no xAOD::TriggerMenuContainer. " + << "This is inconsistent with previous input files." << endmsg; + return StatusCode::FAILURE; + } else { + REPORT_MESSAGE( MSG::WARNING ) + << "In this input file we found xAOD::TriggerMenuJsonContainer(s), but no xAOD::TriggerMenuContainer. " + << "This is inconsistent with previous input files." << endmsg; + return StatusCode::SUCCESS; + } + } + if (m_hltJson->size() > 0 && !m_menuJSONContainerAvailable && m_triggerMenuContainerAvailable) { + m_isInFailure = true; + m_triggerMenuContainerAvailable = false; + m_menuJSONContainerAvailable = false; + if( m_stopOnFailure ) { + REPORT_MESSAGE( MSG::FATAL ) + << "In this input file we found xAOD::TriggerMenuContainer, but no xAOD::TriggerMenuJsonContainer. " + << "This is inconsistent with previous input files." << endmsg; + return StatusCode::FAILURE; + } else { + REPORT_MESSAGE( MSG::WARNING ) + << "In this input file we found xAOD::TriggerMenuContainer, but no xAOD::TriggerMenuJsonContainer. " + << "This is inconsistent with previous input files." << endmsg; return StatusCode::SUCCESS; } } // Let the user know what happened: - REPORT_MESSAGE( MSG::DEBUG ) << "Loaded trigger configuration metadata container" << endmsg; + REPORT_MESSAGE( MSG::DEBUG ) << "Loaded trigger configuration metadata container(s)" << endmsg; + + // If available, give preference to the R3 format + if (m_menuJSONContainerAvailable) { + + copyMetadataToPersonalStore(input_hlt, m_hltJson.get()); + copyMetadataToPersonalStore(input_l1, m_l1Json.get()); + copyMetadataToPersonalStore(input_hltps, m_hltpsJson.get()); + copyMetadataToPersonalStore(input_l1ps, m_l1psJson.get()); + // copyMetadataToPersonalStore(input_bg, m_bgJson.get()); - // A little sanity check: - if( ! input->size() ) { - REPORT_MESSAGE( MSG::WARNING ) << "No trigger configurations are available on the input" << endmsg; return StatusCode::SUCCESS; - } - // Only one thread at a time is allowed to extend m_tmc, - // and this should only happen when it is not being iterated over - // as part of the BeginEvent indicent. - std::unique_lock lockUnique(m_sharedMutex); + } else if (m_triggerMenuContainerAvailable) { // Otherwise load the Run 2 format + + // A little sanity check: + if( ! input_tmc->size() ) { + REPORT_MESSAGE( MSG::WARNING ) << "No trigger configurations are available on the input" << endmsg; + return StatusCode::SUCCESS; + } + + // Copy in new menus + for ( const xAOD::TriggerMenu* inputMenu : *input_tmc ) { + bool alreadyHave = false; + for( const xAOD::TriggerMenu* existingMenu : *m_tmc ) { + if (xAODKeysMatch(inputMenu, existingMenu)) { + alreadyHave = true; + break; + } + } + if (alreadyHave) { + continue; + } + // Copy this menu into the service's internal cache of all menus + xAOD::TriggerMenu* newMenu = new xAOD::TriggerMenu(); + m_tmc->push_back( newMenu ); // Note: 'newMenu' is now memory managed by m_tmc + *newMenu = *inputMenu; + REPORT_MESSAGE( MSG::DEBUG ) << "Imported new configuration: SMK = " << newMenu->smk() + << ", L1PSK = " << newMenu->l1psk() + << ", HLTPSK = " << newMenu->hltpsk() << endmsg; + } - // Copy in new menus - for ( const xAOD::TriggerMenu* inputMenu : *input ) { + return StatusCode::SUCCESS; + + } // m_menuJSONContainerAvailable or m_triggerMenuContainerAvailable + + //Should never get here (due to check above) + ATH_MSG_ERROR( "Both m_menuJSONContainerAvailable and m_triggerMenuContainerAvailable are false" ); + return StatusCode::FAILURE; + } + + void xAODConfigSvc::copyMetadataToPersonalStore(const xAOD::TriggerMenuJsonContainer* input, xAOD::TriggerMenuJsonContainer* existing) { + for ( const xAOD::TriggerMenuJson* inputTriggerMenuJson : *input ) { bool alreadyHave = false; - for( const xAOD::TriggerMenu* existingMenu : *m_tmc ) { - if (xAODKeysMatch(inputMenu, existingMenu)) { + for( const xAOD::TriggerMenuJson* existingTriggerMenuJson : *existing ) { + if (inputTriggerMenuJson->key() == existingTriggerMenuJson->key()) { alreadyHave = true; break; } @@ -330,17 +536,12 @@ namespace TrigConf { if (alreadyHave) { continue; } - // Copy this menu into the service's internal cache of all menus - xAOD::TriggerMenu* newMenu = new xAOD::TriggerMenu(); - m_tmc->push_back( newMenu ); // Note: 'newMenu' is now memory managed by m_tmc - *newMenu = *inputMenu; - REPORT_MESSAGE( MSG::DEBUG ) << "Imported new configuration: SMK = " << newMenu->smk() - << ", L1PSK = " << newMenu->l1psk() - << ", HLTPSK = " << newMenu->hltpsk() << endmsg; + // Copy this menu JSON into the service's internal cache of all menus + xAOD::TriggerMenuJson* newTriggerMenuJson = new xAOD::TriggerMenuJson(); + existing->push_back( newTriggerMenuJson ); // Note: 'newTriggerMenuJson' is now memory managed by 'existing' + *newTriggerMenuJson = *inputTriggerMenuJson; // Perform xAOD copy + REPORT_MESSAGE( MSG::DEBUG ) << "Imported new configuration: Name = " << newTriggerMenuJson->name() << " Key = " << newTriggerMenuJson->key() << endmsg; } - - // Return gracefully: - return StatusCode::SUCCESS; } StatusCode xAODConfigSvc::prepareEvent() { @@ -364,10 +565,20 @@ namespace TrigConf { } } + if (m_menuJSONContainerAvailable) { // Run 3 AOD decoding mode + return prepareEventxAODTriggerMenuJson(keys.cptr(), context); + } else if (m_triggerMenuContainerAvailable) { // Run 2 AOD decoding mode + return prepareEventxAODTriggerMenu(keys.cptr(), context); + } + ATH_MSG_ERROR( "Both m_menuJSONContainerAvailable and m_triggerMenuContainerAvailable are false" ); + return StatusCode::FAILURE; + } + + StatusCode xAODConfigSvc::prepareEventxAODTriggerMenu(const xAOD::TrigConfKeys* keys, const EventContext& context) { const xAOD::TriggerMenu* loadedMenuInSlot = m_menu.get(context)->m_ptr; // Check if we have the correct menu already: - if( loadedMenuInSlot != nullptr && xAODKeysMatch( keys.cptr(), loadedMenuInSlot ) ) { + if( loadedMenuInSlot != nullptr && xAODKeysMatch( keys, loadedMenuInSlot ) ) { return StatusCode::SUCCESS; } @@ -380,7 +591,7 @@ namespace TrigConf { xAOD::TriggerMenuContainer::const_iterator menu_end = m_tmc->end(); for( ; menu_itr != menu_end; ++menu_itr ) { // Check if this is the menu we're looking for: - if( ! xAODKeysMatch( keys.cptr(), *menu_itr ) ) continue; + if( ! xAODKeysMatch( keys, *menu_itr ) ) continue; // Remember it's pointer: loadedMenuInSlot = *menu_itr; m_menu.get(context)->m_ptr = loadedMenuInSlot; @@ -408,4 +619,127 @@ namespace TrigConf { return StatusCode::FAILURE; } + + + + StatusCode xAODConfigSvc::prepareEventxAODTriggerMenuJson(const xAOD::TrigConfKeys* keys, const EventContext& context) { + const xAOD::TriggerMenuJson* loadedHltJson = m_currentHltJson.get(context)->m_ptr; + const xAOD::TriggerMenuJson* loadedL1Json = m_currentL1Json.get(context)->m_ptr; + const xAOD::TriggerMenuJson* loadedHltpsJson = m_currentHltpsJson.get(context)->m_ptr; + const xAOD::TriggerMenuJson* loadedL1psJson = m_currentL1psJson.get(context)->m_ptr; + //const xAOD::TriggerMenuJson* loadedBgJson = m_currentBgJson.get(context)->m_ptr; + + bool validConfig = true; + if (loadedHltJson == nullptr || loadedHltJson->key() != keys->smk()) { + validConfig = false; + } + if (loadedL1Json == nullptr || loadedL1Json->key() != keys->smk()) { + validConfig = false; + } + if (loadedHltpsJson == nullptr || loadedHltpsJson->key() != keys->hltpsk()) { + validConfig = false; + } + if (loadedL1psJson == nullptr || loadedL1psJson->key() != keys->l1psk()) { + validConfig = false; + } + // if (loadedBgJson == nullptr || loadedBgJson->key() != TODO) { + // validConfig = false; + // } + + if (validConfig) { + return StatusCode::SUCCESS; + } + + // If not, let's look for the correct configuration: + // Open a shared lock. OK for multiple events to search at the same time, + // but prevent the extension of m_hltJson et. al. from a BeginInputFile incident. + std::shared_lock lockShared(m_sharedMutex); + + TriggerMenuJsonPtrWrapper& currentHltJson = *(m_currentHltJson.get(context)); + TriggerMenuJsonPtrWrapper& currentL1Json = *(m_currentL1Json.get(context)); + TriggerMenuJsonPtrWrapper& currentHltpsJson = *(m_currentHltpsJson.get(context)); + TriggerMenuJsonPtrWrapper& currentL1psJson = *(m_currentL1psJson.get(context)); + //TriggerMenuJsonPtrWrapper& currentBgJson = *(m_currentBgJson.get(context)); + + TrigConf::HLTMenu& currentHlt = *(m_currentHlt.get(context)); + TrigConf::L1Menu& currentL1 = *(m_currentL1.get(context)); + TrigConf::HLTPrescalesSet& currentHltps = *(m_currentHltps.get(context)); + TrigConf::L1PrescalesSet& currentL1ps = *(m_currentL1ps.get(context)); + TrigConf::L1BunchGroupSet& currentBg = *(m_currentBg.get(context)); + + ATH_CHECK( loadPtree("HLT Menu", m_hltJson.get(), keys->smk(), currentHltJson, currentHlt) ); + ATH_CHECK( loadPtree("L1 Menu", m_l1Json.get(), keys->smk(), currentL1Json, currentL1) ); + ATH_CHECK( loadPtree("HLT Prescales", m_hltpsJson.get(), keys->hltpsk(), currentHltpsJson, currentHltps) ); + ATH_CHECK( loadPtree("L1 Prescales", m_l1psJson.get(), keys->l1psk(), currentL1psJson, currentL1ps) ); + // ATH_CHECK( loadPtree("Bunchgroups", m_bgJson.get(), TODO, currentBgGJson, currentBg) ); + + CTPConfig& ctpConfig = *(m_ctpConfig.get(context)); + HLTChainList& chainList = *(m_chainList.get(context)); + HLTSequenceList& sequenceList = *(m_sequenceList.get(context)); + BunchGroupSet& bgSet = *(m_bgSet.get(context)); + + CHECK( prepareTriggerMenu( currentHlt, + currentL1, + currentHltps, + currentL1ps, + currentBg, + ctpConfig, + chainList, + sequenceList, + bgSet, + msg() ) ); + + REPORT_MESSAGE( MSG::INFO ) << "Loaded xAOD::TriggerMenuJson configuration:" + << " SMK = " << keys->smk() + << ", L1PSK = " << keys->l1psk() + << ", HLTPSK = " << keys->hltpsk() << endmsg; + + REPORT_MESSAGE( MSG::DEBUG ) << "ctpConfig.menu().size() = " << ctpConfig.menu().size() + << " chainList.size() = " << chainList.size() + << " sequenceList.size() = " << sequenceList.size() + << " bgSet.bunchGroups().size() = " << bgSet.bunchGroups().size() << endmsg; + + return StatusCode::SUCCESS; + + } + + StatusCode xAODConfigSvc::loadPtree(const std::string& humanName, + const xAOD::TriggerMenuJsonContainer* metaContainer, + const uint32_t keyToCheck, + TriggerMenuJsonPtrWrapper& cacheOfLoadedMenuPtr, + DataStructure& dataStructure) { + xAOD::TriggerMenuJsonContainer::const_iterator menu_itr = metaContainer->begin(); + xAOD::TriggerMenuJsonContainer::const_iterator menu_end = metaContainer->end(); + const xAOD::TriggerMenuJson* ptrToLocatedMenu = nullptr; + for( ; menu_itr != menu_end; ++menu_itr ) { + // Check if this is the menu we're looking for: + if( keyToCheck != (*menu_itr)->key() ) continue; + // Remember its pointer: + ptrToLocatedMenu = *menu_itr; + cacheOfLoadedMenuPtr.m_ptr = ptrToLocatedMenu; + std::stringstream rawData; + rawData << ptrToLocatedMenu->payload(); + dataStructure.clear(); + try { + boost::property_tree::ptree pt; + boost::property_tree::read_json(rawData, pt); + dataStructure.setData(std::move(pt)); + } catch (const boost::property_tree::json_parser_error& e) { + REPORT_MESSAGE( MSG::FATAL ) << "Unable to decode a JSON trigger menu metadata payload for " << humanName << " with key " << keyToCheck << endmsg; + REPORT_MESSAGE( MSG::FATAL ) << e.what(); + return StatusCode::FAILURE; + } + } + + if (ptrToLocatedMenu == nullptr) { + REPORT_MESSAGE( MSG::FATAL ) + << "Couldn't find configuration for current event" + << ", Requested key=" << keyToCheck + << ", Requested menu=" << humanName + << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + } // namespace TrigConf diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.h b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.h index 3b359a7b399fa77c05710b46176f9c60a4e2d38d..5d23c7801c8cf3fd71902eb1b3d8032861e8841a 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.h +++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODConfigSvc.h @@ -22,10 +22,19 @@ #include "TrigConfHLTData/HLTChainList.h" #include "TrigConfHLTData/HLTSequenceList.h" +#include "TrigConfData/HLTMenu.h" +#include "TrigConfData/L1Menu.h" +#include "TrigConfData/HLTPrescalesSet.h" +#include "TrigConfData/L1PrescalesSet.h" +#include "TrigConfData/L1BunchGroupSet.h" + // xAOD include(s): #include "xAODTrigger/TriggerMenu.h" #include "xAODTrigger/TriggerMenuContainer.h" #include "xAODTrigger/TriggerMenuAuxContainer.h" +#include "xAODTrigger/TriggerMenuJson.h" +#include "xAODTrigger/TriggerMenuJsonContainer.h" +#include "xAODTrigger/TriggerMenuJsonAuxContainer.h" #include "xAODTrigger/TrigConfKeys.h" #include <shared_mutex> @@ -45,6 +54,14 @@ namespace TrigConf { const xAOD::TriggerMenu* m_ptr; }; + /** + * @short Small utility class to wrap a pointer to a const xAOD::TriggerMenuJson + */ + struct TriggerMenuJsonPtrWrapper { + TriggerMenuJsonPtrWrapper() : m_ptr(nullptr) {} + const xAOD::TriggerMenuJson* m_ptr; + }; + /** * @short Trigger configuration service used when reading an xAOD file * @@ -145,6 +162,26 @@ namespace TrigConf { /// @} + /// @name Impliment the JSON config interface. TODO - add this to an abstract interface + /// @{ + + /// Returns the JSON configured HLTMenu ptree + const HLTMenu& hltMenu(const EventContext& ctx) const; + + /// Returns the JSON configured L1 ptree + const L1Menu& l1Menu(const EventContext& ctx) const; + + /// Returns the JSON configured HLT prescales ptree + const HLTPrescalesSet& hltPrescalesSet(const EventContext& ctx) const; + + /// Returns the JSON configured L1 prescales ptree + const L1PrescalesSet& l1PrescalesSet(const EventContext& ctx) const; + + /// Returns the JSON configured bunchgroup ptree + const L1BunchGroupSet& l1BunchGroupSet(const EventContext& ctx) const; + + /// @} + /// Function describing to Gaudi the interface(s) implemented virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvIf ) override; @@ -162,27 +199,104 @@ namespace TrigConf { /// Function setting up the service for a new event StatusCode prepareEvent(); + /// Helper function for copying into the service's private data store + void copyMetadataToPersonalStore(const xAOD::TriggerMenuJsonContainer* input, xAOD::TriggerMenuJsonContainer* existing); + + /// Do per-event decoding for R3 serialised xAOD::TriggerMenuJson metadata + StatusCode prepareEventxAODTriggerMenuJson(const xAOD::TrigConfKeys* keys, const EventContext& context); + + /// Do per-event decoding for R2 serliased xAOD::TriggerMenu metadata + StatusCode prepareEventxAODTriggerMenu(const xAOD::TrigConfKeys* keys, const EventContext& context); + + /// Helper function to find a JSON in a given TriggerMenuJsonContainer using a given key, extract its ptree data + /// @param humanName Name to print if things go wrong + /// @param metaContainer Metadata container of TriggerMenuJson objects from which to load a ptree + /// @param keyToCheck The key of the ptree to load + /// @param cacheOfLoadedMenuPtr Slot's cache of the currently loaded TriggerMenuJson + /// @param DataStructure dataStructure object to fill with the TriggerMenuJson's payload + StatusCode loadPtree(const std::string& humanName, + const xAOD::TriggerMenuJsonContainer* metaContainer, + const uint32_t keyToCheck, + TriggerMenuJsonPtrWrapper& cacheOfLoadedMenuPtr, + DataStructure& dataStructure); SG::ReadHandleKey<xAOD::TrigConfKeys> m_eventKey{this, "EventObjectName", "TrigConfKeys", "Key for the event-level configuration identifier object"}; + + /// @name Names for reading the R2 (and R1) AOD metadata payload + /// @{ Gaudi::Property<std::string> m_metaName{this, "MetaObjectName", "TriggerMenu", "Key for the trigger configuration metadata object"}; + /// @} + + /// @name Names for reading the R3 AOD metadata payload + /// @{ + Gaudi::Property< std::string > m_metaNameJSON_hlt {this, "JSONMetaObjectNameHLT", "TriggerMenuJson_HLT", + "StoreGate key for the xAOD::TriggerMenuJson HLT configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_l1 {this, "JSONMetaObjectNameL1", "TriggerMenuJson_L1", + "StoreGate key for the xAOD::TriggerMenuJson L1 configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_hltps {this, "JSONMetaObjectNameHLTPS", "TriggerMenuJson_HLTPS", + "StoreGate key for the xAOD::TriggerMenuJson HLT prescales configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_l1ps {this, "JSONMetaObjectNameL1PS", "TriggerMenuJson_L1PS", + "StoreGate key for the xAOD::TriggerMenuJson L1 prescales configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_bg {this, "JSONMetaObjectNameBunchgroup", "TriggerMenuJson_BG", + "StoreGate key for the xAOD::TriggerMenuJson BunchGroup configuration object"}; + /// @} Gaudi::Property<bool> m_stopOnFailure{this, "StopOnFailure", true, "Flag for stopping the job in case of a failure"}; /// Internal state of the service bool m_isInFailure; - /// The configuration objects copied from all input files + /// + /// @name The configuration objects copied from all input files. R1 and R2 AOD + /// @{ std::unique_ptr<xAOD::TriggerMenuAuxContainer> m_tmcAux; - /// The configuration objects copied from all input files std::unique_ptr<xAOD::TriggerMenuContainer> m_tmc; + // The menu currently being used by each slot (wrapped 'const xAOD::TriggerMenu' ptr) + SG::SlotSpecificObj<MenuPtrWrapper> m_menu; + /// @} + + /// + /// @name The configuration objects copied from all input files. R3 AOD + /// @{ + std::unique_ptr<xAOD::TriggerMenuJsonAuxContainer> m_hltJsonAux; + std::unique_ptr<xAOD::TriggerMenuJsonContainer> m_hltJson; + std::unique_ptr<xAOD::TriggerMenuJsonAuxContainer> m_l1JsonAux; + std::unique_ptr<xAOD::TriggerMenuJsonContainer> m_l1Json; + std::unique_ptr<xAOD::TriggerMenuJsonAuxContainer> m_hltpsJsonAux; + std::unique_ptr<xAOD::TriggerMenuJsonContainer> m_hltpsJson; + std::unique_ptr<xAOD::TriggerMenuJsonAuxContainer> m_l1psJsonAux; + std::unique_ptr<xAOD::TriggerMenuJsonContainer> m_l1psJson; + std::unique_ptr<xAOD::TriggerMenuJsonAuxContainer> m_bgJsonAux; + std::unique_ptr<xAOD::TriggerMenuJsonContainer> m_bgJson; + + // The menu JSONs being used in the current event by each slot (wrapped 'const xAOD::TriggerMenuJson' ptr) + SG::SlotSpecificObj<TriggerMenuJsonPtrWrapper> m_currentHltJson; + SG::SlotSpecificObj<TriggerMenuJsonPtrWrapper> m_currentL1Json; + SG::SlotSpecificObj<TriggerMenuJsonPtrWrapper> m_currentHltpsJson; + SG::SlotSpecificObj<TriggerMenuJsonPtrWrapper> m_currentL1psJson; + SG::SlotSpecificObj<TriggerMenuJsonPtrWrapper> m_currentBgJson; + + // The decoded menu JSON data stored in ptree objects + SG::SlotSpecificObj<HLTMenu> m_currentHlt; + SG::SlotSpecificObj<L1Menu> m_currentL1; + SG::SlotSpecificObj<HLTPrescalesSet> m_currentHltps; + SG::SlotSpecificObj<L1PrescalesSet> m_currentL1ps; + SG::SlotSpecificObj<L1BunchGroupSet> m_currentBg; + /// @} + /// The mutex used to to restrict access to m_tmc when it is being written to std::shared_mutex m_sharedMutex; - // The menu currently being used by each slot (wrapped 'const xAOD::TriggerMenu' ptr) - SG::SlotSpecificObj<MenuPtrWrapper> m_menu; + /// + /// @name The legacy configuration objects which are populated either from a R1, R2 TriggerMenuContainer or the R3 JSONs + /// @{ /// The "translated" LVL1 configuration object SG::SlotSpecificObj<CTPConfig> m_ctpConfig; /// The "translated" HLT configuration object @@ -191,12 +305,20 @@ namespace TrigConf { SG::SlotSpecificObj<HLTSequenceList> m_sequenceList; /// The "translated" bunch group set object SG::SlotSpecificObj<BunchGroupSet> m_bgSet; + /// @} /// Connection to the metadata store ServiceHandle< StoreGateSvc > m_metaStore{this, "MetaDataStore", "InputMetaDataStore"}; + /// Is decoded R2 format data available? + bool m_triggerMenuContainerAvailable; + /// Is decoded R3 format data available? + bool m_menuJSONContainerAvailable; + }; // class xAODConfigSvc } // namespace TrigConf + + #endif // TRIGCONFXAOD_XAODCONFIGSVC_H diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx index 36bfe6108720a5ce53e75ce1b11a3fc60febfce9..1845f1253332b7743045ac61555f1c8d2ad8e521 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx +++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx @@ -17,10 +17,13 @@ #include "TrigConfHLTData/HLTSignature.h" #include "TrigConfHLTData/HLTTriggerElement.h" #include "TrigConfHLTData/HLTSequenceList.h" +#include "TrigConfHLTData/HLTPrescale.h" // EDM include(s): #include "xAODTrigger/TriggerMenu.h" #include "xAODTrigger/TriggerMenuAuxContainer.h" +#include "xAODTrigger/TriggerMenuJson.h" +#include "xAODTrigger/TriggerMenuJsonAuxContainer.h" // Local include(s): #include "xAODMenuWriterMT.h" @@ -44,8 +47,7 @@ namespace TrigConf { // Greet the user: ATH_MSG_INFO( "Initialising - Package version: " << PACKAGE_VERSION ); - ATH_MSG_DEBUG( "EventObjectName = " << m_eventName ); - ATH_MSG_DEBUG( "MetaObjectName = " << m_metaName ); + ATH_MSG_DEBUG( " EventObjectName = " << m_eventName ); ATH_MSG_VERBOSE( "TrigConfigSvc = " << m_trigConf ); ATH_MSG_VERBOSE( "MetaDataStore = " << m_metaStore ); @@ -56,19 +58,81 @@ namespace TrigConf { CHECK( m_eventName.initialize() ); // WriteHandleKey CHECK( m_HLTMenuKey.initialize(m_isHLTJSONConfig) ); // ReadHandleKey + CHECK( m_HLTPrescaleSetInputKey.initialize(m_isHLTJSONConfig) ); // ReadCondHandleKey + CHECK( m_L1MenuKey.initialize(m_isL1JSONConfig) ); // ReadHandleKey - + CHECK( m_L1PrescaleSetInputKey.initialize(m_isL1JSONConfig) ); // ReadCondHandleKey + // Clear the internal cache variable: m_convertedKeys.clear(); // Create an empty trigger menu container: - xAOD::TriggerMenuAuxContainer* aux = new xAOD::TriggerMenuAuxContainer(); - m_tmc = new xAOD::TriggerMenuContainer(); - m_tmc->setStore( aux ); + if (m_writexAODTriggerMenu) { + + ATH_MSG_DEBUG( "xAOD::TriggerMenuAuxContainer MetaObjectName = " << m_metaName ); + + xAOD::TriggerMenuAuxContainer* aux = new xAOD::TriggerMenuAuxContainer(); + m_tmc = new xAOD::TriggerMenuContainer(); + m_tmc->setStore( aux ); + + // Record the trigger configuration metadata into it: + CHECK( m_metaStore->record( aux, m_metaName + "Aux." ) ); + CHECK( m_metaStore->record( m_tmc, m_metaName ) ); + } + + if (m_writexAODTriggerMenuJson) { + + if (!m_isHLTJSONConfig) { + ATH_MSG_ERROR("Require IsHLTJSONConfig to be TRUE when WritexAODTriggerMenuJson is TRUE"); + return StatusCode::FAILURE; + } + + if (!m_isL1JSONConfig) { + ATH_MSG_ERROR("Require IsL1JSONConfig to be TRUE when WritexAODTriggerMenuJson is TRUE"); + return StatusCode::FAILURE; + } + + // HLT JSON object - contains HLT menus + xAOD::TriggerMenuJsonAuxContainer* aux_hlt = new xAOD::TriggerMenuJsonAuxContainer(); + m_menuJSON_hlt = new xAOD::TriggerMenuJsonContainer(); + m_menuJSON_hlt->setStore( aux_hlt ); - // Record the trigger configuration metadata into it: - CHECK( m_metaStore->record( aux, m_metaName + "Aux." ) ); - CHECK( m_metaStore->record( m_tmc, m_metaName ) ); + CHECK( m_metaStore->record( aux_hlt, m_metaNameJSON_hlt + "Aux." ) ); + CHECK( m_metaStore->record( m_menuJSON_hlt, m_metaNameJSON_hlt ) ); + + // L1 JSON object - contains L1 menus + xAOD::TriggerMenuJsonAuxContainer* aux_l1 = new xAOD::TriggerMenuJsonAuxContainer(); + m_menuJSON_l1 = new xAOD::TriggerMenuJsonContainer(); + m_menuJSON_l1->setStore( aux_l1 ); + + CHECK( m_metaStore->record( aux_l1, m_metaNameJSON_l1 + "Aux." ) ); + CHECK( m_metaStore->record( m_menuJSON_l1, m_metaNameJSON_l1 ) ); + + // HLT PS JSON object - contains prescales sets for HLT menus + xAOD::TriggerMenuJsonAuxContainer* aux_hltps = new xAOD::TriggerMenuJsonAuxContainer(); + m_menuJSON_hltps = new xAOD::TriggerMenuJsonContainer(); + m_menuJSON_hltps->setStore( aux_hltps ); + + CHECK( m_metaStore->record( aux_hltps, m_metaNameJSON_hltps + "Aux." ) ); + CHECK( m_metaStore->record( m_menuJSON_hltps, m_metaNameJSON_hltps ) ); + + // L1 PS JSON object - contains prescales sets for L1 menus + xAOD::TriggerMenuJsonAuxContainer* aux_l1ps = new xAOD::TriggerMenuJsonAuxContainer(); + m_menuJSON_l1ps = new xAOD::TriggerMenuJsonContainer(); + m_menuJSON_l1ps->setStore( aux_l1ps ); + + CHECK( m_metaStore->record( aux_l1ps, m_metaNameJSON_l1ps + "Aux." ) ); + CHECK( m_metaStore->record( m_menuJSON_l1ps, m_metaNameJSON_l1ps ) ); + + // Bunchgroup JSON object - contains bungchgroup configuration + // TODO + // xAOD::TriggerMenuJsonAuxContainer* aux_bg = new xAOD::TriggerMenuJsonAuxContainer(); + // m_menuJSON_bg = new xAOD::TriggerMenuJsonContainer(); + // m_menuJSON_bg->setStore( aux_bg ); + + // CHECK( m_metaStore->record( aux_bg, m_metaNameJSON_bg + "Aux." ) ); + // CHECK( m_metaStore->record( m_menuJSON_bg, m_metaNameJSON_bg ) ); + } // Return gracefully: return StatusCode::SUCCESS; @@ -76,61 +140,143 @@ namespace TrigConf { StatusCode xAODMenuWriterMT::execute(const EventContext& ctx) const { - std::unique_ptr<xAOD::TrigConfKeys> keys = std::make_unique<xAOD::TrigConfKeys>( - m_trigConf->masterKey(), - m_trigConf->lvl1PrescaleKey(), - m_trigConf->hltPrescaleKey() ); - - SG::WriteHandle<xAOD::TrigConfKeys> trigConfKeysWrite(m_eventName, ctx); - ATH_CHECK( trigConfKeysWrite.record( std::move(keys) ) ); + std::unique_ptr<xAOD::TrigConfKeys> keys; + if (m_writexAODTriggerMenuJson) { + SG::ReadHandle<TrigConf::HLTMenu> hltMenuHandle( m_HLTMenuKey, ctx ); + SG::ReadCondHandle<TrigConf::L1PrescalesSet> l1PSHandle( m_L1PrescaleSetInputKey, ctx ); + SG::ReadCondHandle<TrigConf::HLTPrescalesSet> hltPSHandle( m_HLTPrescaleSetInputKey, ctx ); + ATH_CHECK( hltMenuHandle.isValid() ); + ATH_CHECK( l1PSHandle.isValid() ); + ATH_CHECK( hltPSHandle.isValid() ); + keys = std::make_unique<xAOD::TrigConfKeys>( + hltMenuHandle->smk(), + l1PSHandle->psk(), + hltPSHandle->psk() ); + } else { // Fall back to R2 TrigConfSvc. Expect this to stop working in the near future (2021+) + keys = std::make_unique<xAOD::TrigConfKeys>( + m_trigConf->masterKey(), + m_trigConf->lvl1PrescaleKey(), + m_trigConf->hltPrescaleKey() ); + } // Create the keys in the "internal format": const TrigKey_t ckeys = - std::make_pair( m_trigConf->masterKey(), - std::make_pair( m_trigConf->lvl1PrescaleKey(), - m_trigConf->hltPrescaleKey() ) ); + std::make_pair( keys->smk(), + std::make_pair( keys->l1psk(), + keys->hltpsk() ) ); + + + SG::WriteHandle<xAOD::TrigConfKeys> trigConfKeysWrite(m_eventName, ctx); + ATH_CHECK( trigConfKeysWrite.record( std::move(keys) ) ); - // The followign code must only run on one event at a time + // The following code must only run on one event at a time std::lock_guard<std::mutex> lock(m_mutex); - // Check if we converted this configuration already: - if( ! m_convertedKeys.insert( ckeys ).second ) { - ATH_MSG_VERBOSE( "Configuration with keys SMK: " + // TODO - Deprecate this in the future. Only keep m_writexAODTriggerMenuJson mode + if (m_writexAODTriggerMenu) { + + // Check if we converted this configuration already: + if( ! m_convertedKeys.insert( ckeys ).second ) { + ATH_MSG_VERBOSE( "Configuration with keys SMK: " + << ckeys.first << ", L1PSK: " << ckeys.second.first + << ", HLTPSK: " << ckeys.second.second + << " already translated" ); + } else { + + // Tell the user what's happening: + ATH_MSG_INFO( "Converting configuration with keys SMK: " << ckeys.first << ", L1PSK: " << ckeys.second.first - << ", HLTPSK: " << ckeys.second.second - << " already translated" ); - return StatusCode::SUCCESS; - } + << ", HLTPSK: " << ckeys.second.second ); + + // Apparently not, so let's make a new object: + xAOD::TriggerMenu* menu = new xAOD::TriggerMenu(); + m_tmc->push_back( menu ); // Now owned by MetaDataStore + + // + // Set its keys: + // + menu->setSMK( ckeys.first ); + menu->setL1psk( ckeys.second.first ); + menu->setHLTpsk( ckeys.second.second ); + + if (m_isL1JSONConfig) { + CHECK( populateL1FromJSON(menu, ctx) ); + } else { + CHECK( populateL1FromTrigConf(menu) ); + } - // Tell the user what's happening: - ATH_MSG_INFO( "Converting configuration with keys SMK: " - << ckeys.first << ", L1PSK: " << ckeys.second.first - << ", HLTPSK: " << ckeys.second.second ); + if (m_isHLTJSONConfig) { + CHECK( populateHLTFromJSON(menu, ctx) ); + } else { + CHECK( populateHLTFromTrigConf(menu) ); + } - // Apparently not, so let's make a new object: - xAOD::TriggerMenu* menu = new xAOD::TriggerMenu(); - m_tmc->push_back( menu ); // Now owned by MetaDataStore + CHECK( populateBunchGroup(menu) ); + } // m_convertedKeys + } // m_writexAODTriggerMenu + + if (m_writexAODTriggerMenuJson) { + + if( ! m_converted_smk.insert( ckeys.first ).second ) { + ATH_MSG_VERBOSE( "Already converted SMK: " << ckeys.first); + } else { + ATH_MSG_DEBUG( "Filling HLT information for SMK:" << ckeys.first ); + SG::ReadHandle<TrigConf::HLTMenu> hltMenuHandle( m_HLTMenuKey, ctx ); + ATH_CHECK( hltMenuHandle.isValid() ); + std::stringstream hltTriggerMenuJson; + hltMenuHandle->printRaw(hltTriggerMenuJson); + xAOD::TriggerMenuJson* hlt = new xAOD::TriggerMenuJson(); + m_menuJSON_hlt->push_back( hlt ); // Now owned by MetaDataStore + hlt->setKey( ckeys.first ); + hlt->setName( hltMenuHandle->name() ); + hlt->setPayload( hltTriggerMenuJson.str() ); + ////////////////////////////////////////////////////////////////////////////// + ATH_MSG_DEBUG( "Filling L1 information for SMK:" << ckeys.first ); + SG::ReadHandle<TrigConf::L1Menu> l1MenuHandle = SG::makeHandle( m_L1MenuKey, ctx ); + ATH_CHECK( l1MenuHandle.isValid() ); + std::stringstream l1TriggerMenuJson; + l1MenuHandle->printRaw(l1TriggerMenuJson); + xAOD::TriggerMenuJson* l1 = new xAOD::TriggerMenuJson(); + m_menuJSON_l1->push_back( l1 ); // Now owned by MetaDataStore + l1->setKey( ckeys.first ); + l1->setName( l1MenuHandle->name() ); + l1->setPayload( l1TriggerMenuJson.str() ); + } - // - // Set its keys: - // - menu->setSMK( m_trigConf->masterKey() ); - menu->setL1psk( m_trigConf->lvl1PrescaleKey() ); - menu->setHLTpsk( m_trigConf->hltPrescaleKey() ); - - if (m_isL1JSONConfig) { - CHECK( populateL1FromJSON(menu, ctx) ); - } else { - CHECK( populateL1FromTrigConf(menu) ); - } + if( ! m_converted_hltpsk.insert( ckeys.second.second ).second ) { + ATH_MSG_VERBOSE( "Already converted HLTPSK: " << ckeys.second.second); + } else { + ATH_MSG_DEBUG( "Filling prescale information for HLTPSK:" << ckeys.second.second ); + SG::ReadCondHandle<TrigConf::HLTPrescalesSet> hltPSHandle( m_HLTPrescaleSetInputKey, ctx ); + ATH_CHECK( hltPSHandle.isValid() ); + std::stringstream hltPSJSON; + hltPSHandle->printRaw(hltPSJSON); + xAOD::TriggerMenuJson* hltps = new xAOD::TriggerMenuJson(); + m_menuJSON_hltps->push_back( hltps ); // Now owned by MetaDataStore + hltps->setKey( ckeys.second.second ); + hltps->setName( hltPSHandle->name() ); + hltps->setPayload( hltPSJSON.str() ); + } - if (m_isHLTJSONConfig) { - CHECK( populateHLTFromJSON(menu, ctx) ); - } else { - CHECK( populateHLTFromTrigConf(menu) ); - } + if( ! m_converted_l1psk.insert( ckeys.second.first ).second ) { + ATH_MSG_VERBOSE( "Already converted LVL1PSK: " << ckeys.second.first); + } else { + ATH_MSG_DEBUG( "Filling prescale information for LVL1PSK:" << ckeys.second.first ); + SG::ReadCondHandle<TrigConf::L1PrescalesSet> l1PSHandle( m_L1PrescaleSetInputKey, ctx ); + ATH_CHECK( l1PSHandle.isValid() ); + std::stringstream l1PSJSON; + l1PSHandle->printRaw(l1PSJSON); + xAOD::TriggerMenuJson* l1ps = new xAOD::TriggerMenuJson(); + m_menuJSON_l1ps->push_back( l1ps ); // Now owned by MetaDataStore + l1ps->setKey( ckeys.second.first ); + l1ps->setName( l1PSHandle->name() ); + l1ps->setPayload( l1PSJSON.str() ); + } - CHECK( populateBunchGroup(menu) ); + // + // TODO: bg + // + } // Return gracefully: return StatusCode::SUCCESS; @@ -146,6 +292,16 @@ namespace TrigConf { const size_t nL1Items = l1MenuHandle->size(); ATH_MSG_DEBUG("Configuring from " << m_L1MenuKey << " with " << nL1Items << " L1 items"); + SG::ReadCondHandle<TrigConf::L1PrescalesSet> l1PSHandle( m_L1PrescaleSetInputKey, ctx ); + ATH_CHECK( l1PSHandle.isValid() ); + const size_t nL1ItemsPS = l1PSHandle->size(); + ATH_MSG_DEBUG("Prescales from " << m_L1PrescaleSetInputKey << " with " << nL1ItemsPS << " L1 items"); + + if (nL1Items != nL1ItemsPS) { + ATH_MSG_ERROR("Inconsistent number of configured L1 items (" << nL1Items << ") and L1 item prescales (" << nL1ItemsPS << ")"); + return StatusCode::FAILURE; + } + std::vector< uint16_t > ctpIds; std::vector< std::string > itemNames; std::vector< float > itemPrescales; @@ -158,7 +314,8 @@ namespace TrigConf { // Extract the information: ctpIds.push_back( l1.ctpId() ); itemNames.push_back( l1.name() ); - itemPrescales.push_back( 1.0 ); // TODO + const TrigConf::L1PrescalesSet::L1Prescale l1ps = l1PSHandle->prescale(l1.name()); + itemPrescales.push_back( l1ps.prescale ); // Some verbose information: ATH_MSG_VERBOSE( " \"" << itemNames.back() << "\" CTP Id = " @@ -184,6 +341,16 @@ namespace TrigConf { const size_t nChains = hltMenuHandle->size(); ATH_MSG_DEBUG("Configuring from " << m_HLTMenuKey << " with " << nChains << " chains"); + SG::ReadCondHandle<TrigConf::HLTPrescalesSet> hltPSHandle( m_HLTPrescaleSetInputKey, ctx ); + ATH_CHECK( hltPSHandle.isValid() ); + const size_t nChainsPS = hltPSHandle->size(); + ATH_MSG_DEBUG("Prescales from " << m_HLTPrescaleSetInputKey << " with " << nChains << " chains"); + + if (nChains != nChainsPS) { + ATH_MSG_ERROR("Inconsistent number of configured HLT chains (" << nChains << ") and HLT chain prescales (" << nChainsPS << ")"); + return StatusCode::FAILURE; + } + std::vector< uint16_t > chainIds; std::vector< std::string > chainNames, chainParentNames; std::vector< float > chainPrescales, chainRerunPrescales, @@ -211,9 +378,10 @@ namespace TrigConf { chainIds.push_back( ch.counter() ); chainNames.push_back( ch.name() ); chainParentNames.push_back( ch.l1item() ); - chainPrescales.push_back( 1.0 ); // TODO - chainRerunPrescales.push_back( -1.0 ); // TODO - chainPassthroughPrescales.push_back( 0.0 ); // Unused in Run3 + const TrigConf::HLTPrescalesSet::HLTPrescale hltps = hltPSHandle->prescale(ch.name()); + chainPrescales.push_back( hltps.prescale ); + chainRerunPrescales.push_back( -1.0 ); // Unused in Run3 + chainPassthroughPrescales.push_back( -1.0 ); // Unused in Run3 std::vector<uint32_t> counters; std::vector<int> logics; diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h index f5d67d27da7144af125bf227083c51197e88dc49..da884a40524862b1c216330740b4d3e273d6c97c 100644 --- a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h +++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h @@ -24,9 +24,12 @@ extern "C" { #include "TrigConfInterfaces/ITrigConfigSvc.h" #include "TrigConfData/HLTMenu.h" #include "TrigConfData/L1Menu.h" +#include "TrigConfData/HLTPrescalesSet.h" +#include "TrigConfData/L1PrescalesSet.h" // EDM include(s): #include "xAODTrigger/TriggerMenuContainer.h" +#include "xAODTrigger/TriggerMenuJsonContainer.h" #include "xAODTrigger/TrigConfKeys.h" namespace TrigConf { @@ -66,14 +69,36 @@ namespace TrigConf { SG::WriteHandleKey<xAOD::TrigConfKeys> m_eventName {this, "EventObjectName", "TrigConfKeys", "StoreGate key for the event object"}; - SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey {this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", + SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey {this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu key, for use if IsJSONConfig=True"}; - SG::ReadHandleKey<TrigConf::L1Menu> m_L1MenuKey {this, "L1TriggerMenu", "DetectorStore+L1TriggerMenu", + SG::ReadHandleKey<TrigConf::L1Menu> m_L1MenuKey {this, "L1TriggerMenu", "DetectorStore+L1TriggerMenu", "L1 Menu key, for use if IsJSONConfig=True"}; + SG::ReadCondHandleKey<TrigConf::HLTPrescalesSet> m_HLTPrescaleSetInputKey{this, "HLTPrescales", "HLTPrescales", + "HLT prescales set condition handle"}; + + SG::ReadCondHandleKey<TrigConf::L1PrescalesSet> m_L1PrescaleSetInputKey{this, "L1Prescales", "L1Prescales", + "L1 prescales set condition handle"}; + Gaudi::Property< std::string > m_metaName {this, "MetaObjectName", "TriggerMenu", - "StoreGate key for the configuration object"}; + "StoreGate key for the xAOD::TriggerMenu configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_hlt {this, "JSONMetaObjectNameHLT", "TriggerMenuJson_HLT", + "StoreGate key for the xAOD::TriggerMenuJson HLT configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_l1 {this, "JSONMetaObjectNameL1", "TriggerMenuJson_L1", + "StoreGate key for the xAOD::TriggerMenuJson L1 configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_hltps {this, "JSONMetaObjectNameHLTPS", "TriggerMenuJson_HLTPS", + "StoreGate key for the xAOD::TriggerMenuJson HLT prescales configuration object"}; + + Gaudi::Property< std::string > m_metaNameJSON_l1ps {this, "JSONMetaObjectNameL1PS", "TriggerMenuJson_L1PS", + "StoreGate key for the xAOD::TriggerMenuJson L1 prescales configuration object"}; + + // TODO + // Gaudi::Property< std::string > m_metaNameJSON_bg {this, "JSONMetaObjectNameBunchgroup", "TriggerMenuJson_BG", + // "StoreGate key for the xAOD::TriggerMenuJson BunchGroup configuration object"}; Gaudi::Property< bool > m_isL1JSONConfig {this, "IsL1JSONConfig", true, "If converting from a L1 JSON menu (Run3) or from the TrigConfigSvc (Runs 1, 2)"}; @@ -81,6 +106,12 @@ namespace TrigConf { Gaudi::Property< bool > m_isHLTJSONConfig {this, "IsHLTJSONConfig", true, "If converting from a HLT JSON menu (Run3) or from the TrigConfigSvc (Runs 1, 2)"}; + Gaudi::Property< bool > m_writexAODTriggerMenu {this, "WritexAODTriggerMenu", true, + "Flag to control the writing of xAOD::TriggerMenu metadata into the output file. This is the R2 persistent format."}; + + Gaudi::Property< bool > m_writexAODTriggerMenuJson {this, "WritexAODTriggerMenuJson", true, + "Flag to control the writing of xAOD::TriggerMenuJson metadata into the output file. This is the R3 persistent format."}; + ServiceHandle< TrigConf::ITrigConfigSvc > m_trigConf {this, "TrigConfigSvc", "TrigConfigSvc", "The TrigConfigSvc"}; @@ -100,12 +131,25 @@ namespace TrigConf { /// Trigger configuration key type (used just internally) typedef std::pair< uint32_t, std::pair< uint32_t, uint32_t > > TrigKey_t; - /// The configuration object that we are writing + /// The configuration object that we are writing when WritexAODTriggerMenu mutable xAOD::TriggerMenuContainer* m_tmc; - /// Trigger configuration keys that are already converted + // The configuration objects that we are writing when WritexAODTriggerMenuJson + mutable xAOD::TriggerMenuJsonContainer* m_menuJSON_hlt; + mutable xAOD::TriggerMenuJsonContainer* m_menuJSON_l1; + mutable xAOD::TriggerMenuJsonContainer* m_menuJSON_hltps; + mutable xAOD::TriggerMenuJsonContainer* m_menuJSON_l1ps; + // mutable xAOD::TriggerMenuJsonContainer* m_menuJSON_bg; + + /// Trigger configuration keys that are already converted when WritexAODTriggerMenu is true mutable std::set< TrigKey_t > m_convertedKeys; + /// Trigger configuration keys that are already converted when WritexAODTriggerMenuJson is true + mutable std::set< uint32_t > m_converted_smk; + mutable std::set< uint32_t > m_converted_hltpsk; + mutable std::set< uint32_t > m_converted_l1psk; + // mutable std::set< uint32_t > m_converted_bg; + /// The mutex to prevent us from writing more than one configuration at a time mutable std::mutex m_mutex; diff --git a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx index 055409940bbcbb8afdfcb8e4ecea028797b88064..f72c0cca47089e06b23480234aac92c62f68fecc 100644 --- a/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx +++ b/Trigger/TrigMonitoring/TrigEgammaMonitoring/src/TrigEgammaMonitorTagAndProbeAlgorithm.cxx @@ -18,7 +18,6 @@ **********************************************************************/ #include "TrigEgammaMonitorTagAndProbeAlgorithm.h" -#include "TrigConfxAOD/xAODConfigTool.h" #include "GaudiKernel/SystemOfUnits.h" #include "string" #include <algorithm> @@ -28,7 +27,6 @@ //********************************************************************** using namespace Trig; -using namespace TrigConf; using namespace xAOD; using namespace boost; diff --git a/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py b/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py index ada3b3b844a874657516ddafba1dafb5c24409f3..712be1df152c19c3328042c7210443923c7e4d15 100644 --- a/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py +++ b/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py @@ -208,7 +208,6 @@ def L1DecoderCfg(flags, seqName = None): acc.merge( TrigConfigSvcCfg( flags ) ) acc.merge( HLTPrescaleCondAlgCfg( flags ) ) - Configurable.configurableRun3Behavior -= 1 return acc diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py index f0e7b9ccf2c3bdf21c3cf8dce1b3d5788b5d678b..b58e7551db0858505e0fb4b78c210231570ba1bc 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py @@ -430,6 +430,11 @@ def triggerPOOLOutputCfg(flags, edmSet): menuwriter.IsL1JSONConfig = True acc.addEventAlgo( menuwriter ) + # Schedule the insertion of L1 prescales into the conditions store + # Required for metadata production + from TrigConfigSvc.TrigConfigSvcCfg import L1PrescaleCondAlgCfg + acc.merge( L1PrescaleCondAlgCfg( flags ) ) + # Add metadata to the output stream streamAlg.MetadataItemList += [ "xAOD::TriggerMenuContainer#*", "xAOD::TriggerMenuAuxContainer#*" ] diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py index 95a1eebefd417fd66e0ec1dc47595a7d7af43d7a..8616b857d9d99fe92db46b718e4d396e1ef8134b 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigGetter.py @@ -172,7 +172,7 @@ class TriggerConfigGetter(Configured): self.l1Folders = TriggerFlags.dataTakingConditions()=='FullTrigger' or TriggerFlags.dataTakingConditions()=='Lvl1Only' self.hltFolders = TriggerFlags.dataTakingConditions()=='FullTrigger' or TriggerFlags.dataTakingConditions()=='HltOnly' self.isRun1Data = False - self.hasxAODMeta = ("metadata_items" in metadata and any(('TriggerMenu' in key) for key in metadata["metadata_items"].keys())) + self.hasxAODMeta = ("metadata_items" in metadata and any(('TriggerMenu' or 'MenuJSON' in key) for key in metadata["metadata_items"].keys())) if globalflags.DataSource()=='data': from RecExConfig.AutoConfiguration import GetRunNumber runNumber = GetRunNumber() @@ -437,6 +437,8 @@ class TriggerConfigGetter(Configured): # Add the algorithm creating the trigger configuration metadata for # the output: try: + writeTriggerMenu = True + writeMenuJSON = False if TriggerFlags.EDMDecodingVersion() <= 2: from TrigConfxAOD.TrigConfxAODConf import TrigConf__xAODMenuWriter topAlgs += TrigConf__xAODMenuWriter( OverwriteEventObj = True ) @@ -445,15 +447,36 @@ class TriggerConfigGetter(Configured): menuwriter = TrigConf__xAODMenuWriterMT() menuwriter.IsHLTJSONConfig = True menuwriter.IsL1JSONConfig = True - topAlgs += menuwriter + menuwriter.WritexAODTriggerMenu = True # This should be removed in the future + menuwriter.WritexAODMenuJSON = True + writeTriggerMenu = menuwriter.WritexAODTriggerMenu + writeMenuJSON = menuwriter.WritexAODMenuJSON - # The metadata objects to add to the output: - metadataItems = [ "xAOD::TriggerMenuContainer#TriggerMenu", - "xAOD::TriggerMenuAuxContainer#TriggerMenuAux." ] + topAlgs += menuwriter # Set up the metadata for the output ESD and AOD: from RecExConfig.ObjKeyStore import objKeyStore - objKeyStore.addManyTypesMetaData( metadataItems ) + + # The metadata objects to add to the output: + if writeTriggerMenu: + metadataItems = [ "xAOD::TriggerMenuContainer#TriggerMenu", + "xAOD::TriggerMenuAuxContainer#TriggerMenuAux." ] + objKeyStore.addManyTypesMetaData( metadataItems ) + + if writeMenuJSON: + metadataItems = [ "xAOD::TriggerMenuJSONContainer#MenuJSON_HLT", + "xAOD::TriggerMenuJSONAuxContainer#MenuJSON_HLTAux.", + "xAOD::TriggerMenuJSONContainer#MenuJSON_L1", + "xAOD::TriggerMenuJSONAuxContainer#MenuJSON_L1Aux.", + "xAOD::TriggerMenuJSONContainer#MenuJSON_HLTPS", + "xAOD::TriggerMenuJSONAuxContainer#MenuJSON_HLTPSAux.", + "xAOD::TriggerMenuJSONContainer#MenuJSON_L1PS", + "xAOD::TriggerMenuJSONAuxContainer#MenuJSON_L1PSAux.", + # "xAOD::TriggerMenuJSONContainer#MenuJSON_BG", // TODO + # "xAOD::TriggerMenuJSONAuxContainer#MenuJSON_BGAux.", // TODO + ] + objKeyStore.addManyTypesMetaData( metadataItems ) + except ImportError: # don't want to branch in rel 18 pass diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py index 65e1efbcaf6772afc9e23a033b0b8062b0e4a89f..56efb6bc4cf9669f493b93fb5a04c2ad7b2244c8 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone_newJO.py @@ -88,6 +88,10 @@ acc.merge( triggerRunCfg( flags, seqName = "AthMasterSeq", menu=generateHLTMenu from RegionSelector.RegSelConfig import regSelCfg acc.merge( regSelCfg( flags ) ) +# The L1 presacles do not get created in the avoce menu setup +from TrigConfigSvc.TrigConfigSvcCfg import createL1PrescalesFileFromMenu +createL1PrescalesFileFromMenu(flags) + acc.getEventAlgo( "TrigSignatureMoniMT" ).OutputLevel=DEBUG acc.getEventAlgo( "L1Decoder" ).ctpUnpacker.UseTBPBits=True # test setup