From db3941f85fce127caefe50ea1f0aa625ec03c138 Mon Sep 17 00:00:00 2001 From: Frank Berghaus <frank.berghaus@cern.ch> Date: Wed, 25 Nov 2020 15:04:05 +0000 Subject: [PATCH] Clean up and move content There should be no need to expose the header of the FileMetaDataTool to other packages, it can be treated as a component and called through its interface. Remove some unneeded headers. Enable checking for thread safety. --- .../AthenaKernel/AthenaKernel/IMetaDataSvc.h | 9 + .../python/CreateOutputStreams.py | 19 +- .../python/MultipleStreamManager.py | 4 - .../python/OutputStreamConfig.py | 42 +- .../xAODMetaData/Root/FileMetaData_v1.cxx | 4 +- .../xAODMetaData/FileMetaDataAuxInfo.h | 6 + .../xAODMetaData/versions/FileMetaData_v1.h | 4 +- .../xAODMetaDataCnv/ATLAS_CHECK_THREAD_SAFETY | 1 + Event/xAOD/xAODMetaDataCnv/CMakeLists.txt | 25 +- .../xAODMetaDataCnv/Root/FileMetaDataTool.cxx | 140 ++--- .../python/FileMetaDataConfig.py | 62 +++ .../python/TestWriteFileMetaData.py | 73 +++ .../FileMetaDataCreatorTool_jobOptions.py | 94 ++-- .../src/FileMetaDataCreatorTool.cxx | 494 +++++++++++------- .../src/FileMetaDataCreatorTool.h | 179 +++++-- .../src/FileMetaDataMarkUpTool.cxx | 122 ----- .../src/FileMetaDataMarkUpTool.h | 88 ---- .../components/xAODMetaDataCnv_entries.cxx | 7 +- .../xAODMetaDataCnv/FileMetaDataTool.h | 110 ++-- .../xAODMetaDataCnv/xAODMetaDataCnvAthena.h | 16 - Projects/AthGeneration/package_filters.txt | 3 + Projects/AthSimulation/package_filters.txt | 3 + .../share/RecExCommon_topOptions.py | 5 + 23 files changed, 840 insertions(+), 670 deletions(-) create mode 100644 Event/xAOD/xAODMetaDataCnv/ATLAS_CHECK_THREAD_SAFETY create mode 100644 Event/xAOD/xAODMetaDataCnv/python/FileMetaDataConfig.py create mode 100644 Event/xAOD/xAODMetaDataCnv/python/TestWriteFileMetaData.py delete mode 100644 Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.cxx delete mode 100644 Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.h delete mode 100644 Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/xAODMetaDataCnvAthena.h diff --git a/Control/AthenaKernel/AthenaKernel/IMetaDataSvc.h b/Control/AthenaKernel/AthenaKernel/IMetaDataSvc.h index 1c84d4cd5cb9..e9d41f24322e 100644 --- a/Control/AthenaKernel/AthenaKernel/IMetaDataSvc.h +++ b/Control/AthenaKernel/AthenaKernel/IMetaDataSvc.h @@ -49,6 +49,10 @@ public: // Non-static members template <typename T, typename TKEY> StatusCode remove(const TKEY& key, bool ignoreIfAbsent=false); + /// Check if object is already is already in store + template <typename T, typename TKEY> + bool contains(const TKEY& key); + /// The output MetaData Store virtual StoreGateSvc* outputDataStore() const = 0; @@ -142,4 +146,9 @@ StatusCode IMetaDataSvc::remove(const TKEY& key, bool ignoreIfAbsent) return ignoreIfAbsent? StatusCode::SUCCESS : StatusCode::FAILURE; } +template <typename T, typename TKEY> +bool IMetaDataSvc::contains(const TKEY& key) { + return outputDataStore()->contains< MetaCont<T> >(key); +} + #endif diff --git a/Database/AthenaPOOL/OutputStreamAthenaPool/python/CreateOutputStreams.py b/Database/AthenaPOOL/OutputStreamAthenaPool/python/CreateOutputStreams.py index cb3d49ae862f..261097117ea6 100644 --- a/Database/AthenaPOOL/OutputStreamAthenaPool/python/CreateOutputStreams.py +++ b/Database/AthenaPOOL/OutputStreamAthenaPool/python/CreateOutputStreams.py @@ -81,7 +81,24 @@ def createOutputStream( streamName, fileName = "", asAlg = False, noTag = False, Key=event_format_key, ) outputStream.MetadataItemList += ["xAOD::EventFormat#{}".format(event_format_key)] - outputStream.HelperTools = [ streamInfoTool, event_format_tool] + + # Create a new xAOD::FileMetaData object + file_metadata_key = "FileMetaData" + file_metadata_creator_tool = CfgMgr.xAODMaker__FileMetaDataCreatorTool( + "FileMetaDataCreatorTool", + OutputKey=file_metadata_key, + StreamName=streamName, + ) + outputStream.MetadataItemList += [ + "xAOD::FileMetaData#{}".format(file_metadata_key), + "xAOD::FileMetaDataAuxInfo#{}Aux.".format(file_metadata_key), + ] + + outputStream.HelperTools = [ + streamInfoTool, + event_format_tool, + file_metadata_creator_tool, + ] # Support for MT thinning. diff --git a/Database/AthenaPOOL/OutputStreamAthenaPool/python/MultipleStreamManager.py b/Database/AthenaPOOL/OutputStreamAthenaPool/python/MultipleStreamManager.py index a0bb9d68b64a..f9e6d51227f4 100644 --- a/Database/AthenaPOOL/OutputStreamAthenaPool/python/MultipleStreamManager.py +++ b/Database/AthenaPOOL/OutputStreamAthenaPool/python/MultipleStreamManager.py @@ -559,10 +559,6 @@ class MultipleStreamManager: from AthenaCommon.AppMgr import theApp svcMgr = theApp.serviceMgr() - from AthenaCommon import CfgMgr - streamMarkUpTool = CfgMgr.xAODMaker__FileMetaDataMarkUpTool( StreamName + "_FileMetaDataMarkUpTool" ) - streamMarkUpTool.Key = StreamName - theStream.Stream.HelperTools += [ streamMarkUpTool ] theStream.Stream.WritingTool.SubLevelBranchName = "<key>" svcMgr.AthenaPoolCnvSvc.PoolAttributes += [ "DatabaseName = '" + FileName + "'; COMPRESSION_LEVEL = '5'" ] svcMgr.AthenaPoolCnvSvc.PoolAttributes += [ "DatabaseName = '" + FileName + "'; ContainerName = 'TTree=CollectionTree'; TREE_AUTO_FLUSH = '-20000000'" ] diff --git a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py index 3e8818964214..631954562ba6 100644 --- a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py +++ b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py @@ -11,12 +11,12 @@ def OutputStreamCfg(configFlags, streamName, ItemList=[], MetadataItemList=[], AthenaOutputStreamTool=CompFactory.AthenaOutputStreamTool StoreGateSvc=CompFactory.StoreGateSvc + msg = logging.getLogger('OutputStreamCfg') flagName="Output.%sFileName" % streamName if configFlags.hasFlag(flagName): fileName=configFlags._get(flagName) else: fileName="my%s.pool.root" % streamName - msg = logging.getLogger('OutputStreamCfg') msg.info("No file name predefined for stream %s. Using %s", streamName, fileName) if fileName in configFlags.Input.Files: @@ -54,16 +54,6 @@ def OutputStreamCfg(configFlags, streamName, ItemList=[], MetadataItemList=[], "IOVMetaDataContainer#*", ] - # Event Tag - if not disableEventTag: - key = "SimpleTag" - outputStream.WritingTool.AttributeListKey=key - # build eventinfo attribute list - EventInfoAttListTool, EventInfoTagBuilder=CompFactory.getComps("EventInfoAttListTool","EventInfoTagBuilder",) - tagBuilder = EventInfoTagBuilder(AttributeList=key, - Tool=EventInfoAttListTool()) - result.addEventAlgo(tagBuilder) - # Make EventFormat object event_format_key = 'EventFormat{}'.format(streamName) event_format_tool = CompFactory.xAODMaker.EventFormatStreamHelperTool( @@ -71,17 +61,39 @@ def OutputStreamCfg(configFlags, streamName, ItemList=[], MetadataItemList=[], Key=event_format_key, ) outputStream.HelperTools.append(event_format_tool) + msg.info("Creating event format for this stream") # Simplifies naming outputStream.MetadataItemList.append( "xAOD::EventFormat#{}".format(event_format_key) ) + + # setup FileMetaData + file_metadata_key = "FileMetaData" + outputStream.HelperTools.append( + CompFactory.xAODMaker.FileMetaDataCreatorTool( + name='{}_FileMetaDataCreatorTool'.format(streamName), + OutputKey=file_metadata_key, + StreamName=streamName, + ) + ) + outputStream.MetadataItemList += [ + "xAOD::FileMetaData#{}".format(file_metadata_key), + "xAOD::FileMetaDataAuxInfo#{}Aux.".format(file_metadata_key), + ] + + # Event Tag + if not disableEventTag: + key = "SimpleTag" + outputStream.WritingTool.AttributeListKey=key + # build eventinfo attribute list + EventInfoAttListTool, EventInfoTagBuilder=CompFactory.getComps("EventInfoAttListTool","EventInfoTagBuilder",) + tagBuilder = EventInfoTagBuilder(AttributeList=key, + Tool=EventInfoAttListTool()) + result.addEventAlgo(tagBuilder) + # For xAOD output if "xAOD" in streamName: - xAODMaker__FileMetaDataMarkUpTool=CompFactory.xAODMaker.FileMetaDataMarkUpTool - streamMarkUpTool = xAODMaker__FileMetaDataMarkUpTool( streamName + "_FileMetaDataMarkUpTool" ) - streamMarkUpTool.Key = streamName - outputStream.HelperTools += [ streamMarkUpTool ] outputStream.WritingTool.SubLevelBranchName = "<key>" AthenaPoolCnvSvc=CompFactory.AthenaPoolCnvSvc diff --git a/Event/xAOD/xAODMetaData/Root/FileMetaData_v1.cxx b/Event/xAOD/xAODMetaData/Root/FileMetaData_v1.cxx index bd0ec69a9318..efc4dd3e0b42 100644 --- a/Event/xAOD/xAODMetaData/Root/FileMetaData_v1.cxx +++ b/Event/xAOD/xAODMetaData/Root/FileMetaData_v1.cxx @@ -25,7 +25,7 @@ namespace xAOD { } - bool FileMetaData_v1::operator==( const FileMetaData_v1& rhs ) { + bool FileMetaData_v1::operator==( const FileMetaData_v1& rhs ) const { // Get the variable types from both objects: const SG::auxid_set_t& auxids1 = this->getAuxIDs(); @@ -161,7 +161,7 @@ namespace xAOD { return true; } - bool FileMetaData_v1::operator!=( const FileMetaData_v1& rhs ) { + bool FileMetaData_v1::operator!=( const FileMetaData_v1& rhs ) const { return !( this->operator==( rhs ) ); } diff --git a/Event/xAOD/xAODMetaData/xAODMetaData/FileMetaDataAuxInfo.h b/Event/xAOD/xAODMetaData/xAODMetaData/FileMetaDataAuxInfo.h index 0df7b0038cc4..49d1b0e871f8 100644 --- a/Event/xAOD/xAODMetaData/xAODMetaData/FileMetaDataAuxInfo.h +++ b/Event/xAOD/xAODMetaData/xAODMetaData/FileMetaDataAuxInfo.h @@ -19,5 +19,11 @@ namespace xAOD { // Declare a CLID for the type: #include "xAODCore/CLASS_DEF.h" CLASS_DEF( xAOD::FileMetaDataAuxInfo, 73252552, 1 ) +#ifndef XAOD_STANDALONE +#include "AthenaKernel/MetaCont.h" +CLASS_DEF( MetaCont<xAOD::FileMetaDataAuxInfo> , 233059795, 1 ) +#include "xAODCore/BaseInfo.h" +SG_BASE( MetaCont<xAOD::FileMetaDataAuxInfo>, MetaContBase ); +#endif // not XAOD_STANDALONE #endif // XAODMETADATA_FILEMETADATAAUXINFO_H diff --git a/Event/xAOD/xAODMetaData/xAODMetaData/versions/FileMetaData_v1.h b/Event/xAOD/xAODMetaData/xAODMetaData/versions/FileMetaData_v1.h index 00e2bbfa1a85..19f0fb56072a 100644 --- a/Event/xAOD/xAODMetaData/xAODMetaData/versions/FileMetaData_v1.h +++ b/Event/xAOD/xAODMetaData/xAODMetaData/versions/FileMetaData_v1.h @@ -38,9 +38,9 @@ namespace xAOD { /// @{ /// Operator testing the equality of two objects - bool operator==( const FileMetaData_v1& rhs ); + bool operator==( const FileMetaData_v1& rhs ) const; /// Operator testing the inequality of two objects - bool operator!=( const FileMetaData_v1& rhs ); + bool operator!=( const FileMetaData_v1& rhs ) const; /// @} diff --git a/Event/xAOD/xAODMetaDataCnv/ATLAS_CHECK_THREAD_SAFETY b/Event/xAOD/xAODMetaDataCnv/ATLAS_CHECK_THREAD_SAFETY new file mode 100644 index 000000000000..0159809cfdda --- /dev/null +++ b/Event/xAOD/xAODMetaDataCnv/ATLAS_CHECK_THREAD_SAFETY @@ -0,0 +1 @@ +Event/xAOD/xAODMetaDataCnv diff --git a/Event/xAOD/xAODMetaDataCnv/CMakeLists.txt b/Event/xAOD/xAODMetaDataCnv/CMakeLists.txt index 101270ff9e4d..8e83703a2281 100644 --- a/Event/xAOD/xAODMetaDataCnv/CMakeLists.txt +++ b/Event/xAOD/xAODMetaDataCnv/CMakeLists.txt @@ -9,24 +9,39 @@ if( XAOD_STANDALONE ) # The main library is an installed one in this case: atlas_add_library( xAODMetaDataCnv xAODMetaDataCnv/*.h Root/*.cxx - PUBLIC_HEADERS xAODMetaDataCnv - LINK_LIBRARIES AsgTools xAODMetaData ) + PUBLIC_HEADERS + xAODMetaDataCnv + LINK_LIBRARIES + AsgTools + xAODMetaData ) # Plus we also build a dictionary: atlas_add_dictionary( xAODMetaDataCnvDict xAODMetaDataCnv/xAODMetaDataCnvDict.h xAODMetaDataCnv/selection.xml - LINK_LIBRARIES xAODMetaDataCnv ) + LINK_LIBRARIES + xAODMetaDataCnv ) else() # The main library is a component one in this case: atlas_add_component( xAODMetaDataCnv xAODMetaDataCnv/*.h src/*.cxx Root/*.cxx src/components/*.cxx - LINK_LIBRARIES AsgTools xAODMetaData GaudiKernel AthenaKernel - AthenaPoolUtilities EventInfo ) + LINK_LIBRARIES + AsgTools + xAODMetaData + AthenaKernel + AthenaPoolUtilities + xAODEventInfo + PersistentDataModel + IOVDbDataModel ) + + atlas_add_test( WriteFileMetaData + SCRIPT python -m "xAODMetaDataCnv.TestWriteFileMetaData" ) + endif() # Install files from the package: atlas_install_joboptions( share/*.py ) +atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) diff --git a/Event/xAOD/xAODMetaDataCnv/Root/FileMetaDataTool.cxx b/Event/xAOD/xAODMetaDataCnv/Root/FileMetaDataTool.cxx index 352fa3ff7aa0..6dc6055204f3 100644 --- a/Event/xAOD/xAODMetaDataCnv/Root/FileMetaDataTool.cxx +++ b/Event/xAOD/xAODMetaDataCnv/Root/FileMetaDataTool.cxx @@ -5,16 +5,24 @@ // Local include(s): #include "xAODMetaDataCnv/FileMetaDataTool.h" +// standard library includes +#include <memory> +#include <utility> + +// EDM include(s): +#include "xAODMetaData/FileMetaData.h" +#include "xAODMetaData/FileMetaDataAuxInfo.h" + + namespace xAODMaker { FileMetaDataTool::FileMetaDataTool(const std::string& name) - : asg::AsgMetadataTool(name) - , m_md() - , m_mdAux() - , m_beginFileIncidentSeen(false) { - declareProperty("InputKey", m_inputKey = "FileMetaData"); - declareProperty("OutputKey", m_outputKey = "FileMetaData"); + : asg::AsgMetadataTool(name) { + declareProperty("InputKey", m_inputKey = "FileMetaData", + "Key of xAOD::FileMetaData object in input"); + declareProperty("OutputKey", m_outputKey = "FileMetaData", + "Key of xAOD::FileMetaData in MetaDataStore"); #ifndef XAOD_STANDALONE declareInterface< ::IMetaDataTool >(this); #endif // XAOD_STANDALONE @@ -22,20 +30,27 @@ FileMetaDataTool::FileMetaDataTool(const std::string& name) StatusCode FileMetaDataTool::initialize() { - // Greet the user: - ATH_MSG_DEBUG("Initialising xAODMaker::FileMetaDataTool"); - ATH_MSG_DEBUG(" InputKey = " << m_inputKey); - ATH_MSG_DEBUG(" OutputKey = " << m_outputKey); +#ifndef XAOD_STANDALONE + ASG_CHECK(m_metaDataSvc.retrieve()); +#endif // XAOD_STANDALONE - // Reset the member variable(s): - m_md.reset(); - m_mdAux.reset(); - m_beginFileIncidentSeen = false; + // Return gracefully: + return StatusCode::SUCCESS; + } +#ifndef XAOD_STANDALONE +StatusCode + FileMetaDataTool::endInputFile(const SG::SourceID&) { // Return gracefully: return StatusCode::SUCCESS; } +StatusCode + FileMetaDataTool::beginInputFile(const SG::SourceID&) { + return beginInputFile(); + } +#endif // XAOD_STANDALONE + StatusCode FileMetaDataTool::endInputFile() { // Return gracefully: @@ -44,49 +59,67 @@ StatusCode StatusCode FileMetaDataTool::beginInputFile() { - // Whatever happens, we've seen the incident: - m_beginFileIncidentSeen = true; + // Previous input file has been processed + std::lock_guard lock(m_toolMutex); - // If the input file doesn't have any file-level metadata, then - // finish right away: + // Quit gracefully if there is nothing to do if (!inputMetaStore()->contains< xAOD::FileMetaData >(m_inputKey)) { + ATH_MSG_INFO("No xAOD::FileMetaData in the input file"); return StatusCode::SUCCESS; } - // Retrieve the input object: - const xAOD::FileMetaData* input = 0; - ATH_CHECK(inputMetaStore()->retrieve(input, m_inputKey)); + // Get the FileMetaData object from the input file + const xAOD::FileMetaData * input = nullptr; + ASG_CHECK(inputMetaStore()->retrieve(input, m_inputKey)); - // Create the output objects if they don't exist yet: - if ((!m_md.get()) && (!m_mdAux.get())) { - ATH_MSG_DEBUG("Creating output objects"); - m_md.reset(new xAOD::FileMetaData()); - m_mdAux.reset(new xAOD::FileMetaDataAuxInfo()); - m_md->setStore(m_mdAux.get()); + // Emit a warning if the FileMetaData from previous files does not + // match that of the new input file +#ifdef XAOD_STANDALONE + if (outputMetaStore()->contains< xAOD::FileMetaData >(m_outputKey)) { + xAOD::FileMetaData * output = nullptr; + ASG_CHECK( + outputMetaStore()->retrieve(output, m_outputKey)); +#else + if (m_metaDataSvc->contains< xAOD::FileMetaData >(m_outputKey)) { + auto output = m_metaDataSvc->tryConstRetrieve< xAOD::FileMetaData >(m_outputKey); + if (!output) return StatusCode::FAILURE; +#endif // XAOD_STANDALONE - // Copy the payload of the input object: - *(m_md.get()) = *input; - } + if (*input != *output) + ATH_MSG_WARNING("Inconsistent input file MetaData"); + + return StatusCode::SUCCESS; - // Make sure that the objects are compatible: - if (*(m_md.get()) != *input) { - ATH_MSG_ERROR("Processing input files with differing conditions"); - ATH_MSG_ERROR("Consistent xAOD::FileMetaData can't be provided for " - "the output"); - return StatusCode::FAILURE; } - // Return gracefully: - return StatusCode::SUCCESS; - } + ATH_MSG_DEBUG("Creating output objects"); + auto output = std::make_unique< xAOD::FileMetaData >(); + auto outputAux = std::make_unique< xAOD::FileMetaDataAuxInfo >(); + output->setStore(outputAux.get()); -StatusCode - FileMetaDataTool::beginEvent() { - // In case we missed the BeginInputFile incident for the first input file, - // make sure that we still run the appropriate function. - if (!m_beginFileIncidentSeen) { - ATH_CHECK(beginInputFile()); - } + // Copy input object + *output = *input; + + +#ifdef XAOD_STANDALONE + ASG_CHECK( + outputMetaStore()->record< xAOD::FileMetaData >( + std::move(output), m_outputKey)); + + ASG_CHECK( + outputMetaStore()->record< xAOD::FileMetaDataAuxInfo >( + std::move(outputAux), m_outputKey + "Aux.")); +#else + ASG_CHECK( + m_metaDataSvc->record< xAOD::FileMetaData >( + std::move(output), m_outputKey)); + + ASG_CHECK( + m_metaDataSvc->record< xAOD::FileMetaDataAuxInfo >( + std::move(outputAux), m_outputKey + "Aux.")); +#endif // XAOD_STANDALONE + + ATH_MSG_INFO("Copied xAOD::FileMetaData to MetaDataStore"); // Return gracefully: return StatusCode::SUCCESS; @@ -94,22 +127,7 @@ StatusCode StatusCode FileMetaDataTool::metaDataStop() { - // Don't be offended if the metadata already exists in the output: - if (outputMetaStore()->contains< xAOD::FileMetaData >(m_outputKey)) { - ATH_MSG_DEBUG("xAOD::FileMetaData already in the output"); - return StatusCode::SUCCESS; - } - - // Record the metadata, if any was found on the input: - if (m_md.get() && m_mdAux.get()) { - ATH_MSG_DEBUG("Recoding file level metadata"); - ATH_CHECK(outputMetaStore()->record(m_md.release(), m_outputKey)); - ATH_CHECK(outputMetaStore()->record(m_mdAux.release(), - m_outputKey + "Aux.")); - } - // Return gracefully: return StatusCode::SUCCESS; } - } // namespace xAODMaker diff --git a/Event/xAOD/xAODMetaDataCnv/python/FileMetaDataConfig.py b/Event/xAOD/xAODMetaDataCnv/python/FileMetaDataConfig.py new file mode 100644 index 000000000000..89aba61c3560 --- /dev/null +++ b/Event/xAOD/xAODMetaDataCnv/python/FileMetaDataConfig.py @@ -0,0 +1,62 @@ +# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +"""Configure jobs to propogate and/or create xAOD::FileMetaData + +Configure the FileMetaDataTool to propogate FileMetaData into the MetaDataStore +if it exists in the input. In addition configure the FileMetaDataCreatorTool to +create xAOD::FileMetaData from the output stream. The object created for the +output stream is written to the output file. + + Typical usage example + + from xAODFileMetaDataCnv import FileMetaDataConfig + ca = ComponentAccumulator() + ca.merge( + FileMetaDataConfig.FileMetaDataCfg( + flags=ConfigFlags, + stream=outputStreamObject, + ) + ) +""" +from AthenaConfiguration import ComponentFactory, ComponentAccumulator +from AthenaCommon import Logging +from AthenaServices import MetaDataSvcConfig + + +def FileMetaDataCfg(flags, stream, streamName=None, key="FileMetaData"): + """Add tools creating and propogating xAOD::FileMetaData""" + if not streamName: + streamName = stream.name + result = ComponentAccumulator.ComponentAccumulator() + components = ComponentFactory.CompFactory + + # attach the FileMetaData creator to the output stream + creator = components.xAODMaker.FileMetaDataCreatorTool( + '{}_FileMetaDataCreatorTool'.format(streamName), + OutputKey=key, + StreamName=streamName, + ) + stream.HelperTools.append(creator) + stream.MetadataItemList += [ + "xAOD::FileMetaData#{}".format(key), + "xAOD::FileMetaDataAuxInfo#{}Aux.".format(key), + ] + + # Set up the tool propogating the FileMetaData + result.merge( + MetaDataSvcConfig.MetaDataSvcCfg( + flags, + ["xAODMaker::FileMetaDataTool"] + ) + ) + + return result + + +def main(): + """Run a job writing a file with FileMetaData""" + msg = Logging.logging.getLogger("FileMetaDataConfig") + msg.info("FileMetaData config OK") + + +if __name__ == "__main__": + main() diff --git a/Event/xAOD/xAODMetaDataCnv/python/TestWriteFileMetaData.py b/Event/xAOD/xAODMetaDataCnv/python/TestWriteFileMetaData.py new file mode 100644 index 000000000000..a2e4c548764c --- /dev/null +++ b/Event/xAOD/xAODMetaDataCnv/python/TestWriteFileMetaData.py @@ -0,0 +1,73 @@ +# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +"""Test multi-threaded xAOD::FileMetaData writing + +Read default test AOD and configure to write output stream with +xAOD::FileMetaData object. Set up to process 4 concurrent events. Inspect the +produced file for xAOD::FileMetaData metadata items. + + Typical usage example + python -m xAODMetaDataCnv.TestWriteFileMetaData |tee log +""" +from AthenaConfiguration import AllConfigFlags, TestDefaults, MainServicesConfig +from AthenaCommon import Configurable, Logging +from OutputStreamAthenaPool import OutputStreamConfig +from PyUtils import MetaReader +from xAODEventInfoCnv import xAODEventInfoCnvConfig + + +def writeFileMetaData(flags): + """set up an output stream and xAOD::EventInfo""" + accumulator = OutputStreamConfig.OutputStreamCfg( + configFlags=flags, streamName="AOD" + ) + + accumulator.merge( + xAODEventInfoCnvConfig.EventInfoCnvAlgCfg( + flags=flags, inputKey="", + ) + ) + + return accumulator + + +def testMetaData(file_name): + """Check that file metadata is in output""" + meta = MetaReader.read_metadata([file_name])[file_name]["metadata_items"] + file_info_items = [ + v for _, v in meta.items() if "FileMetaData" in v + ] + print("found file metadata objects:", file_info_items) + return bool(file_info_items) + + +def main(): + """Run a job writing a file with FileMetaData""" + Configurable.Configurable.configurableRun3Behavior = True + msg = Logging.logging.getLogger("TestFileMetaData") + + config_flags = AllConfigFlags.ConfigFlags + config_flags.Input.Files = TestDefaults.defaultTestFiles.AOD + config_flags.Output.AODFileName = "test.pool.root" + config_flags.Output.doWriteAOD = True + config_flags.Concurrency.NumThreads = 4 + config_flags.Concurrency.NumConcurrentEvents = 4 + config_flags.lock() + + write = MainServicesConfig.MainServicesCfg(config_flags) + write.merge(writeFileMetaData(config_flags)) + write.run(100) + + try: + if testMetaData(config_flags.Output.AODFileName): + msg.info("File contains xAOD::FileMetaData") + return 0 + msg.error("File does not contain xAOD::FileMetaData") + except ReferenceError: + msg.error("Failed to produce output file") + except KeyError: + msg.error("Failed to get metadata item list from file") + return 1 + + +if __name__ == "__main__": + main() diff --git a/Event/xAOD/xAODMetaDataCnv/share/FileMetaDataCreatorTool_jobOptions.py b/Event/xAOD/xAODMetaDataCnv/share/FileMetaDataCreatorTool_jobOptions.py index 21d0dcfefac7..402c6f76a82e 100644 --- a/Event/xAOD/xAODMetaDataCnv/share/FileMetaDataCreatorTool_jobOptions.py +++ b/Event/xAOD/xAODMetaDataCnv/share/FileMetaDataCreatorTool_jobOptions.py @@ -1,50 +1,72 @@ # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -# -# Test jobO for exercising xAODMaker::FileMetaDataCreatorTool to create -# the file-level metadata. -# +"""Test writing xAOD::EventFormat in job reading from input + +Read in POOL files created by the write test job options. Uses the metadata +tool to transcribe the EventFormat metadata to the MetaDataStore. Then an +algorithm reads the EventFormat from the MetaDataStore and prints the content. + + Typical usage example + 1. run: athena xAODEventFormatCnv/EventFormatWriteTestJobOptions.py + 2. run: athena xAODEventFormatCnv/EventFormatReadWriteTestJobOptions.py +""" from AthenaCommon import CfgMgr +from AthenaCommon.AlgSequence import AlgSequence from AthenaCommon.AppMgr import ServiceMgr as svcMgr +from AthenaCommon.AppMgr import theApp from AthenaCommon.AppMgr import ToolSvc -from AthenaCommon.AthenaCommonFlags import athenaCommonFlags -from RecExConfig.RecFlags import rec +import AthenaPoolCnvSvc.ReadAthenaPool +from xAODEventInfoCnv.xAODEventInfoCreator import xAODMaker__EventInfoCnvAlg from OutputStreamAthenaPool.MultipleStreamManager import MSMgr -# Set up the reading of an input file: -INFILE = ( - "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/CommonInputs/" - "data16_13TeV.00311321.physics_Main.recon.AOD.r9264/" - "AOD.11038520._000001.pool.root.1" -) +VERBOSE = 1 +DEBUG = 2 +INFO = 3 +WARNING = 4 -athenaCommonFlags.FilesInput = [INFILE] -athenaCommonFlags.EvtMax = 10 -# Turn off most of what RecExCommon does: +def makeStream(name='TestStream'): + """create and return an output stream""" + test_stream = MSMgr.NewStream( + StreamName=name, + FileName="{}.pool.root".format(name), + ) + return test_stream -rec.doCBNT.set_Value_and_Lock(False) -rec.doWriteAOD.set_Value_and_Lock(False) -rec.doWriteTAG.set_Value_and_Lock(False) -rec.AutoConfiguration = ["everything"] -# Read the file using RecExCommon: -include("RecExCommon/RecExCommon_topOptions.py") +# grab input files +svcMgr.EventSelector.InputCollections = ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/CommonInputs/data16_13TeV.00311321.physics_Main.recon.AOD.r9264/AOD.11038520._000001.pool.root.1"] -# Set up the metadata tool: -ToolSvc += CfgMgr.xAODMaker__FileMetaDataCreatorTool( - "FileMetaDataCreatorTool", OutputLevel=2 +# propogate xAOD::EventFormat from InputMetaDataStore to MetaDataStore +ToolSvc += CfgMgr.xAODMaker__FileMetaDataTool( + "FileMetaDataTool", + InputKey="FileMetaData", + OutputKey="FileMetaData", + OutputLevel=DEBUG, ) -svcMgr.MetaDataSvc.MetaDataTools += [ToolSvc.FileMetaDataCreatorTool] +svcMgr.MetaDataSvc.MetaDataTools += [ToolSvc.FileMetaDataTool] -# Set up the writing of an output file: -stream = MSMgr.NewPoolRootStream("StreamDAOD", "DxAOD.pool.root") -stream.AddItem( - ["xAOD::EventInfo#EventInfo", "xAOD::EventAuxInfo#EventInfoAux."] -) -stream.AddMetaDataItem( - [ - "xAOD::FileMetaData#FileMetaData", - "xAOD::FileMetaDataAuxInfo#FileMetaDataAux.", - ] -) +# Add the xAOD::EventFormat printer algorithm to main algorithm sequence +algSeq = AlgSequence() + +# Make sure event info is available +algSeq += xAODMaker__EventInfoCnvAlg() + +# Write some output streams to file with this container. +streams = [ + makeStream('xAOD') +] + +svcMgr.MessageSvc.OutputLevel = INFO +# svcMgr.MetaDataSvc.OutputLevel = INFO + + +# Set the event printout interval. +if not hasattr(svcMgr, theApp.EventLoop): + svcMgr += getattr(CfgMgr, theApp.EventLoop)() +evtLoop = getattr(svcMgr, theApp.EventLoop) +evtLoop.EventPrintoutInterval = 1000 + +# read the last event of the first file and the first event of the second file +# to test metadata access across file boundary +theApp.EvtMax = 100 diff --git a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.cxx b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.cxx index f7cecdc30cc0..ad383449e65b 100644 --- a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.cxx +++ b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.cxx @@ -2,274 +2,362 @@ Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ +// Local include(s): +#include "FileMetaDataCreatorTool.h" + // System include(s): #include <algorithm> +#include <functional> +#include <memory> +#include <stdexcept> #include <sstream> +#include <utility> // Athena metadata EDM: #include "AthenaPoolUtilities/CondAttrListCollection.h" #include "AthenaPoolUtilities/AthenaAttributeList.h" -#include "EventInfo/EventStreamInfo.h" +#include "StoreGate/ReadHandle.h" +#include "StoreGate/WriteHandle.h" +#include "xAODMetaData/FileMetaData.h" +#include "xAODMetaData/FileMetaDataAuxInfo.h" -// Local include(s): -#include "FileMetaDataCreatorTool.h" -namespace xAODMaker { +inline StatusCode toStatusCode(bool b) { + if (b) + return StatusCode::SUCCESS; + else + return StatusCode::FAILURE; +} -/// The folder in DetectorStore that we get the information from -static const char FOLDER_NAME[] = "/TagInfo"; -static const char SIMFOLDER_NAME[] = "/Simulation/Parameters"; - -/// Helper macro to execute the setter functions correctly -#define CHECK_BOOL(EXP) \ -do { \ - try { \ - if (!EXP) { \ - ATH_MSG_ERROR("Failed to execute: " << #EXP); \ - return StatusCode::FAILURE; \ - } \ - } catch(const std::exception& ex) { \ - ATH_MSG_INFO("Couldn't extract attribute with command: " \ - << #EXP); \ - } \ -} while (0) - -FileMetaDataCreatorTool::FileMetaDataCreatorTool(const std::string& name) - : asg::AsgMetadataTool(name) - , m_md() - , m_mdAux() { - declareProperty("OutputKey", m_outputKey = "FileMetaData"); - } +namespace xAODMaker { StatusCode - FileMetaDataCreatorTool::start() { - const DataHandle< CondAttrListCollection > dummy; - StatusCode sc = detStore()->regFcn( - &xAODMaker::FileMetaDataCreatorTool::update, - this, - dummy, - FOLDER_NAME, - true); - - if (sc.isFailure()) { - ATH_MSG_WARNING("Unable to register callback for " << FOLDER_NAME); - // return StatusCode::FAILURE; + FileMetaDataCreatorTool::initialize() { + // Greet the user: + ATH_MSG_DEBUG("Initialising - Package version: " << PACKAGE_VERSION); + + ATH_CHECK(m_eventStore.retrieve()); + ATH_CHECK(m_metaDataSvc.retrieve()); + + ATH_CHECK(m_tagInfoKey.initialize()); + ATH_CHECK(m_simInfoKey.initialize()); + + // If DataHeader key not specified, try determining it + if (m_dataHeaderKey.empty()) { + auto parentAlg = dynamic_cast< const INamedInterface* >(parent()); + if (parentAlg) + m_dataHeaderKey = parentAlg->name(); } - if (detStore()->contains< AthenaAttributeList >(SIMFOLDER_NAME)) { - const DataHandle< AthenaAttributeList > dummy2; - sc = detStore()->regFcn( - &xAODMaker::FileMetaDataCreatorTool::update, - this, - dummy2, - SIMFOLDER_NAME, - true); - - if (sc.isFailure()) { - ATH_MSG_WARNING("Unable to register callback for " << SIMFOLDER_NAME); - // return StatusCode::FAILURE; + // Listen for the begin of an input file. Act after MetaDataSvc, which + // has priority 80. That means the FileMetaDataTool be called first + ServiceHandle< IIncidentSvc > incidentSvc("IncidentSvc", name()); + ATH_CHECK(incidentSvc.retrieve()); + incidentSvc->addListener(this, "BeginInputFile", 70); + + // Create a fresh object to fill + ATH_MSG_DEBUG("Creating new xAOD::FileMetaData object to output"); + m_info = std::make_unique< xAOD::FileMetaData >(); + m_aux = std::make_unique< xAOD::FileMetaDataAuxInfo >(); + m_info->setStore(m_aux.get()); + + // FileMetaData has no content + m_filledNonEvent = false; + m_filledEvent = false; + + + // Return gracefully: + return StatusCode::SUCCESS; + } + +void + FileMetaDataCreatorTool::handle(const Incident& inc) { + // gracefully ignore unexpected incident types + if (inc.type() == "BeginInputFile") { + if (!updateFromNonEvent().isSuccess()) { + ATH_MSG_INFO("Failed to fill FileMetaData with non-event info"); } - } else { - ATH_MSG_INFO("Processing file with no " << SIMFOLDER_NAME); } - return StatusCode::SUCCESS; } StatusCode - FileMetaDataCreatorTool::initialize() { - // Greet the user: - ATH_MSG_DEBUG("Initialising - Package version: " << PACKAGE_VERSION); - ATH_MSG_DEBUG(" OutputKey = " << m_outputKey); - - // Return gracefully: + FileMetaDataCreatorTool::finalize() { + // Nothing to do here return StatusCode::SUCCESS; } StatusCode - FileMetaDataCreatorTool::beginInputFile() { - // Create the output objects if they don't exist yet: - if ((!m_md.get()) && (!m_mdAux.get())) { - ATH_MSG_DEBUG("Creating output objects"); - m_md.reset(new xAOD::FileMetaData()); - m_mdAux.reset(new xAOD::FileMetaDataAuxInfo()); - m_md->setStore(m_mdAux.get()); - } - - ATH_MSG_DEBUG("DetectorStore contents:\n\n" << detStore()->dump()); + FileMetaDataCreatorTool::postInitialize() { + return StatusCode::SUCCESS; + } - // Return gracefully: +StatusCode + FileMetaDataCreatorTool::preExecute() { return StatusCode::SUCCESS; } StatusCode - FileMetaDataCreatorTool::endInputFile() { - // Return gracefully: + FileMetaDataCreatorTool::preStream() { return StatusCode::SUCCESS; } StatusCode - FileMetaDataCreatorTool::metaDataStop() { - // Don't be offended if the metadata already exists in the output: - if (outputMetaStore()->contains< xAOD::FileMetaData >(m_outputKey)) { - ATH_MSG_DEBUG("xAOD::FileMetaData already in the output"); - return StatusCode::SUCCESS; + FileMetaDataCreatorTool::postExecute() { + // Lock the tool while working with FileMetaData + std::lock_guard lock(m_toolMutex); + + // Return if object has already been filled + if (m_filledEvent) return StatusCode::SUCCESS; + + // Sanity check + if (!(m_info && m_aux)) { + ATH_MSG_ERROR("No xAOD::FileMetaData object to fill"); + return StatusCode::FAILURE; } - SG::ConstIterator<EventStreamInfo> esi_h1; - SG::ConstIterator<EventStreamInfo> esi_h2; - StatusCode sc = outputMetaStore()->retrieve(esi_h1, esi_h2); - if (sc.isSuccess() && esi_h1 != esi_h2) { - if (esi_h1->getProcessingTags().size() == 1) { - CHECK_BOOL(m_md->setValue( - xAOD::FileMetaData::dataType, - *(esi_h1->getProcessingTags().begin()))); - } else { - ATH_MSG_WARNING("Found multiple output process tags"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::dataType, "multiple")); + // Read xAOD event info + auto eventInfo = + m_eventStore->tryConstRetrieve< xAOD::EventInfo >(m_eventInfoKey); + if (eventInfo) { + try { + ATH_MSG_DEBUG("Valid " << m_eventInfoKey << " handle"); + + xAOD::FileMetaData::MetaDataType type = xAOD::FileMetaData::mcProcID; + const float id = static_cast< float >(eventInfo->mcChannelNumber()); + + if (m_info->setValue(type, id)) + ATH_MSG_DEBUG("setting " << type << " to "<< id); + else + ATH_MSG_WARNING("error setting " << type << " to "<< id); + } catch (std::exception&) { + // Probably processing data + ATH_MSG_INFO("No xAOD::FileMetaData:mcProcID update from " + << m_eventInfoKey); } - if (esi_h1->getEventTypes().size() == 1) { - float id = esi_h1->getEventTypes().begin()->mc_channel_number(); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::mcProcID, id)); - } else { - ATH_MSG_WARNING("Found multiple eventtypes"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::mcProcID, 0.0f)); + } else { + ATH_MSG_WARNING("No " << m_eventInfoKey); + } + + // Read data header + auto dataHeader = + m_eventStore->tryConstRetrieve< DataHeader >(m_dataHeaderKey); + if (dataHeader) { + try { + ATH_MSG_DEBUG("valid " << m_dataHeaderKey << " handle"); + + xAOD::FileMetaData::MetaDataType type = xAOD::FileMetaData::dataType; + const std::string tag = dataHeader->getProcessTag(); + + if (m_info->setValue(type, tag)) + ATH_MSG_DEBUG("set " << type << " to "<< tag); + else + ATH_MSG_WARNING("error setting " << type << " to "<< tag); + } catch (std::exception&) { + ATH_MSG_INFO("No xAOD::FileMetaData::dataType update from " + << m_dataHeaderKey); } + } else { + ATH_MSG_WARNING("No " << m_dataHeaderKey); + } + + m_filledEvent = true; + + return StatusCode::SUCCESS; + } + +StatusCode + FileMetaDataCreatorTool::preFinalize() { + std::lock_guard lock(m_toolMutex); + + // Create and object if there isn't one already present + if (!m_metaDataSvc->contains< xAOD::FileMetaData >(m_key)) { + ATH_MSG_DEBUG("Creating new xAOD::FileMetaData object to output"); + auto info = std::make_unique< xAOD::FileMetaData >(); + auto aux = std::make_unique< xAOD::FileMetaDataAuxInfo >(); + info->setStore(aux.get()); + ATH_CHECK(m_metaDataSvc->record(std::move(info), m_key)); + ATH_CHECK(m_metaDataSvc->record(std::move(aux), m_key + "Aux.")); } - // Record the metadata, if any was found on the input: - if (m_md.get() && m_mdAux.get()) { - ATH_MSG_DEBUG("Recoding file level metadata"); - ATH_CHECK(outputMetaStore()->record(m_md.release(), m_outputKey)); - ATH_CHECK(outputMetaStore()->record(m_mdAux.release(), - m_outputKey + "Aux.")); + // Replace content in store with content created for this stream + auto output = m_metaDataSvc->tryRetrieve< xAOD::FileMetaData >(m_key); + if (!output) { + ATH_MSG_DEBUG("Cannot fill xAOD::FileMetaData output object"); + return StatusCode::FAILURE; } + *output = *m_info; - // Return gracefully: return StatusCode::SUCCESS; } StatusCode - FileMetaDataCreatorTool::update(IOVSVC_CALLBACK_ARGS_K(keys)) { - ATH_MSG_DEBUG("update() invoked for key(s): " << keys); + FileMetaDataCreatorTool::updateFromNonEvent() { + // Lock the tool while we work on the FileMetaData + std::lock_guard lock(m_toolMutex); + // Have we already done this? + if (m_filledNonEvent) return StatusCode::SUCCESS; + + // Sanity check + if (!(m_info && m_aux)) { + ATH_MSG_ERROR("No xAOD::FileMetaData object to fill"); + return StatusCode::FAILURE; + } + + // Read TagInfo + auto tagInfo = SG::makeHandle(m_tagInfoKey); + if (!tagInfo.isValid()) { + ATH_MSG_INFO("Invalid \"" << m_tagInfoKey.key() << "\" handle"); + return StatusCode::SUCCESS; + } + + for (const auto* payload : *tagInfo->payloadContainer()) { + for (const auto& itr : *payload) { + const coral::AttributeList& attributeList = itr.second; + ATH_CHECK( + setString( + attributeList, + "AtlasRelease", + xAOD::FileMetaData::productionRelease)); + + ATH_CHECK( + setString( + attributeList, + "AMITag", + xAOD::FileMetaData::amiTag)); + + ATH_CHECK( + setString( + attributeList, + "GeoAtlas", + xAOD::FileMetaData::geometryVersion)); + + ATH_CHECK( + setString( + attributeList, + "IOVDbGlobalTag", + xAOD::FileMetaData::conditionsTag)); + + ATH_CHECK( + setFloat( + attributeList, + "beam_energy", + xAOD::FileMetaData::beamEnergy)); + + ATH_CHECK( + setString( + attributeList, + "beam_type", + xAOD::FileMetaData::beamType)); + + // only investigate the first IOV + break; + } + // only investigate the first payload in the container + break; + } + + // Read simulation parameters + SG::ReadHandle< IOVMetaDataContainer > simInfo(m_simInfoKey); // Bail if the requested folder is not amongst the keys: - if (std::find(keys.begin(), keys.end(), FOLDER_NAME) == keys.end() - && std::find(keys.begin(), keys.end(), SIMFOLDER_NAME) == keys.end()) { - ATH_MSG_WARNING("Update callback received without the \"" - << FOLDER_NAME << "\" key"); + if (!simInfo.isValid()) { + ATH_MSG_INFO("Invalid \"" << m_simInfoKey.key() << "\" handle"); return StatusCode::SUCCESS; } - // Retrieve the needed metadata: - if (std::find(keys.begin(), keys.end(), FOLDER_NAME) != keys.end()) { - const CondAttrListCollection* tagInfo = 0; - ATH_CHECK(detStore()->retrieve(tagInfo, FOLDER_NAME)); + for (const CondAttrListCollection* payload : *simInfo->payloadContainer()) { + for (const auto& itr : *payload) { + const coral::AttributeList& attributeList = itr.second; - ATH_MSG_DEBUG("Retrieved object: " << FOLDER_NAME); + ATH_CHECK( + setString( + attributeList, + "SimulationFlavour", + xAOD::FileMetaData::simFlavour)); - // Make sure that it has some the expected size: - if (tagInfo->size() > 1) { - ATH_MSG_WARNING("Collection with >1 size received for \"" - << FOLDER_NAME << "\""); - } - if (!tagInfo->size()) { - ATH_MSG_ERROR("Empty collection received for \"" - << FOLDER_NAME << "\""); - return StatusCode::FAILURE; - } - // Access the first, and only channel of the object: - const CondAttrListCollection::AttributeList& al = - tagInfo->attributeList(0); - - if (al.exists("AtlasRelease")) { - CHECK_BOOL(m_md->setValue( - xAOD::FileMetaData::productionRelease, - al[ "AtlasRelease" ].data< std::string >())); - } else { - ATH_MSG_WARNING("Did not find AtlasRelease in TagInfo setting to none"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::productionRelease, "none")); - } + ATH_CHECK( + setBool( + attributeList, + "IsEventOverlayInputSim", + xAOD::FileMetaData::isDataOverlay)); - if (al.exists("AMITag")) { - CHECK_BOOL(m_md->setValue( - xAOD::FileMetaData::amiTag, - al["AMITag"].data< std::string >())); - } else { - ATH_MSG_WARNING("Did not find AMITag in TagInfo setting to none"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::amiTag, "none")); + // only investigate first IOV + break; } + // only investigate first payload + break; + } - if (al.exists("GeoAtlas")) { - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::geometryVersion, - al["GeoAtlas"].data< std::string >())); - } else { - ATH_MSG_WARNING("Did not find GeoAtlas in TagInfo setting to none"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::geometryVersion, "none")); - } + // FileMetaData object has been filled with non event info + m_filledNonEvent = true; + + return StatusCode::SUCCESS; + } - if (al.exists("IOVDbGlobalTag")) { - CHECK_BOOL(m_md->setValue( - xAOD::FileMetaData::conditionsTag, - al["IOVDbGlobalTag"].data< std::string >())); - } else { - ATH_MSG_WARNING("Did not find IOVDbGlobalTag in TagInfo setting to none"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::conditionsTag, "none")); +StatusCode + FileMetaDataCreatorTool::setString( + const coral::AttributeList& attrList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType type) { + try { + std::string attr = "none"; + if (attrList.exists(tag)) { + attr = attrList[tag].data< std::string >(); + // remap simulation flavor "default" to "FullSim" + if (type == xAOD::FileMetaData::simFlavour && attr == "default") + attr = "FullSim"; } + ATH_MSG_DEBUG("Setting " << type << " to \"" << attr << "\""); + return toStatusCode(m_info->setValue(type, attr)); + } catch (std::exception&) { + ATH_MSG_ERROR("unexpected error building FileMetaData"); + return StatusCode::FAILURE; + } + } - // Convert the beam energy to float. (If it exists.) - if (al.exists("beam_energy")) { +StatusCode + FileMetaDataCreatorTool::setFloat( + const coral::AttributeList& attrList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType type) { + try { + float number = -1.0f; + if (attrList.exists(tag)) { try { - const std::string beamEnergyStr = al["beam_energy"].data< std::string >(); - char* endptr = 0; - float beamEnergy = strtof(beamEnergyStr.c_str(), &endptr); - if (endptr) { - if (!m_md->setValue(xAOD::FileMetaData::beamEnergy, beamEnergy)) { - ATH_MSG_ERROR("Failed to set the beam energy"); - return StatusCode::FAILURE; - } - } - } catch(const std::exception& ex) { - ATH_MSG_INFO("Couldn't set the beam energy"); + const std::string attr = attrList[tag].data< std::string >(); + number = std::stof(attr); + } catch (std::invalid_argument& e) { + ATH_MSG_INFO("beam energy tag could not be converted to float"); + } catch (std::out_of_range& e) { + ATH_MSG_INFO("converted beam energy value outside float range"); } - } else { - ATH_MSG_WARNING("Did not find beam_energy in TagInfo setting to -1"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::beamEnergy, -1.0f)); - } - - if (al.exists("beam_type")) { - CHECK_BOOL(m_md->setValue( - xAOD::FileMetaData::beamType, - al["beam_type"].data< std::string >())); - } else { - ATH_MSG_WARNING("Did not find beam_type in TagInfo setting to none"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::beamType, "none")); } + ATH_MSG_DEBUG("Setting " << type << " to \"" << number << "\""); + return toStatusCode(m_info->setValue(type, number)); + } catch (std::exception&) { + ATH_MSG_ERROR("unexpected error building FileMetaData"); + return StatusCode::FAILURE; } + } - if (std::find(keys.begin(), keys.end(), SIMFOLDER_NAME) != keys.end()) { - const AthenaAttributeList* simInfo = 0; - ATH_CHECK(detStore()->retrieve(simInfo, SIMFOLDER_NAME)); - - if (simInfo->exists("SimulationFlavour")) { - std::string flavor = (*simInfo)["SimulationFlavour"].data< std::string >(); - if (flavor == "default") flavor = "FullSim"; - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::simFlavour, flavor)); - } else { - ATH_MSG_ERROR("Unable to retrieve SimulationFlavour from " << SIMFOLDER_NAME); +StatusCode + FileMetaDataCreatorTool::setBool( + const coral::AttributeList& attrList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType type) { + try { + bool yesNo = false; + if (attrList.exists(tag)) { + yesNo = attrList[tag].data< std::string >() == "True"; } - if (simInfo->exists("IsEventOverlayInputSim")) { - bool isDataOverlay = (*simInfo)["IsEventOverlayInputSim"].data< std::string >() == "True"; - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::isDataOverlay, isDataOverlay)); - } else { - ATH_MSG_INFO("Unable to retrieve IsEventOverlayInputSim from " - << SIMFOLDER_NAME << " - assuming not data overlay"); - CHECK_BOOL(m_md->setValue(xAOD::FileMetaData::isDataOverlay, false)); - } + ATH_MSG_DEBUG("Setting " << type << " to " << std::boolalpha << yesNo + << std::noboolalpha); + return toStatusCode(m_info->setValue(type, yesNo)); + } catch (std::exception&) { + ATH_MSG_ERROR("unexpected error building FileMetaData"); + return StatusCode::FAILURE; } - - // Return gracefully: - return StatusCode::SUCCESS; } } // namespace xAODMaker diff --git a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.h b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.h index 144431f39f52..dfcd28f0658c 100644 --- a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.h +++ b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataCreatorTool.h @@ -10,82 +10,157 @@ #include <memory> // Infrastructure include(s): +#include "Gaudi/Property.h" +#include "GaudiKernel/extends.h" +#include "GaudiKernel/IIncidentListener.h" #include "GaudiKernel/ServiceHandle.h" -#include "AthenaKernel/IIOVSvc.h" -#include "AsgTools/AsgMetadataTool.h" -#include "AthenaKernel/IMetaDataTool.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "AthenaKernel/IAthenaOutputTool.h" +#include "AthenaKernel/IMetaDataSvc.h" +#include "IOVDbDataModel/IOVMetaDataContainer.h" +#include "CoralBase/AttributeList.h" +#include "StoreGate/ReadHandleKey.h" // EDM include(s): +#include "PersistentDataModel/DataHeader.h" +#include "xAODEventInfo/EventInfo.h" #include "xAODMetaData/FileMetaData.h" #include "xAODMetaData/FileMetaDataAuxInfo.h" namespace xAODMaker { -/// Tool creating or propagating xAOD::FileMetaData information +/// Tool creating xAOD::FileMetaData information /// -/// This Athena-only tool can be used to create xAOD::FileMetaData -/// information out of the non-ROOT-readable metadata available in -/// the input. -/// -/// Or, if the input file already has xAOD::FileMetaData payload, -/// it is taken as is, and copied to the output. -/// -/// The class uses asg::AsgMetadataTool as a base class for convenience, -/// but it's not a dual-use tool. (Hence the header is hidden from the -/// outside world.) +/// This Athena-only tool can be used to create xAOD::FileMetaData information +/// out of the non-ROOT-readable metadata available in the input. The +/// FileMetaDataTool may have copied a xAOD::FileMetaData object to the +/// MetaDataStore. If such a xAOD::FileMetaData object is found it is updated +/// to reflect the current data type and MC channel number. /// /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> -/// -/// $Revision: 676522 $ -/// $Date: 2015-06-19 00:17:03 +0200 (Fri, 19 Jun 2015) $ +/// @author Frank Berghaus <fberghaus@anl.gov> /// class FileMetaDataCreatorTool - : public asg::AsgMetadataTool - , public virtual ::IMetaDataTool { - /// Declare the correct constructor for Athena - ASG_TOOL_CLASS(FileMetaDataCreatorTool, IMetaDataTool) - + : public extends< AthAlgTool, IAthenaOutputTool, IIncidentListener > { public: - /// Regular AsgTool constructor - FileMetaDataCreatorTool(const std::string& name = - "FileMetaDataCreatorTool"); + using extends::extends; - /// Function initialising the tool - virtual StatusCode initialize(); - virtual StatusCode start(); + /// @name AlgTool Methods + /// @{ + /// Called by AthenaOutputStream::initialize() (via ToolSvc retrieve()). + StatusCode initialize() override; - protected: - /// @name Functions called by the AsgMetadataTool base class - /// @{ + /// Called at the end of AthenaOutputStream::finalize() (via release()). + StatusCode finalize() override; + /// @} - /// Function collecting the metadata from a new input file - virtual StatusCode beginInputFile(); + /// @name Methods inherited by IAthenaOutputTool + /// @{ + /// Called at the end of AthenaOutputStream::initialize(). + StatusCode postInitialize() override; - /// Function collecting the metadata from a new input file - virtual StatusCode endInputFile(); + /// Called at the beginning of AthenaOutputStream::execute(). + StatusCode preExecute() override; - /// Function writing the collected metadata to the output - virtual StatusCode metaDataStop(); + /// Called before actually streaming objects. + StatusCode preStream() override; - /// Function collecting the metadata from a new input file - virtual StatusCode beginInputFile(const SG::SourceID&) {return beginInputFile();} + /// Called at the end of AthenaOutputStream::execute(). + StatusCode postExecute() override; - /// Function collecting the metadata from a new input file - virtual StatusCode endInputFile(const SG::SourceID&) {return endInputFile();} + /// Called at the beginning of AthenaOutputStream::finalize(). + StatusCode preFinalize() override; + /// @} - /// @} + /// @name IIncidentListener methods + //@{ + /// Handle BeginInputFile incident after MetaDataSvc + void handle(const Incident&) override; + //@} private: - /// Function called by the DetectorStore when the metadata is updated - StatusCode update(IOVSVC_CALLBACK_ARGS_P(I, keys)); - - /// Key of the metadata object for the output file - std::string m_outputKey; - - /// The output interface object - std::unique_ptr< xAOD::FileMetaData > m_md; - /// The output auxiliary object - std::unique_ptr< xAOD::FileMetaDataAuxInfo > m_mdAux; + /// output key for produced xAOD::FileMetaData in MetaDataStore + Gaudi::Property< std::string > m_key{ + this, + "OutputKey", + "FileMetaData", + "Key to use for FileMetaData in MetaDataStore" + }; + + /// Read tag information + SG::ReadHandleKey< IOVMetaDataContainer > m_tagInfoKey { + this, + "TagInfoKey", + "InputMetaDataStore+/TagInfo", + "Store and Key to use to look up tags" + }; + + /// Read simulation parameters + SG::ReadHandleKey< IOVMetaDataContainer > m_simInfoKey { + this, + "SimInfoKey", + "InputMetaDataStore+/Simulation/Parameters", + "Store and Key to use to look up simulation parameters" + }; + + /// DataHeader is produced by another OutputTool, so need StoreGateSvc + ServiceHandle< StoreGateSvc > m_eventStore{"StoreGateSvc", name()}; + + + /// Key for xAOD::EventInfo to update MC channel number + Gaudi::Property< std::string > m_eventInfoKey { + this, + "EventInfoKey", + "EventInfo", + "StoreGate key to read xAOD::EventInfo" + }; + + /// Key for DataHeader in StoreGateSvc + Gaudi::Property< std::string > m_dataHeaderKey { + this, + "StreamName", + "", + "key of data header in event store" + }; + + /// Use MetaDataSvc store interface to support output in EventService + ServiceHandle< IMetaDataSvc > m_metaDataSvc{"MetaDataSvc", name()}; + + /// Update from Simulation Parameters and TagInfo + StatusCode updateFromNonEvent(); + + /// helper tool to update file meta data with IOV string content + StatusCode setString( + const coral::AttributeList& attributeList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType type); + + /// helper tool to update file meta data with IOV float content + StatusCode setFloat( + const coral::AttributeList& attrList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType); + + /// helper tool to update file meta data with IOV boolean content + StatusCode setBool( + const coral::AttributeList& attrList, + const std::string& tag, + const xAOD::FileMetaData::MetaDataType); + + /// The object created for this output stream + std::unique_ptr< xAOD::FileMetaData > m_info; + + /// The auxiliary containing the created object + std::unique_ptr< xAOD::FileMetaDataAuxInfo > m_aux; + + /// FileMetaData has been filled with non-event info + bool m_filledNonEvent{false}; + + /// FileMetaData has been filled with event information + bool m_filledEvent{false}; + + /// creation of FileMetaData should happen on a single thread + std::mutex m_toolMutex; }; // class FileMetaDataCreatorTool } // namespace xAODMaker diff --git a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.cxx b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.cxx deleted file mode 100644 index 17c31e3c70f6..000000000000 --- a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.cxx +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -// System include(s): -#include <algorithm> -#include <sstream> -#include <vector> - -// Athena metadata EDM: -#include "EventInfo/EventStreamInfo.h" - -// Local include(s): -#include "FileMetaDataMarkUpTool.h" - -namespace xAODMaker { - -/// Helper macro to execute the setter functions correctly -#define CHECK_BOOL(EXP) \ - do { \ - try { \ - if (!EXP) { \ - ATH_MSG_ERROR("Failed to execute: " << #EXP); \ - return StatusCode::FAILURE; \ - } \ - } catch(const std::exception& ex) { \ - ATH_MSG_INFO("Couldn't extract attribute with command: " \ - << #EXP); \ - } \ - } while (0) - - FileMetaDataMarkUpTool::FileMetaDataMarkUpTool(const std::string& name) - : asg::AsgMetadataTool(name) { - declareProperty("Key", m_outputKey = ""); - } - - StatusCode - FileMetaDataMarkUpTool::initialize() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::postInitialize() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::preExecute() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::preStream() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::postExecute() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::preFinalize() { - ATH_MSG_DEBUG("in preFinalize()"); - - std::vector<std::string> fmd_keys; - outputMetaStore()->keys<xAOD::FileMetaData>(fmd_keys); - if (fmd_keys.size() != 1) { - return StatusCode::SUCCESS; - } - - if (!outputMetaStore()->transientContains< xAOD::FileMetaData >( - *(fmd_keys.begin()))) { - return StatusCode::SUCCESS; - } - - xAOD::FileMetaData* fmd = nullptr; - StatusCode sc = outputMetaStore()->retrieve(fmd, *(fmd_keys.begin())); - if (!sc.isSuccess()) { - return StatusCode::SUCCESS; - } - - const EventStreamInfo* esi = nullptr; - sc = outputMetaStore()->retrieve(esi, m_outputKey); - if (sc.isSuccess()) { - ATH_MSG_DEBUG("Setting xAOD::FileMetaData from output " - << "EventStreamInfo object " << m_outputKey); - if (esi->getProcessingTags().size() == 1) { - CHECK_BOOL(fmd->setValue(xAOD::FileMetaData::dataType, - *(esi->getProcessingTags().begin()))); - } else { - CHECK_BOOL(fmd->setValue(xAOD::FileMetaData::dataType, m_outputKey)); - } - if (esi->getEventTypes().size() == 1) { - float id = esi->getEventTypes().begin()->mc_channel_number(); - CHECK_BOOL(fmd->setValue(xAOD::FileMetaData::mcProcID, id)); - } - } - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::finalize() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::start() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::beginInputFile() { - return StatusCode::SUCCESS; - } - - StatusCode - FileMetaDataMarkUpTool::metaDataStop() { - return StatusCode::SUCCESS; - } - -} // namespace xAODMaker diff --git a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.h b/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.h deleted file mode 100644 index 50ce08e07e99..000000000000 --- a/Event/xAOD/xAODMetaDataCnv/src/FileMetaDataMarkUpTool.h +++ /dev/null @@ -1,88 +0,0 @@ -// Dear emacs, this is -*- c++ -*- -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ -#ifndef XAODMETADATACNV_FILEMETADATAMARKUPTOOL_H -#define XAODMETADATACNV_FILEMETADATAMARKUPTOOL_H - -// System include(s): -#include <string> -#include <memory> - -// Infrastructure include(s): -#include "GaudiKernel/ServiceHandle.h" -#include "AsgTools/AsgMetadataTool.h" -#include "AthenaKernel/IAthenaOutputTool.h" - -// EDM include(s): -#include "xAODMetaData/FileMetaData.h" -#include "xAODMetaData/FileMetaDataAuxInfo.h" - -namespace xAODMaker { - -/// Tool creating or propagating xAOD::FileMetaData information -/// -/// This Athena-only tool can be used to create xAOD::FileMetaData -/// information out of the non-ROOT-readable metadata available in -/// the input. -/// -/// Or, if the input file already has xAOD::FileMetaData payload, -/// it is taken as is, and copied to the output. -/// -/// The class uses asg::AsgMetadataTool as a base class for convenience, -/// but it's not a dual-use tool. (Hence the header is hidden from the -/// outside world.) -/// -/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> -/// -/// $Revision: 676522 $ -/// $Date: 2015-06-19 00:17:03 +0200 (Fri, 19 Jun 2015) $ -/// -class FileMetaDataMarkUpTool - : public asg::AsgMetadataTool - , public virtual ::IAthenaOutputTool { - /// Declare the correct constructor for Athena - ASG_TOOL_CLASS(FileMetaDataMarkUpTool, IAthenaOutputTool) - - public: - /// Regular AsgTool constructor - explicit FileMetaDataMarkUpTool( - const std::string& name = "FileMetaDataMarkUpTool"); - - /// Required of all IAthenaOutputTools: - /// Called by AthenaOutputStream::initialize() (via ToolSvc retrieve()). - StatusCode initialize() override; - /// Called at the end of AthenaOutputStream::initialize(). - StatusCode postInitialize() override; - /// Called at the beginning of AthenaOutputStream::execute(). - StatusCode preExecute() override; - /// Called before actually streaming objects. - StatusCode preStream() override; - /// Called at the end of AthenaOutputStream::execute(). - StatusCode postExecute() override; - /// Called at the beginning of AthenaOutputStream::finalize(). - StatusCode preFinalize() override; - /// Called at the end of AthenaOutputStream::finalize() (via release()). - StatusCode finalize() override; - StatusCode start() override; - - protected: - /// @name Functions called by the AsgMetadataTool base class - /// @{ - - /// Function collecting the metadata from a new input file - StatusCode beginInputFile() override; - - /// Function writing the collected metadata to the output - StatusCode metaDataStop() override; - - /// @} - - private: - /// Key of the metadata object for the output file - std::string m_outputKey; -}; // class FileMetaDataMarkUpTool - -} // namespace xAODMaker - -#endif // XAODMETADATACNV_FILEMETADATAMARKUPTOOL_H diff --git a/Event/xAOD/xAODMetaDataCnv/src/components/xAODMetaDataCnv_entries.cxx b/Event/xAOD/xAODMetaDataCnv/src/components/xAODMetaDataCnv_entries.cxx index 7e3a95a0dedf..1a7c70cad4d0 100644 --- a/Event/xAOD/xAODMetaDataCnv/src/components/xAODMetaDataCnv_entries.cxx +++ b/Event/xAOD/xAODMetaDataCnv/src/components/xAODMetaDataCnv_entries.cxx @@ -1,8 +1,9 @@ +// Dear emacs, this is -*- c++ -*- +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ #include "xAODMetaDataCnv/FileMetaDataTool.h" #include "../FileMetaDataCreatorTool.h" -#include "../FileMetaDataMarkUpTool.h" DECLARE_COMPONENT( xAODMaker::FileMetaDataTool ) DECLARE_COMPONENT( xAODMaker::FileMetaDataCreatorTool ) -DECLARE_COMPONENT( xAODMaker::FileMetaDataMarkUpTool ) - diff --git a/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/FileMetaDataTool.h b/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/FileMetaDataTool.h index 3c3c718a93e5..c45092a35af3 100644 --- a/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/FileMetaDataTool.h +++ b/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/FileMetaDataTool.h @@ -7,89 +7,79 @@ // System include(s): #include <string> -#include <memory> // Infrastructure include(s): #include "AsgTools/AsgMetadataTool.h" #ifndef XAOD_STANDALONE -# include "AthenaKernel/IMetaDataTool.h" -#endif // XAOD_STANDALONE - -// EDM include(s): -#include "xAODMetaData/FileMetaData.h" -#include "xAODMetaData/FileMetaDataAuxInfo.h" +# include "GaudiKernel/ServiceHandle.h" +# include "AthenaKernel/IMetaDataSvc.h" +# include "AthenaKernel/IMetaDataTool.h" +#endif namespace xAODMaker { -/// Tool taking care of propagating xAOD::FileMetaData information -/// -/// This dual-use tool can be used both in Athena and in AnalysisBase -/// to propagate the generic file-level metadata from the processed -/// input files to an output file. +/// Tool propagating xAOD::FileMetaData from input to output /// -/// It relies on the input already containing the information in an -/// xAOD format. +/// This tool propogates the xAOD::FileMetaData object from the input files to +/// the MetaDataStore in Athena. It requires the input to contain the +/// information in an xAOD format. The tool will emit a warning if the file +/// metadata between inputs does not match. /// /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> -/// -/// $Revision: 683697 $ -/// $Date: 2015-07-17 11:12:14 +0200 (Fri, 17 Jul 2015) $ +/// @author Frank Berghaus <fberghaus@anl.gov> /// class FileMetaDataTool - : public asg::AsgMetadataTool -#ifndef XAOD_STANDALONE - , public virtual ::IMetaDataTool -#endif // XAOD_STANDALONE -{ - /// Declare the correct constructor for Athena - ASG_TOOL_CLASS0(FileMetaDataTool) - +#ifdef XAOD_STANDALONE + : public asg::AsgMetadataTool { +#else + : public asg::AsgMetadataTool, virtual public IMetaDataTool { +#endif public: - /// Regular AsgTool constructor - explicit FileMetaDataTool(const std::string& name = "FileMetaDataTool"); - - /// Function initialising the tool - virtual StatusCode initialize(); + //using extends::extends; + ASG_TOOL_CLASS0(FileMetaDataTool) - protected: - /// @name Functions called by the AsgMetadataTool base class - /// @{ + /// Regular AsgTool constructor + explicit FileMetaDataTool(const std::string& name = "FileMetaDataTool"); - /// Function collecting the metadata from a new input file - virtual StatusCode beginInputFile(); + /// Function initialising the tool + StatusCode initialize() override; - /// Function collecting the metadata from a new input file - virtual StatusCode endInputFile(); + /// @name Functions called by the IMetaDataTool base class + /// @{ - /// Function making sure that BeginInputFile incidents are not missed - virtual StatusCode beginEvent(); + /// Collecting file metadata from input and write to output + StatusCode beginInputFile() override; - /// Function writing the collected metadata to the output - virtual StatusCode metaDataStop(); + /// Does nothing + StatusCode endInputFile() override; #ifndef XAOD_STANDALONE - /// Function collecting the metadata from a new input file - virtual StatusCode beginInputFile(const SG::SourceID&) {return beginInputFile();} + /// Collecting file metadata from input and write to output + StatusCode beginInputFile(const SG::SourceID&) override; - /// Function collecting the metadata from a new input file - virtual StatusCode endInputFile(const SG::SourceID&) {return endInputFile();} -#endif // XAOD_STANDALONE - /// @} + /// Does nothing + StatusCode endInputFile(const SG::SourceID&) override; +#endif + + /// Does nothing + StatusCode metaDataStop() override; + + /// @} private: - /// Key of the metadata object in the input file - std::string m_inputKey; - /// Key of the metadata object for the output file - std::string m_outputKey; - - /// The output interface object - std::unique_ptr< xAOD::FileMetaData > m_md; - /// The output auxiliary object - std::unique_ptr< xAOD::FileMetaDataAuxInfo > m_mdAux; - - /// Internal flag for keeping track of whether a BeginInputFile incident - /// was seen already - bool m_beginFileIncidentSeen; + /// Key of the metadata object in the input file + std::string m_inputKey; + + /// Key of the metadata object for the output file + std::string m_outputKey; + +#ifndef XAOD_STANDALONE + /// Get a handle on the metadata store for the job + ServiceHandle< IMetaDataSvc > m_metaDataSvc{"MetaDataSvc", name()}; +#endif + + // To lock/unlock the tool + std::mutex m_toolMutex; }; // class FileMetaDataTool } // namespace xAODMaker diff --git a/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/xAODMetaDataCnvAthena.h b/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/xAODMetaDataCnvAthena.h deleted file mode 100644 index aa05a376f510..000000000000 --- a/Event/xAOD/xAODMetaDataCnv/xAODMetaDataCnv/xAODMetaDataCnvAthena.h +++ /dev/null @@ -1,16 +0,0 @@ -// Dear emacs, this is -*- c++ -*- -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -// $Id: xAODMetaDataCnvAthena.h 670279 2015-05-27 15:18:27Z krasznaa $ -#ifndef XAODMETADATACNV_XAODMETADATACNVATHENA_H -#define XAODMETADATACNV_XAODMETADATACNVATHENA_H - -// This file is used to convince checkreq.py that the correct dependencies -// were declared for the package. It should never be explicitly included -// by any client code. - -#include "AthenaKernel/IMetaDataTool.h" - -#endif // XAODMETADATACNV_XAODMETADATACNVATHENA_H diff --git a/Projects/AthGeneration/package_filters.txt b/Projects/AthGeneration/package_filters.txt index e738f729837a..bf3abe287df1 100644 --- a/Projects/AthGeneration/package_filters.txt +++ b/Projects/AthGeneration/package_filters.txt @@ -140,6 +140,9 @@ + Event/xAOD/xAODEventShape + Event/xAOD/xAODJet + Event/xAOD/xAODJetAthenaPool ++ Event/xAOD/xAODMetaData ++ Event/xAOD/xAODMetaDataAthenaPool ++ Event/xAOD/xAODMetaDataCnv + Event/xAOD/xAODMuon + Event/xAOD/xAODPrimitives + Event/xAOD/xAODTracking diff --git a/Projects/AthSimulation/package_filters.txt b/Projects/AthSimulation/package_filters.txt index 717087ee4843..2fcd19aace4f 100644 --- a/Projects/AthSimulation/package_filters.txt +++ b/Projects/AthSimulation/package_filters.txt @@ -151,6 +151,9 @@ + Event/xAOD/xAODEventInfoCnv + Event/xAOD/xAODJet + Event/xAOD/xAODJetAthenaPool ++ Event/xAOD/xAODMetaData ++ Event/xAOD/xAODMetaDataAthenaPool ++ Event/xAOD/xAODMetaDataCnv + Event/xAOD/xAODPrimitives + Event/xAOD/xAODTruth + Event/xAOD/xAODTruthAthenaPool diff --git a/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py b/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py index afeaf2a19648..9fba04818920 100644 --- a/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py +++ b/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py @@ -1399,6 +1399,11 @@ if rec.doWriteAOD(): ToolSvc += CfgMgr.xAODMaker__EventFormatMetaDataTool( "EventFormatMetaDataTool") svcMgr.MetaDataSvc.MetaDataTools += [ ToolSvc.EventFormatMetaDataTool ] + + # FileMetaData tool + ToolSvc += CfgMgr.xAODMaker__FileMetaDataTool("FileMetaDataTool") + svcMgr.MetaDataSvc.MetaDataTools += [ToolSvc.FileMetaDataTool] + # Put MetaData in AOD stream via AugmentedPoolStream_ # Write all meta data containers StreamAOD_Augmented.AddMetaDataItem(dfMetadataItemList()) -- GitLab