diff --git a/Event/xAOD/xAODCore/CMakeLists.txt b/Event/xAOD/xAODCore/CMakeLists.txt index 72e0b5084ecf07ad325dd40bb320180570ed398d..df01b23be6f16156f386f7a7f70f59f8c4f558d3 100644 --- a/Event/xAOD/xAODCore/CMakeLists.txt +++ b/Event/xAOD/xAODCore/CMakeLists.txt @@ -6,7 +6,7 @@ atlas_subdir( xAODCore ) # Extra dependencies based on what environment we are in. set( extra_libs ) if( NOT XAOD_STANDALONE ) - set( extra_libs AthenaKernel ) + set( extra_libs AthenaKernel GaudiKernel) endif() # External dependencies. diff --git a/Event/xAOD/xAODCore/xAODCore/ShallowCopy.h b/Event/xAOD/xAODCore/xAODCore/ShallowCopy.h index ff9dfa596afe148402f3c3aa20ebdf9497bc05ac..ee60ecddaa6b52ecc4b37db54d3f384c636ecf10 100644 --- a/Event/xAOD/xAODCore/xAODCore/ShallowCopy.h +++ b/Event/xAOD/xAODCore/xAODCore/ShallowCopy.h @@ -1,7 +1,7 @@ // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ // $Id: ShallowCopy.h 766390 2016-08-04 11:18:59Z wlampl $ @@ -20,25 +20,110 @@ #include "xAODCore/ShallowAuxContainer.h" #include "xAODCore/ShallowAuxInfo.h" +#ifndef XAOD_STANDALONE +#include <GaudiKernel/ThreadLocalContext.h> +#else +class EventContext; +#endif + + namespace xAOD { /// Function to prepare an object to be stored in a shallow-copy container /// - /// To be used by shallowCopyContainer. The default implementation - /// here is dummy, just calling the default constructor. Can be - /// overloaded for types that require special treatment + /// To be used by shallowCopyContainer. The default implementation + /// here is dummy, just calling the default constructor. Can be + /// overloaded for types that require special treatment /// (like xAOD::CaloCluster) /// @param elem: Input object, ignored in this implementation - /// @returns A uniqe_ptr to the object to be push_back'ed into the - /// shallow-copy container. + /// @returns A uniqe_ptr to the object to be push_back'ed into the + /// shallow-copy container. template< class T > std::unique_ptr<T> prepareElementForShallowCopy(const T* /*elem*/) { return std::make_unique<T>(); } + namespace detail{ + /// Impl function for shallow copy container + /// @param cont The container to make a shallow copy of + /// @param ctx The currentEventContext + /// @returns A pair of unique_ptr to the created objects. + template<class T> + std::pair<std::unique_ptr<T>, std::unique_ptr<ShallowAuxContainer>> + shallowCopyContainerImpl(const T& cont, + DataLink<SG::IConstAuxStore>& link){ + + if (!link.cptr()) { + // This can happen when we read the input file in standalone + // mode in branch access mode. That's unfortunately not + // compatible with using a shallow copy auxiliary store. + std::cout << "xAOD::shallowCopyContainer ERROR Couldn't set up " + << "DataLink to the original container's auxiliary store" + << std::endl; + std::cout << "xAOD::shallowCopyContainer ERROR Are you using the " + << "xAOD::TEvent::kBranchAccess access mode?" << std::endl; + return {}; + } + + // Create the new DV container: + auto newCont = std::make_unique<T>(); + + // Add the required number of elements to it: + newCont->reserve(cont.size()); + for (size_t i = 0; i < cont.size(); ++i) { + newCont->push_back(prepareElementForShallowCopy(cont[i])); + } + + // Create a new shallow auxiliary container: + auto aux = std::make_unique<ShallowAuxContainer>(link); + + // Connect it to the interface container: + newCont->setStore(aux.get()); + + // Return the new objects: + return std::make_pair(std::move(newCont), std::move(aux)); + } + }//end namespace detail + + /// Function making a shallow copy of a constant container + /// + /// This function can be used to make a shallow copy of an existing + /// (constant) container. It is most useful when reading an input file, + /// and/or applying systematic variations on a container. + /// + /// @param cont The container to make a shallow copy of + /// @param ctx The currentEventContext + /// @returns A pair of unique_ptr to the created objects. + /// + /// In Analysis Base it can be still called by using + /// Gaudi::Hive::currentContext() as 2nd argument, + /// although in practice is ignored as we do not really have + /// an actual EventContext type. + /// + /// Be aware: If CONT has decorations, then the scheduler won't automatically + /// known that they are available on the copy. To make that happen, see + /// StoreGate/ShallowCopyDecorDeps.h. + + template<class T> + std::pair<std::unique_ptr<T>, std::unique_ptr<ShallowAuxContainer>> + shallowCopyContainer(const T& cont, + [[maybe_unused]] const EventContext& ctx + ){ +#ifndef XAOD_STANDALONE + DataLink<SG::IConstAuxStore> link (cont.getConstStore(), ctx); +#else + //Note that in AnalysisBase + //- EventContext, is not a complete type, we have no class. + //- We do not have a DataLink ctor with EventContext + //- The return value of currentContext() can not be used. + DataLink<SG::IConstAuxStore> link(cont.getConstStore()); +#endif + return detail::shallowCopyContainerImpl(cont,link); + } /// Function making a shallow copy of a constant container + // /// /// This function can be used to make a shallow copy of an existing /// (constant) container. It is most useful when reading an input file, @@ -54,40 +139,9 @@ namespace xAOD { /// template< class T > std::pair< T*, ShallowAuxContainer* > shallowCopyContainer( const T& cont ) { - - // Create a DataLink, to check if we'll be successful: - DataLink< SG::IConstAuxStore > link( cont.getConstStore() ); - if( ! link.cptr() ) { - // This can happen when we read the input file in standalone - // mode in branch access mode. That's unfortunately not - // compatible with using a shallow copy auxiliary store. - std::cout << "xAOD::shallowCopyContainer ERROR Couldn't set up " - << "DataLink to the original container's auxiliary store" - << std::endl; - std::cout << "xAOD::shallowCopyContainer ERROR Are you using the " - << "xAOD::TEvent::kBranchAccess access mode?" - << std::endl; - std::pair< T*, ShallowAuxContainer* > dummy; - return dummy; - } - - // Create the new DV container: - T* newCont = new T(); - - // Add the required number of elements to it: - newCont->reserve( cont.size() ); - for( size_t i = 0; i < cont.size(); ++i ) { - newCont->push_back(prepareElementForShallowCopy(cont[i])); - } - - // Create a new shallow auxiliary container: - ShallowAuxContainer* aux = new ShallowAuxContainer( link ); - - // Connect it to the interface container: - newCont->setStore( aux ); - - // Return the new objects: - return std::make_pair( newCont, aux ); + DataLink<SG::IConstAuxStore> link (cont.getConstStore()); + auto tmp = detail::shallowCopyContainerImpl(cont, link); + return std::make_pair(tmp.first.release(), tmp.second.release()); } /// Function making a shallow copy of a constant standalone object diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTopoClusterCopier.cxx b/Reconstruction/egamma/egammaAlgs/src/egammaTopoClusterCopier.cxx index 2edfc21b9dd962f05543d403c847339993e25bdd..36bc49ba3f8e418317f00f9531f48a07182108da 100644 --- a/Reconstruction/egamma/egammaAlgs/src/egammaTopoClusterCopier.cxx +++ b/Reconstruction/egamma/egammaAlgs/src/egammaTopoClusterCopier.cxx @@ -62,11 +62,14 @@ StatusCode egammaTopoClusterCopier::execute(const EventContext& ctx) const { /* Create a shallow copy, the elements of this can be modified, * but no need to recreate the cluster */ - std::pair<xAOD::CaloClusterContainer*, xAOD::ShallowAuxContainer*> - inputShallowcopy = xAOD::shallowCopyContainer(*inputTopoclusters); + std::pair<std::unique_ptr<xAOD::CaloClusterContainer>, + std::unique_ptr<xAOD::ShallowAuxContainer>> + inputShallowcopy = xAOD::shallowCopyContainer(*inputTopoclusters, ctx); + + + ATH_CHECK(outputTopoclustersShallow.record(std::move(inputShallowcopy.first), + std::move(inputShallowcopy.second))); - ATH_CHECK( outputTopoclustersShallow.record(std::unique_ptr<xAOD::CaloClusterContainer>(inputShallowcopy.first), - std::unique_ptr<xAOD::ShallowAuxContainer>(inputShallowcopy.second)) ); /* * Here it just needs to be a view copy, * i.e the collection we create does not really