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