From 5f44d9207f49951a0e7c544498622761fcbc5bae Mon Sep 17 00:00:00 2001
From: Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
Date: Wed, 22 Jul 2020 15:06:35 +0200
Subject: [PATCH 1/3] Introduced xAODMaker::ROOTHeaderLoaderSvc.

Introduced a new (simple) service for hacking around the issue discussed in
ATR-21753 and ROOT-10940.
---
 Event/xAOD/xAODCoreCnv/CMakeLists.txt         | 35 ++++++-------
 .../ROOTHeaderLoaderSvcTest_jobOptions.py     | 15 ++++++
 .../xAODCoreCnv/src/ROOTHeaderLoaderSvc.cxx   | 46 +++++++++++++++++
 .../xAODCoreCnv/src/ROOTHeaderLoaderSvc.h     | 50 +++++++++++++++++++
 .../src/components/xAODCoreCnv_entries.cxx    |  7 ++-
 .../xAODCoreCnv/IROOTHeaderLoaderSvc.h        | 34 +++++++++++++
 6 files changed, 166 insertions(+), 21 deletions(-)
 create mode 100644 Event/xAOD/xAODCoreCnv/share/ROOTHeaderLoaderSvcTest_jobOptions.py
 create mode 100644 Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.cxx
 create mode 100644 Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
 create mode 100644 Event/xAOD/xAODCoreCnv/xAODCoreCnv/IROOTHeaderLoaderSvc.h

diff --git a/Event/xAOD/xAODCoreCnv/CMakeLists.txt b/Event/xAOD/xAODCoreCnv/CMakeLists.txt
index d8ebff324602..d351dd74f77f 100644
--- a/Event/xAOD/xAODCoreCnv/CMakeLists.txt
+++ b/Event/xAOD/xAODCoreCnv/CMakeLists.txt
@@ -1,28 +1,23 @@
-# $Id$
-################################################################################
-# Package: xAODCoreCnv
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-# Declare the package name:
+# Declare the package's name.
 atlas_subdir( xAODCoreCnv )
 
