From 17a62c7b981d04a2ee9d9670fe5e2c20830fe667 Mon Sep 17 00:00:00 2001 From: Tadej Novak Date: Wed, 18 May 2022 16:21:06 +0200 Subject: [PATCH] Add HGTD overlay placeholder algorithm --- .../python/HGTD_DigitizationConfig.py | 50 +- .../src/HGTD_Digitization.cxx | 28 + .../HGTD_Digitization/src/HGTD_Digitization.h | 28 + .../components/HGTD_Digitization_entries.cxx | 2 + .../HGTD_Overlay/CMakeLists.txt | 32 ++ .../HGTD_Overlay/python/HGTD_OverlayConfig.py | 82 +++ .../src/ATLAS_CHECK_THREAD_SAFETY | 1 + .../HGTD_Overlay/src/HGTD_Overlay.cxx | 104 ++++ .../HGTD_Overlay/src/HGTD_Overlay.h | 27 + .../src/components/HGTD_Overlay_entries.cxx | 3 + .../test/HGTD_OverlayConfig_test.py | 45 ++ .../HGTD_Overlay/test/HGTD_Overlay_test.cxx | 539 ++++++++++++++++++ .../python/OverlaySteering.py | 5 + 13 files changed, 938 insertions(+), 8 deletions(-) create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.cxx create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.h create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/CMakeLists.txt create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/python/HGTD_OverlayConfig.py create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/ATLAS_CHECK_THREAD_SAFETY create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.cxx create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.h create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/components/HGTD_Overlay_entries.cxx create mode 100755 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_OverlayConfig_test.py create mode 100644 HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_Overlay_test.cxx diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/python/HGTD_DigitizationConfig.py b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/python/HGTD_DigitizationConfig.py index 5eda39f0c71..371432ada1d 100644 --- a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/python/HGTD_DigitizationConfig.py +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/python/HGTD_DigitizationConfig.py @@ -28,12 +28,14 @@ def HGTD_TimingResolutionCfg(flags, name="HGTD_TimingResolution", **kwargs): acc.setPrivateTools(CompFactory.HGTD_TimingResolution(name, **kwargs)) return acc + def HGTD_FrontEndToolCfg(flags, name="HGTD_FrontEndTool", **kwargs): acc = ComponentAccumulator() acc.setPrivateTools(CompFactory.HGTD_FrontEndTool(name, **kwargs)) return acc + def HGTD_SurfaceChargesGeneratorCfg(flags, name="HGTD_SurfaceChargesGenerator", **kwargs): acc = ComponentAccumulator() @@ -43,6 +45,7 @@ def HGTD_SurfaceChargesGeneratorCfg(flags, name="HGTD_SurfaceChargesGenerator", acc.setPrivateTools(CompFactory.HGTD_SurfaceChargesGenerator(name, **kwargs)) return acc + def HGTD_DigitizationBasicToolCfg(flags, name="HGTD_DigitizationBasicTool", **kwargs): """Return ComponentAccumulator with configured HGTD_DigitizationTool""" acc = HGTD_ReadoutGeometryCfg(flags) @@ -60,6 +63,7 @@ def HGTD_DigitizationBasicToolCfg(flags, name="HGTD_DigitizationBasicTool", **kw acc.setPrivateTools(CompFactory.HGTD_DigitizationTool(name, **kwargs)) return acc + def HGTD_DigitizationToolCfg(flags, name="HGTD_DigitizationTool", **kwargs): """Return ComponentAccumulator with configured HGTD_DigitizationBasicTool""" acc = ComponentAccumulator() @@ -69,17 +73,25 @@ def HGTD_DigitizationToolCfg(flags, name="HGTD_DigitizationTool", **kwargs): intervals += [acc.popToolsAndMerge(HGTD_RangeCfg(flags))] kwargs.setdefault("MergeSvc", acc.getPrimaryAndMerge(PileUpMergeSvcCfg(flags, Intervals=intervals)).name) else: - kwargs.setdefault("MergeSvc", '') + kwargs.setdefault("MergeSvc", "") kwargs.setdefault("OnlyUseContainerName", flags.Digitization.PileUp) if flags.Common.ProductionStep == ProductionStep.PileUpPresampling: - kwargs.setdefault("OutputObjectName", flags.Overlay.BkgPrefix + "HGTD_RDOs") - kwargs.setdefault("OutputSDOName", flags.Overlay.BkgPrefix + "HGTD_SDO_Map") + kwargs.setdefault("OutputObjectName", f"{flags.Overlay.BkgPrefix}HGTD_RDOs") + kwargs.setdefault("OutputSDOName", f"{flags.Overlay.BkgPrefix}HGTD_SDO_Map") else: kwargs.setdefault("OutputObjectName", "HGTD_RDOs") kwargs.setdefault("OutputSDOName", "HGTD_SDO_Map") - tool = acc.popToolsAndMerge(HGTD_DigitizationBasicToolCfg(flags, name, **kwargs)) - acc.setPrivateTools(tool) - return acc + return HGTD_DigitizationBasicToolCfg(flags, name, **kwargs) + + +def HGTD_OverlayDigitizationToolCfg(flags, name="HGTD_OverlayDigitizationTool", **kwargs): + """Return ComponentAccumulator with HGTD_DigitizationTool configured for overlay""" + kwargs.setdefault("OnlyUseContainerName", False) + kwargs.setdefault("OutputObjectName", f"{flags.Overlay.SigPrefix}HGTD_RDOs") + kwargs.setdefault("OutputSDOName", f"{flags.Overlay.SigPrefix}HGTD_SDO_Map") + kwargs.setdefault("MergeSvc", "") + return HGTD_DigitizationBasicToolCfg(flags, name, **kwargs) + def HGTD_RangeCfg(flags, name="HGTD_Range", **kwargs): """Return a configured PileUpXingFolder tool""" @@ -89,6 +101,7 @@ def HGTD_RangeCfg(flags, name="HGTD_Range", **kwargs): kwargs.setdefault("ItemList", ["SiHitCollection#HGTD_Hits"]) return PileUpXingFolderCfg(flags, name, **kwargs) + def HGTD_OutputCfg(flags): """Return ComponentAccumulator with Output for HGTD. Not standalone.""" acc = ComponentAccumulator() @@ -100,15 +113,36 @@ def HGTD_OutputCfg(flags): acc.merge(OutputStreamCfg(flags, "RDO", ItemList)) return acc + def HGTD_DigitizationBasicCfg(flags, **kwargs): """Return ComponentAccumulator for HGTD digitization""" acc = ComponentAccumulator() if "PileUpTools" not in kwargs: - PileUpTools = acc.popToolsAndMerge(HGTD_DigitizationToolCfg(flags)) - kwargs["PileUpTools"] = PileUpTools + kwargs["PileUpTools"] = acc.popToolsAndMerge(HGTD_DigitizationToolCfg(flags)) acc.merge(PileUpToolsCfg(flags, **kwargs)) return acc + +def HGTD_OverlayDigitizationBasicCfg(flags, **kwargs): + """Return ComponentAccumulator with HGTD Overlay digitization""" + acc = ComponentAccumulator() + if flags.Common.ProductionStep != ProductionStep.FastChain: + from SGComps.SGInputLoaderConfig import SGInputLoaderCfg + acc.merge(SGInputLoaderCfg(flags, ["SiHitCollection#HGTD_Hits"])) + + if "DigitizationTool" not in kwargs: + kwargs["DigitizationTool"] = acc.popToolsAndMerge(HGTD_OverlayDigitizationToolCfg(flags)) + + if flags.Concurrency.NumThreads > 0: + kwargs.setdefault("Cardinality", flags.Concurrency.NumThreads) + + # Set common overlay extra inputs + kwargs.setdefault("ExtraInputs", flags.Overlay.ExtraInputs) + + acc.addEventAlgo(CompFactory.HGTD_Digitization(name="HGTD_OverlayDigitization", **kwargs)) + return acc + + # with output defaults def HGTD_DigitizationCfg(flags, **kwargs): """Return ComponentAccumulator for HGTD digitization and Output""" diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.cxx b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.cxx new file mode 100644 index 00000000000..24c70134c06 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.cxx @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + */ + +#include "HGTD_Digitization.h" + + +HGTD_Digitization::HGTD_Digitization(const std::string &name, + ISvcLocator *pSvcLocator) + : AthAlgorithm(name, pSvcLocator) +{ +} + + +StatusCode HGTD_Digitization::initialize() +{ + ATH_MSG_DEBUG("initialize()"); + ATH_CHECK(m_HGTD_DigitizationTool.retrieve()); + ATH_MSG_DEBUG("Successfully retreived HGTD digitization tool."); + return StatusCode::SUCCESS; +} + + +StatusCode HGTD_Digitization::execute() +{ + ATH_MSG_DEBUG("execute()"); + return m_HGTD_DigitizationTool->processAllSubEvents(Gaudi::Hive::currentContext()); +} diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.h b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.h new file mode 100644 index 00000000000..6f9b519f56e --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/HGTD_Digitization.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef HGTDDIGITIZATION_HGTDDIGITIZATION_H +#define HGTDDIGITIZATION_HGTDDIGITIZATION_H + +#include +#include +#include + + +class HGTD_Digitization : public AthAlgorithm +{ +public: + HGTD_Digitization(const std::string &name, ISvcLocator *pSvcLocator); + virtual ~HGTD_Digitization() = default; + virtual StatusCode initialize() override final; + virtual StatusCode execute() override final; + virtual bool isClonable() const override final { return true; } + +private: + ToolHandle m_HGTD_DigitizationTool { + this, "DigitizationTool", "HGTD_DigitizationTool", "HGTD_DigitizationTool name" + }; +}; + +#endif // HGTDDIGITIZATION_HGTDDIGITIZATION_H diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/components/HGTD_Digitization_entries.cxx b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/components/HGTD_Digitization_entries.cxx index 8c1b59c1e08..f88eb4df4fa 100644 --- a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/components/HGTD_Digitization_entries.cxx +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Digitization/src/components/HGTD_Digitization_entries.cxx @@ -1,8 +1,10 @@ +#include "../HGTD_Digitization.h" #include "../HGTD_DigitizationTool.h" #include "../HGTD_FrontEndTool.h" #include "../HGTD_SurfaceChargesGenerator.h" #include "../HGTD_TimingResolution.h" +DECLARE_COMPONENT(HGTD_Digitization) DECLARE_COMPONENT(HGTD_DigitizationTool) DECLARE_COMPONENT(HGTD_FrontEndTool) DECLARE_COMPONENT(HGTD_SurfaceChargesGenerator) diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/CMakeLists.txt b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/CMakeLists.txt new file mode 100644 index 00000000000..4804c363eb6 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + +# Declare the package name: +atlas_subdir( HGTD_Overlay ) + +# External dependencies: +find_package( CLHEP ) +find_package( GTest ) +find_package( GMock ) + +# Unit Tests +atlas_add_test( HGTD_Overlay_test + SOURCES test/HGTD_Overlay_test.cxx src/HGTD_Overlay.cxx + INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} + LINK_LIBRARIES ${GTEST_LIBRARIES} CxxUtils IDC_OverlayBase HGTD_RawData StoreGateLib TestTools + POST_EXEC_SCRIPT nopost.sh ) + +# Component(s) in the package: +atlas_add_component( HGTD_Overlay + src/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel AtlasHepMCLib GaudiKernel IDC_OverlayBase HGTD_RawData ) + +# Install files from the package: +atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) + +# Configuration tests +# TODO: to be enabled once we have reasonable inputs +# atlas_add_test( HGTD_OverlayConfig_test +# SCRIPT test/HGTD_OverlayConfig_test.py +# POST_EXEC_SCRIPT nopost.sh ) diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/python/HGTD_OverlayConfig.py b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/python/HGTD_OverlayConfig.py new file mode 100644 index 00000000000..cf975a88b81 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/python/HGTD_OverlayConfig.py @@ -0,0 +1,82 @@ +"""Define methods to construct configured HGTD overlay algorithms + +Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +""" + +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory + + +def HGTD_OverlayAlgCfg(flags, name="HGTD_Overlay", **kwargs): + """Return a ComponentAccumulator for HGTD overlay algorithm""" + acc = ComponentAccumulator() + + kwargs.setdefault("BkgInputKey", f"{flags.Overlay.BkgPrefix}HGTD_RDOs") + kwargs.setdefault("SignalInputKey", f"{flags.Overlay.SigPrefix}HGTD_RDOs") + kwargs.setdefault("OutputKey", "HGTD_RDOs") + + if not flags.Overlay.DataOverlay: + from SGComps.SGInputLoaderConfig import SGInputLoaderCfg + acc.merge(SGInputLoaderCfg(flags, [f'HGTD_RDO_Container#{kwargs["BkgInputKey"]}'])) + + # Do HGTD overlay + acc.addEventAlgo(CompFactory.HGTD_Overlay(name, **kwargs)) + + # Setup output + if flags.Output.doWriteRDO: + from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + acc.merge(OutputStreamCfg(flags, "RDO", ItemList=[ + "HGTD_RDO_Container#HGTD_RDOs" + ])) + + if flags.Output.doWriteRDO_SGNL: + from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + acc.merge(OutputStreamCfg(flags, "RDO_SGNL", ItemList=[ + f"HGTD_RDO_Container#{flags.Overlay.SigPrefix}HGTD_RDOs" + ])) + + return acc + + +def HGTD_TruthOverlayCfg(flags, name="HGTD_SDOOverlay", **kwargs): + """Return a ComponentAccumulator for the HGTD SDO overlay algorithm""" + acc = ComponentAccumulator() + + # We do not need background Pixel SDOs + kwargs.setdefault("BkgInputKey", "") + + kwargs.setdefault("SignalInputKey", f"{flags.Overlay.SigPrefix}HGTD_SDO_Map") + kwargs.setdefault("OutputKey", "HGTD_SDO_Map") + + # Do Pixel truth overlay + acc.addEventAlgo(CompFactory.InDetSDOOverlay(name, **kwargs)) + + # Setup output + if flags.Output.doWriteRDO: + from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + acc.merge(OutputStreamCfg(flags, "RDO", ItemList=[ + "InDetSimDataCollection#HGTD_SDO_Map" + ])) + + if flags.Output.doWriteRDO_SGNL: + from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + acc.merge(OutputStreamCfg(flags, "RDO_SGNL", ItemList=[ + f"InDetSimDataCollection#{flags.Overlay.SigPrefix}HGTD_SDO_Map" + ])) + + return acc + + +def HGTD_OverlayCfg(flags): + """Configure and return a ComponentAccumulator for HGTD overlay""" + acc = ComponentAccumulator() + + # Add HGTD overlay digitization algorithm + from HGTD_Digitization.HGTD_DigitizationConfig import HGTD_OverlayDigitizationBasicCfg + acc.merge(HGTD_OverlayDigitizationBasicCfg(flags)) + # Add HGTD overlay algorithm + acc.merge(HGTD_OverlayAlgCfg(flags)) + # Add HGTD truth overlay + acc.merge(HGTD_TruthOverlayCfg(flags)) + + return acc diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/ATLAS_CHECK_THREAD_SAFETY b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/ATLAS_CHECK_THREAD_SAFETY new file mode 100644 index 00000000000..0a346b95a70 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/ATLAS_CHECK_THREAD_SAFETY @@ -0,0 +1 @@ +HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.cxx b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.cxx new file mode 100644 index 00000000000..2c4ca4d22f5 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.cxx @@ -0,0 +1,104 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#include "HGTD_Overlay.h" + +#include + + +namespace Overlay +{ + // Specialize mergeChannelData() for the HGTD + template <> + void mergeChannelData(HGTD_RDO &/* baseDatum */, + const HGTD_RDO &/* additionalDatum */, + const IDC_OverlayBase *algorithm) + { + algorithm->msg(MSG::DEBUG) << "Overlay::mergeChannelData(): " + << "Merging of data on the same channel is not explicitly implemented for HGTD_RDORawData" << endmsg; + } + + // Specialize copyCollection() for the HGTD + template<> + std::unique_ptr copyCollection(const IdentifierHash &hashId, + const HGTD_RDO_Collection *collection) + { + auto outputCollection = std::make_unique(hashId); + outputCollection->setIdentifier(collection->identify()); + + for (const HGTD_RDO *existingDatum : *collection) { + // Owned by the collection + auto *datumCopy = new HGTD_RDO(existingDatum->identify(), existingDatum->getTOA(), existingDatum->getTOT(), + existingDatum->getBCID(), existingDatum->getL1ID(), existingDatum->getL1A()); + outputCollection->push_back(datumCopy); + } + + return outputCollection; + } +} // namespace Overlay + + +HGTD_Overlay::HGTD_Overlay(const std::string &name, ISvcLocator *pSvcLocator) + : IDC_OverlayBase(name, pSvcLocator) +{ +} + +StatusCode HGTD_Overlay::initialize() +{ + ATH_MSG_DEBUG("Initializing..."); + + // Check and initialize keys + ATH_CHECK( m_bkgInputKey.initialize(!m_bkgInputKey.key().empty()) ); + ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_bkgInputKey); + ATH_CHECK( m_signalInputKey.initialize() ); + ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_signalInputKey); + ATH_CHECK( m_outputKey.initialize() ); + ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputKey); + + return StatusCode::SUCCESS; +} + +StatusCode HGTD_Overlay::execute(const EventContext& ctx) const +{ + ATH_MSG_DEBUG("execute() begin"); + + // Reading the input RDOs + ATH_MSG_VERBOSE("Retrieving input RDO containers"); + + const HGTD_RDO_Container *bkgContainerPtr = nullptr; + if (!m_bkgInputKey.empty()) { + SG::ReadHandle bkgContainer(m_bkgInputKey, ctx); + if (!bkgContainer.isValid()) { + ATH_MSG_ERROR("Could not get background HGTD RDO container " << bkgContainer.name() << " from store " << bkgContainer.store()); + return StatusCode::FAILURE; + } + bkgContainerPtr = bkgContainer.cptr(); + + ATH_MSG_DEBUG("Found background HGTD RDO container " << bkgContainer.name() << " in store " << bkgContainer.store()); + ATH_MSG_DEBUG("HGTD Background = " << Overlay::debugPrint(bkgContainer.cptr())); + } + + SG::ReadHandle signalContainer(m_signalInputKey, ctx); + if (!signalContainer.isValid()) { + ATH_MSG_ERROR("Could not get signal HGTD RDO container " << signalContainer.name() << " from store " << signalContainer.store()); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Found signal HGTD RDO container " << signalContainer.name() << " in store " << signalContainer.store()); + ATH_MSG_DEBUG("HGTD Signal = " << Overlay::debugPrint(signalContainer.cptr())); + + // Creating output RDO container + SG::WriteHandle outputContainer(m_outputKey, ctx); + ATH_CHECK(outputContainer.record(std::make_unique(signalContainer->size()))); + if (!outputContainer.isValid()) { + ATH_MSG_ERROR("Could not record output HGTD RDO container " << outputContainer.name() << " to store " << outputContainer.store()); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Recorded output HGTD RDO container " << outputContainer.name() << " in store " << outputContainer.store()); + + ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr())); + ATH_MSG_DEBUG("HGTD Result = " << Overlay::debugPrint(outputContainer.ptr())); + + ATH_MSG_DEBUG("execute() end"); + return StatusCode::SUCCESS; +} diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.h b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.h new file mode 100644 index 00000000000..12ccfaad154 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/HGTD_Overlay.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef HGTDOVERLAY_HGTDOVERLAY_H +#define HGTDOVERLAY_HGTDOVERLAY_H + +#include +#include + + +class HGTD_Overlay : public IDC_OverlayBase +{ +public: + + HGTD_Overlay(const std::string &name, ISvcLocator *pSvcLocator); + + virtual StatusCode initialize() override final; + virtual StatusCode execute(const EventContext& ctx) const override final; + +private: + SG::ReadHandleKey m_bkgInputKey{ this, "BkgInputKey", "Bkg_HGTD_RDOs", "ReadHandleKey for Background Input HGTD_RDO_Container" }; + SG::ReadHandleKey m_signalInputKey{ this, "SignalInputKey", "Sig_HGTD_RDOs", "ReadHandleKey for Signal Input HGTD_RDO_Container" }; + SG::WriteHandleKey m_outputKey{ this, "OutputKey", "HGTD_RDOs", "WriteHandleKey for Output HGTD_RDO_Container" }; +}; + +#endif // HGTDOVERLAY_HGTDOVERLAY_H diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/components/HGTD_Overlay_entries.cxx b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/components/HGTD_Overlay_entries.cxx new file mode 100644 index 00000000000..7156260eb9a --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/src/components/HGTD_Overlay_entries.cxx @@ -0,0 +1,3 @@ +#include "../HGTD_Overlay.h" + +DECLARE_COMPONENT( HGTD_Overlay ) diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_OverlayConfig_test.py b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_OverlayConfig_test.py new file mode 100755 index 00000000000..728983074bb --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_OverlayConfig_test.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +"""Run tests on HGTD_OverlayConfig.py + +Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +""" +import sys + +from AthenaCommon.Configurable import Configurable +from AthenaConfiguration.AllConfigFlags import ConfigFlags +from AthenaConfiguration.MainServicesConfig import MainServicesCfg +from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg +from HGTD_Overlay.HGTD_OverlayConfig import HGTD_OverlayCfg +from OverlayConfiguration.OverlayTestHelpers import \ + CommonTestArgumentParser, defaultTestFlags, postprocessAndLockFlags, printAndRun +from OverlayCopyAlgs.OverlayCopyAlgsConfig import CopyMcEventCollectionCfg +from xAODEventInfoCnv.xAODEventInfoCnvConfig import EventInfoOverlayCfg + +# Configure +Configurable.configurableRun3Behavior = True + +# Argument parsing +parser = CommonTestArgumentParser("HGTD_OverlayConfig_test.py") +args = parser.parse_args() + +# Configure +defaultTestFlags(ConfigFlags, args) +postprocessAndLockFlags(ConfigFlags, args) + +# Construct our accumulator to run +acc = MainServicesCfg(ConfigFlags) +acc.merge(PoolReadCfg(ConfigFlags)) + +# Add event and truth overlay (needed downstream) +acc.merge(EventInfoOverlayCfg(ConfigFlags)) +acc.merge(CopyMcEventCollectionCfg(ConfigFlags)) + +# Add HGTD overlay +acc.merge(HGTD_OverlayCfg(ConfigFlags)) + +# Dump the pickle +with open("HGTD_OverlayCfg.pkl", "wb") as f: + acc.store(f) + +# Print and run +sys.exit(printAndRun(acc, ConfigFlags, args)) diff --git a/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_Overlay_test.cxx b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_Overlay_test.cxx new file mode 100644 index 00000000000..d219d478db7 --- /dev/null +++ b/HighGranularityTimingDetector/HGTD_Digitization/HGTD_Overlay/test/HGTD_Overlay_test.cxx @@ -0,0 +1,539 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @brief Tests for HGTD_Overlay. + */ + +#undef NDEBUG + +// Framework +#include "TestTools/initGaudi.h" + +// Google Test +#include "gtest/gtest.h" + +// Tested AthAlgorithm +#include "../src/HGTD_Overlay.h" + +#include "CxxUtils/checker_macros.h" +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; // Use of global g_svcLoc is not thread safe. + +namespace OverlayTesting +{ + + // needed every time an AthAlgorithm, AthAlgTool or AthService is instantiated + ISvcLocator *g_svcLoc = nullptr; + + // global test environment takes care of setting up Gaudi + class GaudiEnvironment : public ::testing::Environment { + protected: + virtual void SetUp() override { + Athena_test::initGaudi(OverlayTesting::g_svcLoc); + } + }; + + class HGTD_Overlay_test : public ::testing::Test { + + protected: + virtual void SetUp() override { + m_alg = new HGTD_Overlay{"HGTD_Overlay", g_svcLoc}; + ASSERT_TRUE( g_svcLoc->service("StoreGateSvc", m_sg) ); + } + + virtual void TearDown() override { + ASSERT_TRUE( m_alg->finalize().isSuccess() ); + delete m_alg; + ASSERT_TRUE( m_sg->clearStore().isSuccess() ); + } + + HGTD_Overlay *m_alg{}; + StoreGateSvc *m_sg{}; + }; // HGTD_Overlay_test fixture + + + TEST_F(HGTD_Overlay_test, set_properties) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isFailure() ); //inputs don't exist + } + + TEST_F(HGTD_Overlay_test, empty_containers_alg_execute) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG"}; + const unsigned int containerSize(1188); + inputSigDataHandle = std::make_unique(containerSize); + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG"}; + inputBkgDataHandle = std::make_unique(containerSize); + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + } + + TEST_F(HGTD_Overlay_test, containers_with_matching_empty_collections) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG1"}; + const unsigned int containerSize(1188); + IdentifierHash sigElementHash(1); + IdentifierHash bkgElementHash(1); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG1"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG1'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG1'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs1'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs1"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->empty() ); + } + + TEST_F(HGTD_Overlay_test, containers_with_different_empty_collections) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG2"}; + const unsigned int containerSize(1188); + IdentifierHash sigElementHash(1); + IdentifierHash bkgElementHash(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG2"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG2'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG2'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs2'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs2"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection1 = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection1!=nullptr ); + ASSERT_TRUE( outputCollection1->empty() ); + const HGTD_RDO_Collection *outputCollection2 = outputDataHandle->indexFindPtr(bkgElementHash); + ASSERT_TRUE( outputCollection2!=nullptr ); + ASSERT_TRUE( outputCollection2->empty() ); + } + + TEST_F(HGTD_Overlay_test, containers_with_matching_collections_one_with_an_RDO) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG3"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const unsigned int sigTOT(10); + const unsigned int sigBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG3"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG3'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG3'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs3'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs3"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection1 = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection1!=nullptr ); + ASSERT_TRUE( outputCollection1->size()==1 ); + const HGTD_RDO *outputDigit1 = outputCollection1->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==sigTOA ); + ASSERT_TRUE( outputDigit1->getTOT()==sigTOT ); + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); + } + + TEST_F(HGTD_Overlay_test, containers_with_different_collections_one_RDO_each) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG4"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(2); + const float sigTOA(1.23); + const float bkgTOA(1.23); + const unsigned int sigTOT(10); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(2); + const unsigned int bkgBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG4"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(12),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG4'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG4'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs4'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs4"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection1 = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection1!=nullptr ); + ASSERT_TRUE( outputCollection1->size()==1 ); + const HGTD_RDO *outputDigit1 = outputCollection1->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==sigTOA ); + ASSERT_TRUE( outputDigit1->getTOT()==sigTOT ); + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); + const HGTD_RDO_Collection *outputCollection2 = outputDataHandle->indexFindPtr(bkgElementHash); + ASSERT_TRUE( outputCollection2!=nullptr ); + ASSERT_TRUE( outputCollection2->size()==1 ); + const HGTD_RDO *outputDigit2 = outputCollection2->at(0); + ASSERT_TRUE( outputDigit2!=nullptr ); + ASSERT_TRUE( outputDigit2->getTOA()==bkgTOA ); + ASSERT_TRUE( outputDigit2->getTOT()==bkgTOT ); + ASSERT_TRUE( outputDigit2->getBCID()==bkgBCID-1 ); + } + + TEST_F(HGTD_Overlay_test, containers_with_matching_collections_one_different_RDO_each) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG5"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const float bkgTOA(3.21); + const unsigned int sigTOT(11); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(1); + const unsigned int bkgBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG5"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(13),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG5'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG5'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs5'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs5"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->size()==2 ); + const HGTD_RDO *outputDigit1 = outputCollection->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==sigTOA ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit1->getTOT()==sigTOT ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); // RDOs in same collection sorted according to Identifier + const HGTD_RDO *outputDigit2 = outputCollection->at(1); + ASSERT_TRUE( outputDigit2!=nullptr ); + ASSERT_TRUE( outputDigit2->getTOA()==bkgTOA ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit2->getTOT()==bkgTOT ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit2->getBCID()==bkgBCID-1 ); // RDOs in same collection sorted according to Identifier + } + + TEST_F(HGTD_Overlay_test, containers_with_matching_collections_one_matching_RDO_each) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG6"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const float bkgTOA(1.23); + const unsigned int sigTOT(10); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(2); + const unsigned int bkgBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG6"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(12),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG6'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG6'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs6'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs6"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->size()==1 ); + const HGTD_RDO *outputDigit1 = outputCollection->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==bkgTOA ); // Bkg RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getTOT()==bkgTOT ); // Bkg RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getBCID()==bkgBCID-1 ); // Bkg RDO taken in case of matching Identifiers + } + + TEST_F(HGTD_Overlay_test, two_RDOs_with_matching_id_signal_first) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG7"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const float bkgTOA(3.21); + const unsigned int sigTOT(11); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(1); + const unsigned int bkgBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG7"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(12),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG7'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG7'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs7'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs7"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->size()==1 ); + const HGTD_RDO *outputDigit1 = outputCollection->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==sigTOA ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getTOT()==sigTOT ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); // Signal RDO taken in case of matching Identifiers + } + + TEST_F(HGTD_Overlay_test, two_RDOs_with_matching_id_bkg_first) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG8"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const float bkgTOA(3.21); + const unsigned int sigTOT(11); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(2); + const unsigned int bkgBCID(1); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(12),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG8"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(12),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG8'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG8'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs8'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs8"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->size()==1 ); + const HGTD_RDO *outputDigit1 = outputCollection->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==sigTOA ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getTOT()==sigTOT ); // Signal RDO taken in case of matching Identifiers + ASSERT_TRUE( outputDigit1->getBCID()==sigBCID-1 ); // Signal RDO taken in case of matching Identifiers + } + + TEST_F(HGTD_Overlay_test, containers_with_matching_collections_one_different_RDO_each_v2) { + EventContext ctx(0,0); + ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) ); + SG::WriteHandle inputSigDataHandle{"StoreGateSvc+HGTD_RDOs_SIG9"}; + const unsigned int containerSize(1188); + const IdentifierHash sigElementHash(1); + const IdentifierHash bkgElementHash(1); + const float sigTOA(1.23); + const float bkgTOA(3.21); + const unsigned int sigTOT(11); + const unsigned int bkgTOT(10); + const unsigned int sigBCID(1); + const unsigned int bkgBCID(2); + inputSigDataHandle = std::make_unique(containerSize); + std::unique_ptr sigCollection = std::make_unique(sigElementHash); + //Add a HGTD_RDO object + std::unique_ptr sigDigit = std::make_unique(Identifier(13),sigTOA,sigTOT,sigBCID-1,0,sigBCID-1); + sigCollection->push_back(sigDigit.release()); + ASSERT_TRUE(inputSigDataHandle->addCollection(sigCollection.get(),sigElementHash).isSuccess()); + sigCollection.release(); // Now owned by inputSigDataHandle + SG::WriteHandle inputBkgDataHandle{"StoreGateSvc+HGTD_RDOs_BKG9"}; + inputBkgDataHandle = std::make_unique(containerSize); + std::unique_ptr bkgCollection = std::make_unique(bkgElementHash); + //Add a HGTD_RDO object + std::unique_ptr bkgDigit = std::make_unique(Identifier(12),bkgTOA,bkgTOT,bkgBCID-1,0,bkgBCID-1); + bkgCollection->push_back(bkgDigit.release()); + ASSERT_TRUE(inputBkgDataHandle->addCollection(bkgCollection.get(),bkgElementHash).isSuccess()); + bkgCollection.release(); // Now owned by inputBkgDataHandle + + // ordering A, C, B is on purpose to test for unintended alphabetic ordering + std::string inputSigPropertyValue = "'StoreGateSvc+HGTD_RDOs_SIG9'"; + std::string inputBkgPropertyValue = "'StoreGateSvc+HGTD_RDOs_BKG9'"; + std::string outputPropertyValue = "'StoreGateSvc+HGTD_RDOs9'"; + ASSERT_TRUE( m_alg->setProperty( "SignalInputKey", inputSigPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "BkgInputKey", inputBkgPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() ); + ASSERT_TRUE( m_alg->initialize().isSuccess() ); + ASSERT_TRUE( m_alg->execute(ctx).isSuccess() ); + // check output makes sense + SG::ReadHandle outputDataHandle{"StoreGateSvc+HGTD_RDOs9"}; + ASSERT_TRUE( outputDataHandle.isValid() ); + const HGTD_RDO_Collection *outputCollection = outputDataHandle->indexFindPtr(sigElementHash); + ASSERT_TRUE( outputCollection!=nullptr ); + ASSERT_TRUE( outputCollection->size()==2 ); + const HGTD_RDO *outputDigit1 = outputCollection->at(0); + ASSERT_TRUE( outputDigit1!=nullptr ); + ASSERT_TRUE( outputDigit1->getTOA()==bkgTOA ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit1->getTOT()==bkgTOT ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit1->getBCID()==bkgBCID-1 ); // RDOs in same collection sorted according to Identifier + const HGTD_RDO *outputDigit2 = outputCollection->at(1); + ASSERT_TRUE( outputDigit2!=nullptr ); + ASSERT_TRUE( outputDigit2->getTOA()==sigTOA ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit2->getTOT()==sigTOT ); // RDOs in same collection sorted according to Identifier + ASSERT_TRUE( outputDigit2->getBCID()==sigBCID-1 ); // RDOs in same collection sorted according to Identifier + } + +} // <-- namespace OverlayTesting + + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest( &argc, argv ); + ::testing::AddGlobalTestEnvironment( new OverlayTesting::GaudiEnvironment ); + return RUN_ALL_TESTS(); +} diff --git a/Simulation/Overlay/OverlayConfiguration/python/OverlaySteering.py b/Simulation/Overlay/OverlayConfiguration/python/OverlaySteering.py index 08bafaff36a..818ead92293 100644 --- a/Simulation/Overlay/OverlayConfiguration/python/OverlaySteering.py +++ b/Simulation/Overlay/OverlayConfiguration/python/OverlaySteering.py @@ -16,6 +16,7 @@ from InDetOverlay.ITkStripOverlayConfig import ITkStripOverlayCfg from InDetOverlay.PixelOverlayConfig import PixelOverlayCfg from InDetOverlay.SCTOverlayConfig import SCTOverlayCfg from InDetOverlay.TRTOverlayConfig import TRTOverlayCfg +from HGTD_Overlay.HGTD_OverlayConfig import HGTD_OverlayCfg from LArDigitization.LArDigitizationConfigNew import LArOverlayCfg, LArSuperCellOverlayCfg from MuonConfig.CSC_OverlayConfig import CSC_OverlayCfg from MuonConfig.MDT_OverlayConfig import MDT_OverlayCfg @@ -81,6 +82,10 @@ def OverlayMainContentCfg(configFlags): if configFlags.Detector.EnableITkStrip: acc.merge(ITkStripOverlayCfg(configFlags)) + # HGTD + if configFlags.Detector.EnableHGTD: + acc.merge(HGTD_OverlayCfg(configFlags)) + # Calorimeters if configFlags.Detector.EnableLAr: acc.merge(LArOverlayCfg(configFlags)) -- GitLab