-# Declare the package's dependencies:
-atlas_depends_on_subdirs(
-   PRIVATE
-   Control/AthContainers
-   Control/AthContainersInterfaces
-   Control/AthLinks
-   Control/AthenaBaseComps
-   Control/AthenaKernel
-   Control/SGTools
-   Event/xAOD/xAODCore
-   GaudiKernel )
+# External(s).
+find_package( ROOT COMPONENTS Core )
+
+# Component(s) in the package.
+atlas_add_library( xAODCoreCnvLib
+   xAODCoreCnv/*.h
+   INTERFACE
+   PUBLIC_HEADERS xAODCoreCnv
+   LINK_LIBRARIES GaudiKernel )
 
-# Component(s) in the package:
 atlas_add_component( xAODCoreCnv
    src/*.h src/*.cxx src/components/*.cxx
-   LINK_LIBRARIES AthContainers AthLinks AthenaBaseComps AthenaKernel SGTools
-   xAODCore GaudiKernel )
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthLinks AthenaBaseComps
+   AthenaKernel SGTools xAODCore GaudiKernel xAODCoreCnvLib )
 
-# Install files from the package:
+# Install files from the package.
 atlas_install_joboptions( share/*.py )
diff --git a/Event/xAOD/xAODCoreCnv/share/ROOTHeaderLoaderSvcTest_jobOptions.py b/Event/xAOD/xAODCoreCnv/share/ROOTHeaderLoaderSvcTest_jobOptions.py
new file mode 100644
index 000000000000..02eba950bd76
--- /dev/null
+++ b/Event/xAOD/xAODCoreCnv/share/ROOTHeaderLoaderSvcTest_jobOptions.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+#
+# Small/simple job testing the behaviour of xAODMaker::ROOTHeaderLoaderSvc.
+#
+
+# Set up the service.
+from AthenaCommon.AppMgr import ServiceMgr
+ServiceMgr += CfgMgr.xAODMaker__ROOTHeaderLoaderSvc( 'ROOTHeaderLoaderSvc',
+                              HeaderNames = [
+                                 'xAODEgamma/PhotonContainer.h',
+                                 'xAODTrigEgamma/TrigPhotonContainer.h' ] )
+theApp.CreateSvc += [ 'xAODMaker::ROOTHeaderLoaderSvc/ROOTHeaderLoaderSvc' ]
+
+# Some final tweaking:
+theApp.EvtMax = 1
diff --git a/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.cxx b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.cxx
new file mode 100644
index 000000000000..786d242625c0
--- /dev/null
+++ b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.cxx
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+//
+
+// Local include(s).
+#include "ROOTHeaderLoaderSvc.h"
+
+// ROOT include(s).
+#include <TInterpreter.h>
+#include <TString.h>
+#include <TROOT.h>
+
+namespace xAODMaker {
+
+   StatusCode ROOTHeaderLoaderSvc::initialize() {
+
+      // Load all the configured headers.
+      for( const std::string& headerName : m_headerNames.value() ) {
+         ATH_MSG_INFO( "Loading header \"" << headerName << "\"" );
+         ATH_CHECK( loadHeader( headerName ) );
+      }
+
+      // Return gracefully.
+      return StatusCode::SUCCESS;
+   }
+
+   StatusCode
+   ROOTHeaderLoaderSvc::loadHeader( const std::string& headerName ) const {
+
+      // Load the requested header.
+      Int_t errorCode = 0;
+      gROOT->ProcessLine( TString::Format( "#include \"%s\"",
+                                           headerName.c_str() ),
+                          &errorCode );
+
+      // Check if the call succeeded.
+      if( errorCode != TInterpreter::kNoError ) {
+         ATH_MSG_FATAL( "Failed to load header \"" << headerName << "\"" );
+         return StatusCode::FAILURE;
+      }
+
+      // Return gracefully.
+      return StatusCode::SUCCESS;
+   }
+
+} // namespace xAODMaker
diff --git a/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
new file mode 100644
index 000000000000..efd547e0f8d5
--- /dev/null
+++ b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
@@ -0,0 +1,50 @@
+// Dear emacs, this is -*- c++ -*-
+//
+// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+//
+#ifndef XAODCORECNV_ROOTHEADERLOADERSVC_H
+#define XAODCORECNV_ROOTHEADERLOADERSVC_H
+
+// Local include(s).
+#include "xAODCoreCnv/IROOTHeaderLoaderSvc.h"
+
+// Framework include(s).
+#include "AthenaBaseComps/AthService.h"
+#include "GaudiKernel/Property.h"
+
+// System include(s).
+#include <string>
+#include <vector>
+
+namespace xAODMaker {
+
+   class ROOTHeaderLoaderSvc : public extends< AthService,
+                                               IROOTHeaderLoaderSvc > {
+
+   public:
+      // Inherit the base class's constructor(s).
+      using extends::extends;
+
+      /// Function initialising the service
+      virtual StatusCode initialize() override;
+
+      /// @name Implementation of the @c xAODMaker::IEventFormatSvc interface
+      /// @{
+
+      /// (Force-)Load one particular header
+      virtual StatusCode
+      loadHeader( const std::string& headerName ) const override;
+
+      /// @}
+
+   private:
+      /// Names of the headers to auto-load during initialisation
+      Gaudi::Property< std::vector< std::string > > m_headerNames{ this,
+         "HeaderNames", {},
+         "Names of the headers to auto-load during initialisation" };
+
+   }; // class ROOTHeaderLoaderSvc
+
+} // namespace xAODMaker
+
+#endif // XAODCORECNV_ROOTHEADERLOADERSVC_H
diff --git a/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx b/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx
index 372f2e6a2a9c..b9c62416b7f8 100644
--- a/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx
+++ b/Event/xAOD/xAODCoreCnv/src/components/xAODCoreCnv_entries.cxx
@@ -1,6 +1,11 @@
+//
+// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+//
+
 #include "../AuxStoreWrapper.h"
 #include "../ElementLinkResetAlg.h"
+#include "../ROOTHeaderLoaderSvc.h"
 
 DECLARE_COMPONENT( xAODMaker::AuxStoreWrapper )
 DECLARE_COMPONENT( xAODMaker::ElementLinkResetAlg )
-
+DECLARE_COMPONENT( xAODMaker::ROOTHeaderLoaderSvc )
diff --git a/Event/xAOD/xAODCoreCnv/xAODCoreCnv/IROOTHeaderLoaderSvc.h b/Event/xAOD/xAODCoreCnv/xAODCoreCnv/IROOTHeaderLoaderSvc.h
new file mode 100644
index 000000000000..a9846bc315d3
--- /dev/null
+++ b/Event/xAOD/xAODCoreCnv/xAODCoreCnv/IROOTHeaderLoaderSvc.h
@@ -0,0 +1,34 @@
+// Dear emacs, this is -*- c++ -*-
+//
+// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+//
+#ifndef XAODCORECNV_IROOTHEADERLOADERSVC_H
+#define XAODCORECNV_IROOTHEADERLOADERSVC_H
+
+// Framework include(s).
+#include "GaudiKernel/IService.h"
+#include "GaudiKernel/StatusCode.h"
+
+namespace xAODMaker {
+
+   /// Interface to a helper service used for force-loading headers into ROOT
+   ///
+   /// This interface may never actually be used by anyone, but I didn't want
+   /// to introduce a service that would not have any interface whatsoever...
+   ///
+   /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+   ///
+   class IROOTHeaderLoaderSvc : public virtual IService {
+
+   public:
+      /// Declare an interface ID for the class
+      DeclareInterfaceID( xAODMaker::IROOTHeaderLoaderSvc, 1, 0 );
+
+      /// (Force-)Load one particular header
+      virtual StatusCode loadHeader( const std::string& headerName ) const = 0;
+
+   }; // class IROOTHeaderLoaderSvc
+
+} // namespace xAODMaker
+
+#endif // XAODCORECNV_IROOTHEADERLOADERSVC_H
-- 
GitLab


From e8a78300c930d8d80e37df70821838516ba969c9 Mon Sep 17 00:00:00 2001
From: Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
Date: Wed, 22 Jul 2020 15:24:05 +0200
Subject: [PATCH 2/3] Added xAODMaker::ROOTHeaderLoaderSvc to some relevant HLT
 jobOptions.

Only the ones that needed it to make the CI tests succeed. For every test
to succeed, it may need to be added in a few more places as well.
---
 .../TriggerJobOpts/share/decodeBS.py          | 12 ++++++++
 .../TriggerJobOpts/share/runHLT_standalone.py | 29 +++++++++++++------
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/decodeBS.py b/Trigger/TriggerCommon/TriggerJobOpts/share/decodeBS.py
index 1478eb45848f..dbcd0275982f 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/share/decodeBS.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/share/decodeBS.py
@@ -76,3 +76,15 @@ if len(ItemList) == 0:
     ItemList += [ 'xAOD::TrigCompositeAuxContainer#*' ]
 StreamESD.ItemList = list(set(ItemList))
 outSequence += StreamESD
+
+# Set up a temporary workaround for ROOT-10940 / ATR-21753.
+from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+from xAODCoreCnv.xAODCoreCnvConf import xAODMaker__ROOTHeaderLoaderSvc
+svcMgr += xAODMaker__ROOTHeaderLoaderSvc( 'ROOTHeaderLoaderSvc',
+            HeaderNames = [ 'xAODEgamma/PhotonContainer.h',
+                            'xAODTrigEgamma/TrigPhotonContainer.h',
+                            'xAODMuon/MuonContainer.h',
+                            'xAODTrigMuon/L2StandAloneMuonContainer.h',
+                            'xAODJet/JetContainer.h',
+                            'xAODTau/TauJetContainer.h' ] )
+theApp.CreateSvc += [ 'xAODMaker::ROOTHeaderLoaderSvc/ROOTHeaderLoaderSvc' ]
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py
index 8d4cc9c5028a..90c6ec693579 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py
@@ -83,7 +83,7 @@ for option in defaultOptions:
     if option in globals():
         setattr(opt, option, globals()[option])
         print(' %20s = %s' % (option, getattr(opt, option)))
-    else:        
+    else:
         print(' %20s = (Default) %s' % (option, getattr(opt, option)))
 
 
@@ -194,7 +194,7 @@ ConfigFlags.Trigger.enableL1CaloLegacy = opt.enableL1CaloLegacy
 
 # To turn off HLT for athena running
 TriggerFlags.doHLT = bool(opt.doHLT)
-    
+
 # To extract the Trigger configuration
 TriggerFlags.Online.doDBConfig = bool(opt.doDBConfig)
 if opt.trigBase is not None:
@@ -247,7 +247,7 @@ TriggerFlags.doCalo = opt.doCalo
 modifierList=[]
 from TrigConfigSvc.TrigConfMetaData import TrigConfMetaData
 meta = TrigConfMetaData()
-    
+
 for mod in dir(TriggerJobOpts.Modifiers):
     if not hasattr(getattr(TriggerJobOpts.Modifiers,mod),'preSetup'):
         continue
@@ -361,7 +361,7 @@ else:
     topSequence.SGInputLoader.Load += [( 'xAOD::EventInfo' , 'StoreGateSvc+EventInfo' )]
 
 # ----------------------------------------------------------------
-# Detector geometry 
+# Detector geometry
 # ----------------------------------------------------------------
 # Always enable AtlasFieldSvc
 from AthenaCommon.DetFlags import DetFlags
@@ -407,12 +407,12 @@ if globalflags.InputFormat.is_pool():
     import AthenaPoolCnvSvc.ReadAthenaPool   # noqa
     svcMgr.AthenaPoolCnvSvc.PoolAttributes = [ "DEFAULT_BUFFERSIZE = '2048'" ]
     svcMgr.PoolSvc.AttemptCatalogPatch=True
-    # enable transient BS 
+    # enable transient BS
     if TriggerFlags.doTransientByteStream():
         log.info("setting up transient BS")
         include( "TriggerJobOpts/jobOfragment_TransBS_standalone.py" )
-        
-     
+
+
 # ----------------------------------------------------------------
 # ByteStream input
 # ----------------------------------------------------------------
@@ -425,6 +425,17 @@ elif globalflags.InputFormat.is_bytestream() and not ConfigFlags.Trigger.Online.
     from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
     CAtoGlobalWrapper(ByteStreamReadCfg, ConfigFlags)
 
+# Set up a temporary workaround for ROOT-10940 / ATR-21753.
+from xAODCoreCnv.xAODCoreCnvConf import xAODMaker__ROOTHeaderLoaderSvc
+svcMgr += xAODMaker__ROOTHeaderLoaderSvc( 'ROOTHeaderLoaderSvc',
+            HeaderNames = [ 'xAODEgamma/PhotonContainer.h',
+                            'xAODTrigEgamma/TrigPhotonContainer.h',
+                            'xAODMuon/MuonContainer.h',
+                            'xAODTrigMuon/L2StandAloneMuonContainer.h',
+                            'xAODJet/JetContainer.h',
+                            'xAODTau/TauJetContainer.h' ] )
+theApp.CreateSvc += [ 'xAODMaker::ROOTHeaderLoaderSvc/ROOTHeaderLoaderSvc' ]
+
 # ---------------------------------------------------------------
 # Trigger config
 # ---------------------------------------------------------------
@@ -503,7 +514,7 @@ if not opt.createHLTMenuExternally:
     if (opt.selectChains):
         menu.selectChainsForTesting = opt.selectChains
 
-    # generating the HLT structure requires 
+    # generating the HLT structure requires
     # the L1Decoder to be defined in the topSequence
     menu.generateMT()
 
@@ -544,7 +555,7 @@ if hasattr(svcMgr.THistSvc, "Output"):
 
 #-------------------------------------------------------------
 # Conditions overrides
-#-------------------------------------------------------------    
+#-------------------------------------------------------------
 if len(opt.condOverride)>0:
     for folder,tag in opt.condOverride.iteritems():
         log.warning('Overriding folder %s with tag %s', folder, tag)
-- 
GitLab


From 983fbd6fda421f5b3e1870eb95352c3020fd515b Mon Sep 17 00:00:00 2001
From: Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
Date: Wed, 22 Jul 2020 15:24:57 +0200
Subject: [PATCH 3/3] Added some Doxygen documentation to the new service.

---
 Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
index efd547e0f8d5..b1ef58997762 100644
--- a/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
+++ b/Event/xAOD/xAODCoreCnv/src/ROOTHeaderLoaderSvc.h
@@ -18,6 +18,15 @@
 
 namespace xAODMaker {
 
+   /// Service implementing @c xAODMaker::IROOTHeaderLoaderSvc
+   ///
+   /// The service simply relies on @c TROOT::ProcessLine(...) to execute
+   /// '#include "headerName.h"' commands. Forcing ROOT to interpret those
+   /// headers during the job's initialisation. Allowing us to work around
+   /// ATR-21753 / ROOT-10940.
+   ///
+   /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+   ///
    class ROOTHeaderLoaderSvc : public extends< AthService,
                                                IROOTHeaderLoaderSvc > {
 
-- 
GitLab