From fa68ca0dced9e9be2f540c08a174f28a38ab67a8 Mon Sep 17 00:00:00 2001 From: Nils Krumnack <krumnack@iastate.edu> Date: Tue, 15 Jun 2021 13:13:39 -0500 Subject: [PATCH] remake SysListLoaderAlg into SystematicsSvc For now this just replaces the algorithm with a service, and communicates the systematics list via the service interface instead of via the event store. The plan is to add more functionality in future merge requests that will move a lot of the systematics handling functionality from the configuration layer into the service. --- Control/xAODRootAccess/Root/Init.cxx | 8 + .../AsgAnalysisAlgorithmsDict.h | 1 - .../AsgAnalysisAlgorithms/SysListDumperAlg.h | 2 +- .../AsgAnalysisAlgorithms/selection.xml | 3 +- .../Root/SysListLoaderAlg.cxx | 137 ----------------- .../python/AsgAnalysisAlgorithmsTest.py | 20 +-- .../AsgAnalysisAlgorithms_entries.cxx | 3 - .../python/EgammaAnalysisAlgorithmsTest.py | 10 +- .../python/FTagAnalysisAlgorithmsTest.py | 9 +- .../python/JetAnalysisAlgorithmsTest.py | 9 +- .../python/JetAnalysisSequence.py | 1 + .../python/MetAnalysisAlgorithmsTest.py | 9 +- .../python/MuonAnalysisAlgorithmsTest.py | 9 +- .../SystematicsHandles/CMakeLists.txt | 12 ++ .../SystematicsHandles/Root/SysListHandle.cxx | 7 +- .../SystematicsHandles/Root/SysListType.cxx | 27 ---- .../Root/SystematicsSvc.cxx | 144 ++++++++++++++++++ .../SystematicsHandles/ISystematicsSvc.h | 35 +++++ .../SystematicsHandles/SysListHandle.h | 33 +--- .../SystematicsHandles/SysListHandle.icc | 5 +- .../SystematicsHandles/SysListType.h | 4 - .../SystematicsHandlesDict.h | 13 ++ .../SystematicsHandles/SystematicsSvc.h} | 40 ++--- .../SystematicsHandles/selection.xml | 6 + .../components/SystematicsHandles_entries.cxx | 9 ++ .../python/TauAnalysisAlgorithmsTest.py | 9 +- .../python/TriggerAnalysisAlgorithmsTest.py | 9 +- 27 files changed, 300 insertions(+), 274 deletions(-) delete mode 100644 PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/SysListLoaderAlg.cxx delete mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListType.cxx create mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SystematicsSvc.cxx create mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/ISystematicsSvc.h create mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsHandlesDict.h rename PhysicsAnalysis/Algorithms/{AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListLoaderAlg.h => SystematicsHandles/SystematicsHandles/SystematicsSvc.h} (55%) create mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/selection.xml create mode 100644 PhysicsAnalysis/Algorithms/SystematicsHandles/src/components/SystematicsHandles_entries.cxx diff --git a/Control/xAODRootAccess/Root/Init.cxx b/Control/xAODRootAccess/Root/Init.cxx index 3313c9ed339a..727bb412b926 100644 --- a/Control/xAODRootAccess/Root/Init.cxx +++ b/Control/xAODRootAccess/Root/Init.cxx @@ -69,6 +69,14 @@ namespace xAOD { ROOT::Cintex::Cintex::Enable(); #endif // ROOT_VERSION +#ifdef XAOD_STANDALONE + // Ensure the JetContainer dictionary is loaded. This fixes an + // issue in the common CP algorithms where this dictionary is + // not always loaded in the correct order despite the code + // above. + gInterpreter->ProcessLine ("delete new xAOD::JetContainer;"); +#endif + // Let the user know what happened: ::Info( appname, "Environment initialised for data access" ); diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h index 9f851a038d39..9514cfab34b0 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h @@ -28,7 +28,6 @@ #include <AsgAnalysisAlgorithms/PileupReweightingAlg.h> #include <AsgAnalysisAlgorithms/PMGTruthWeightAlg.h> #include <AsgAnalysisAlgorithms/SysListDumperAlg.h> -#include <AsgAnalysisAlgorithms/SysListLoaderAlg.h> #include <AsgAnalysisAlgorithms/TreeFillerAlg.h> #include <AsgAnalysisAlgorithms/TreeMakerAlg.h> diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListDumperAlg.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListDumperAlg.h index 6b0f3d775ac5..ea35718fa83e 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListDumperAlg.h +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListDumperAlg.h @@ -39,7 +39,7 @@ namespace CP /// \brief the name of the histogram to use private: - std::string m_histogramName {sysListDefaultName()}; + std::string m_histogramName {"systematics"}; /// \brief whether the next event will be the first event private: diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml index 53b3cbfbb99c..1d8e58ad2376 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml @@ -10,7 +10,7 @@ <class name="CP::AsgLeptonTrackSelectionAlg" /> <class name="CP::AsgOriginalObjectLinkAlg" /> <class name="CP::AsgSelectionAlg" /> - <class name="CP::AsgViewSelectionAlg" /> + <class name="CP::AsgViewFromSelectionAlg" /> <class name="CP::AsgxAODNTupleMakerAlg" /> <class name="CP::EventFlagSelectionAlg" /> <class name="CP::EventSelectionByObjectFlagAlg" /> @@ -21,7 +21,6 @@ <class name="CP::PileupReweightingAlg" /> <class name="CP::PMGTruthWeightAlg" /> <class name="CP::SysListDumperAlg" /> - <class name="CP::SysListLoaderAlg" /> <class name="CP::TreeFillerAlg" /> <class name="CP::TreeMakerAlg" /> diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/SysListLoaderAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/SysListLoaderAlg.cxx deleted file mode 100644 index 068697fa1fb3..000000000000 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/SysListLoaderAlg.cxx +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration -*/ - -/// @author Nils Krumnack - - -// -// includes -// - -#include <regex> - -#include <AsgAnalysisAlgorithms/SysListLoaderAlg.h> - -#include <AsgTools/MessageCheck.h> -#include <PATInterfaces/MakeSystematicsVector.h> -#include <PATInterfaces/SystematicRegistry.h> - -// -// method implementations -// - -namespace CP -{ - SysListLoaderAlg :: - SysListLoaderAlg (const std::string& name, - ISvcLocator* pSvcLocator) - : AnaAlgorithm (name, pSvcLocator) - { - declareProperty ("systematicsName", m_systematicsName, "the name of the systematics in the event store"); - declareProperty ("systematicsList", m_systematicsList, "the list of systematics to run"); - declareProperty ("systematicsRegex", m_systematicsRegex, "systematics filter regex"); - declareProperty ("sigmaRecommended", m_sigmaRecommended, "the sigma with which to run recommended systematics"); - } - - - - StatusCode SysListLoaderAlg :: - initialize () - { - if (m_systematicsName.empty()) - { - ANA_MSG_ERROR ("no name configured for the systematics list"); - return StatusCode::FAILURE; - } - - if (!std::isfinite (m_sigmaRecommended) || - m_sigmaRecommended < 0) - { - ANA_MSG_ERROR ("invalid value for sigmaRecommended: " << m_sigmaRecommended); - return StatusCode::FAILURE; - } - - if (m_sigmaRecommended != 0) - { - if (!m_systematicsList.empty()) - { - ANA_MSG_ERROR ("can't specify both sigmaRecommended and systematicsList"); - return StatusCode::FAILURE; - } - } else if (m_systematicsList.empty()) - { - // take an empty property as running just the central - // systematics set. implication is that you can't really run - // doing nothing, but that ought to be Ok. - m_systematicsVector.push_back (CP::SystematicSet ()); - } else - { - for (const std::string& sysName : m_systematicsList) - m_systematicsVector.push_back (CP::SystematicSet (sysName)); - } - return StatusCode::SUCCESS; - } - - - - StatusCode SysListLoaderAlg :: - execute () - { - if (m_firstEvent) - { - m_firstEvent = false; - const CP::SystematicSet recommended - = CP::SystematicRegistry::getInstance().recommendedSystematics(); - const CP::SystematicSet affecting - = CP::SystematicRegistry::getInstance().globalSystematics(); - - for (const CP::SystematicVariation& mysys : affecting) - { - // this logic checks whether a systematic is recommended and - // affecting, or only affecting. if it is only the later, it - // reports the systematic in parenthesis to set it apart. - if (recommended.find (mysys) == recommended.end()) - ANA_MSG_INFO ("found systematic: (" << mysys << ")"); - else - ANA_MSG_INFO ("found systematic: " << mysys); - } - bool error = false; - for (const CP::SystematicVariation& mysys : recommended) - { - if (affecting.find (mysys) == affecting.end()) - { - ANA_MSG_ERROR ("systematic is only registered as recommended, not affecting: " << mysys); - error = true; - } - } - if (error) - return StatusCode::FAILURE; - - - if (m_systematicsVector.empty()) - { - assert (m_sigmaRecommended > 0); - CP::MakeSystematicsVector sys; - sys.setSigma (m_sigmaRecommended); - sys.calc (recommended); - - std::regex expr (m_systematicsRegex); - for (const CP::SystematicSet& mysys : sys.result("")) - { - if (!regex_match (mysys.name(), expr)) - { - ANA_MSG_INFO ("skipping systematic: " << mysys.name()); - } else { - ANA_MSG_INFO ("configuring systematic: " << mysys.name()); - m_systematicsVector.push_back (mysys); - } - } - } - } - - std::unique_ptr<SysListType> list (new SysListType (m_systematicsVector)); - ANA_CHECK (evtStore()->record (list.release(), m_systematicsName)); - return StatusCode::SUCCESS; - } -} diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisAlgorithmsTest.py index 762c116e55b9..288dd9613953 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisAlgorithmsTest.py @@ -4,7 +4,7 @@ # @author Tadej Novak from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createAlgorithm, createService def makeOverlapSequence (dataType) : algSeq = AlgSequence() @@ -15,9 +15,9 @@ def makeOverlapSequence (dataType) : algSeq.PrimaryVertexSelectorAlg.VertexContainer = 'PrimaryVertices' algSeq.PrimaryVertexSelectorAlg.MinVertices = 1 - # Set up the systematics loader/handler algorithm: - algSeq += createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - algSeq.SysLoaderAlg.sigmaRecommended = 1 + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ @@ -145,9 +145,9 @@ def makeEventAlgorithmsSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - algSeq += createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - algSeq.SysLoaderAlg.sigmaRecommended = 1 + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: from AsgAnalysisAlgorithms.EventSelectionAnalysisSequence import \ @@ -179,9 +179,9 @@ def makeGeneratorAlgorithmsSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - algSeq += createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - algSeq.SysLoaderAlg.sigmaRecommended = 1 + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence (to make a copy): from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx index 029357e9c37e..cdeed836fb66 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx @@ -27,7 +27,6 @@ #include <AsgAnalysisAlgorithms/PileupReweightingAlg.h> #include <AsgAnalysisAlgorithms/PMGTruthWeightAlg.h> #include <AsgAnalysisAlgorithms/SysListDumperAlg.h> -#include <AsgAnalysisAlgorithms/SysListLoaderAlg.h> #include <AsgAnalysisAlgorithms/TreeFillerAlg.h> #include <AsgAnalysisAlgorithms/TreeMakerAlg.h> @@ -51,7 +50,6 @@ DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, OverlapRemovalAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, PileupReweightingAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, PMGTruthWeightAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, SysListDumperAlg) -DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, SysListLoaderAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, TreeFillerAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, TreeMakerAlg) @@ -75,7 +73,6 @@ DECLARE_FACTORY_ENTRIES(AsgAnalysisAlgorithms) { DECLARE_NAMESPACE_ALGORITHM (CP, PileupReweightingAlg) DECLARE_NAMESPACE_ALGORITHM (CP, PMGTruthWeightAlg) DECLARE_NAMESPACE_ALGORITHM (CP, SysListDumperAlg) - DECLARE_NAMESPACE_ALGORITHM (CP, SysListLoaderAlg) DECLARE_NAMESPACE_ALGORITHM (CP, TreeFillerAlg) DECLARE_NAMESPACE_ALGORITHM (CP, TreeMakerAlg) } diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/EgammaAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/EgammaAnalysisAlgorithmsTest.py index 27ed78a7449f..846c9d368f4c 100644 --- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/EgammaAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/EgammaAnalysisAlgorithmsTest.py @@ -1,16 +1,14 @@ # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createService def makeSequence (dataType, likelihood=True) : algSeq = AlgSequence() - # Create the algorithm's configuration. Note that we'll be able to add - # algorithm property settings here later on. - alg = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - alg.sigmaRecommended = 1 - algSeq += alg + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ diff --git a/PhysicsAnalysis/Algorithms/FTagAnalysisAlgorithms/python/FTagAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/FTagAnalysisAlgorithms/python/FTagAnalysisAlgorithmsTest.py index 7e0c9e5bb4e1..f081bf11c730 100644 --- a/PhysicsAnalysis/Algorithms/FTagAnalysisAlgorithms/python/FTagAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/FTagAnalysisAlgorithms/python/FTagAnalysisAlgorithmsTest.py @@ -3,16 +3,15 @@ # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createService def makeSequence (dataType, jetContainer="AntiKt4EMPFlowJets") : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - sysLoader = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - sysLoader.sigmaRecommended = 1 - algSeq += sysLoader + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the jet analysis algorithm sequence: from JetAnalysisAlgorithms.JetAnalysisSequence import makeJetAnalysisSequence diff --git a/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisAlgorithmsTest.py index 6d04dd9bd5da..7a2f3ee31554 100644 --- a/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisAlgorithmsTest.py @@ -3,7 +3,7 @@ # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createAlgorithm, createService def makeSequence (dataType, jetContainer="AntiKt4EMPFlowJets") : @@ -12,10 +12,9 @@ def makeSequence (dataType, jetContainer="AntiKt4EMPFlowJets") : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - sysLoader = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - sysLoader.sigmaRecommended = 1 - algSeq += sysLoader + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: from AsgAnalysisAlgorithms.PileupAnalysisSequence import \ diff --git a/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisSequence.py b/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisSequence.py index 3bdc1d03c6cc..2b3c2b0c9b45 100644 --- a/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/JetAnalysisAlgorithms/python/JetAnalysisSequence.py @@ -66,6 +66,7 @@ def makeJetAnalysisSequence( dataType, jetCollection, postfix = '', enableKinematicHistograms -- Whether or not to dump the kinematic histograms Other keyword arguments are forwarded to the other functions. """ + if dataType not in ["data", "mc", "afii"]: raise ValueError ("invalid data type: " + dataType ) diff --git a/PhysicsAnalysis/Algorithms/MetAnalysisAlgorithms/python/MetAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/MetAnalysisAlgorithms/python/MetAnalysisAlgorithmsTest.py index 3086cdaabaf0..369d4daa6baa 100644 --- a/PhysicsAnalysis/Algorithms/MetAnalysisAlgorithms/python/MetAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/MetAnalysisAlgorithms/python/MetAnalysisAlgorithmsTest.py @@ -1,15 +1,14 @@ # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import addPrivateTool, createAlgorithm +from AnaAlgorithm.DualUseConfig import addPrivateTool, createAlgorithm, createService def makeSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - sysLoader = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - sysLoader.sigmaRecommended = 1 - algSeq += sysLoader + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the jet analysis algorithm sequence: from JetAnalysisAlgorithms.JetAnalysisSequence import makeJetAnalysisSequence diff --git a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisAlgorithmsTest.py index ffa135dd6603..54a8bd9fa4c4 100644 --- a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisAlgorithmsTest.py @@ -3,16 +3,15 @@ # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createAlgorithm, createService def makeSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - sysLoader = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - sysLoader.sigmaRecommended = 1 - algSeq += sysLoader + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/CMakeLists.txt b/PhysicsAnalysis/Algorithms/SystematicsHandles/CMakeLists.txt index 6fa55968831c..01035b157859 100644 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/CMakeLists.txt +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/CMakeLists.txt @@ -26,6 +26,7 @@ atlas_add_library( SystematicsHandlesLib SystematicsHandles/*.h SystematicsHandles/*.icc Root/*.cxx PUBLIC_HEADERS SystematicsHandles LINK_LIBRARIES AsgTools PATInterfaces AnaAlgorithmLib xAODBase xAODCore AthContainers xAODEventInfo + AsgServicesLib PRIVATE_LINK_LIBRARIES RootCoreUtils xAODJet xAODMuon xAODEgamma xAODTau ) @@ -38,6 +39,17 @@ atlas_add_test( cc_SysCopyHandle LINK_LIBRARIES AsgTools AnaAlgorithmLib xAODEventInfo xAODJet SystematicsHandlesLib ) +atlas_add_dictionary( SystematicsHandlesDict + SystematicsHandles/SystematicsHandlesDict.h + SystematicsHandles/selection.xml + LINK_LIBRARIES SystematicsHandlesLib ) + +if( NOT XAOD_STANDALONE ) + atlas_add_component( SystematicsHandles + src/*.h src/*.cxx src/components/*.cxx + LINK_LIBRARIES GaudiKernel SystematicsHandlesLib ) +endif() + if( XAOD_STANDALONE ) atlas_add_test( ut_CopyHelpers SOURCES test/ut_CopyHelpers.cxx diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListHandle.cxx b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListHandle.cxx index ccd200164bc7..8cb4cabae04e 100644 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListHandle.cxx +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListHandle.cxx @@ -58,7 +58,7 @@ namespace CP ::StatusCode SysListHandle :: initialize () { - m_evtStore = m_evtStoreGetter(); + ANA_CHECK (m_systematicsService.retrieve()); m_isInitialized = true; return StatusCode::SUCCESS; } @@ -88,11 +88,8 @@ namespace CP m_fullAffecting = std::move (affecting); } - const SysListType *systematicsList = nullptr; - ANA_CHECK_THROW (m_evtStore->retrieve (systematicsList, m_systematicsListName)); - std::unordered_set<CP::SystematicSet> mysysList; - for (const auto& sys : *systematicsList) + for (const auto& sys : m_systematicsService->systematicsVector()) { auto iter = m_affectingCache.find (sys); if (iter != m_affectingCache.end()) diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListType.cxx b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListType.cxx deleted file mode 100644 index c352f7aff01b..000000000000 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysListType.cxx +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration -*/ - -/// @author Nils Krumnack - - -// -// includes -// - -#include <SystematicsHandles/SysListType.h> - -#include <string> - -// -// method implementations -// - -namespace CP -{ - const std::string& sysListDefaultName () - { - static const std::string result = "systematics"; - return result; - } -} diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SystematicsSvc.cxx b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SystematicsSvc.cxx new file mode 100644 index 000000000000..dafadf5dc0ce --- /dev/null +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SystematicsSvc.cxx @@ -0,0 +1,144 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Nils Krumnack + + +// +// includes +// + +#include <SystematicsHandles/SystematicsSvc.h> + +#include <AsgMessaging/MessageCheck.h> +#include <PATInterfaces/MakeSystematicsVector.h> +#include <PATInterfaces/SystematicRegistry.h> +#include <cassert> +#include <cmath> +#include <regex> + +// +// method implementations +// + +namespace CP +{ + SystematicsSvc :: + SystematicsSvc (const std::string& name, + ISvcLocator* pSvcLocator) + : AsgService (name, pSvcLocator) + { + declareProperty ("systematicsList", m_systematicsList, "the list of systematics to run"); + declareProperty ("systematicsRegex", m_systematicsRegex, "systematics filter regex"); + declareProperty ("sigmaRecommended", m_sigmaRecommended, "the sigma with which to run recommended systematics"); + + declareServiceInterface<ISystematicsSvc>(); + } + + + + StatusCode SystematicsSvc :: + initialize () + { + if (!std::isfinite (m_sigmaRecommended) || + m_sigmaRecommended < 0) + { + ANA_MSG_ERROR ("invalid value for sigmaRecommended: " << m_sigmaRecommended); + return StatusCode::FAILURE; + } + + if (m_sigmaRecommended != 0) + { + if (!m_systematicsList.empty()) + { + ANA_MSG_ERROR ("can't specify both sigmaRecommended and systematicsList"); + return StatusCode::FAILURE; + } + } + return StatusCode::SUCCESS; + } + + + + const SysListType& SystematicsSvc :: + systematicsVector () const + { + if (m_hasVector.load()) + return m_systematicsVector; + std::lock_guard<std::mutex> lock (m_vectorMutex); + if (m_hasVector.load()) + return m_systematicsVector; + + assert (m_systematicsVector.empty()); + + if (m_sigmaRecommended != 0) + { + assert (m_sigmaRecommended > 0); + + const CP::SystematicSet recommended + = CP::SystematicRegistry::getInstance().recommendedSystematics(); + + CP::MakeSystematicsVector sys; + sys.setSigma (m_sigmaRecommended); + sys.calc (recommended); + + std::regex expr (m_systematicsRegex); + for (const CP::SystematicSet& mysys : sys.result("")) + { + if (!regex_match (mysys.name(), expr)) + { + ANA_MSG_INFO ("skipping systematic: " << mysys.name()); + } else { + ANA_MSG_INFO ("configuring systematic: " << mysys.name()); + m_systematicsVector.push_back (mysys); + } + } + } else if (m_systematicsList.empty()) + { + // take an empty property as running just the central + // systematics set. implication is that you can't really run + // doing nothing, but that ought to be Ok. + m_systematicsVector.push_back (CP::SystematicSet ()); + } else + { + for (const std::string& sysName : m_systematicsList) + m_systematicsVector.push_back (CP::SystematicSet (sysName)); + } + + assert (!m_systematicsVector.empty()); + m_hasVector = true; + return m_systematicsVector; + } + + + + StatusCode SystematicsSvc :: + finalize () + { + const CP::SystematicSet recommended + = CP::SystematicRegistry::getInstance().recommendedSystematics(); + const CP::SystematicSet affecting + = CP::SystematicRegistry::getInstance().globalSystematics(); + + for (const CP::SystematicVariation& mysys : affecting) + { + // this logic checks whether a systematic is recommended and + // affecting, or only affecting. if it is only the later, it + // reports the systematic in parenthesis to set it apart. + if (recommended.find (mysys) == recommended.end()) + ANA_MSG_INFO ("found systematic: (" << mysys << ")"); + else + ANA_MSG_INFO ("found systematic: " << mysys); + } + + for (const CP::SystematicVariation& mysys : recommended) + { + if (affecting.find (mysys) == affecting.end()) + { + ANA_MSG_WARNING ("systematic is only registered as recommended, not affecting: " << mysys); + } + } + return StatusCode::SUCCESS; + } +} diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/ISystematicsSvc.h b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/ISystematicsSvc.h new file mode 100644 index 000000000000..49118c0abb03 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/ISystematicsSvc.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Nils Krumnack + + +#ifndef SYSTEMATICS_HANDLES__I_SYSTEMATICS_SVC_H +#define SYSTEMATICS_HANDLES__I_SYSTEMATICS_SVC_H + +#include <AsgServices/IAsgService.h> + +#include <SystematicsHandles/SysListType.h> + +namespace CP +{ + /// \brief the interface for the central systematics service + /// + /// This service is used as a core part of the common CP algorithms + /// to allow communicating systematics information between + /// algorithms in a sequence, without those algorithms needing to + /// talk to each other directly. + + class ISystematicsSvc : virtual public asg::IAsgService + { + public: + + DeclareInterfaceID (CP::ISystematicsSvc, 1, 0); + + /// \brief get the list of systematics + virtual const SysListType& systematicsVector () const = 0; + }; +} + +#endif diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.h b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.h index 53ec9d7a325a..9190ba7c433f 100644 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.h +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.h @@ -8,9 +8,10 @@ #ifndef SYSTEMATICS_HANDLES__SYS_LIST_HANDLE_H #define SYSTEMATICS_HANDLES__SYS_LIST_HANDLE_H -#include <AnaAlgorithm/AnaAlgorithm.h> -#include <AsgTools/AsgMessagingForward.h> +#include <AsgMessaging/AsgMessagingForward.h> +#include <AsgServices/ServiceHandle.h> #include <PATInterfaces/SystematicSet.h> +#include <SystematicsHandles/ISystematicsSvc.h> #include <SystematicsHandles/SysListType.h> #include <functional> #include <string> @@ -36,8 +37,8 @@ namespace CP /// \brief standard constructor public: template<typename T> - SysListHandle (T *owner, const std::string& propertyName = "systematics", - const std::string& propertyDescription = "list of systematics to evaluate"); + SysListHandle (T *owner, const std::string& propertyName = "systematicsService", + const std::string& propertyDescription = "systematics to evaluate"); /// \brief register an input handle we are using @@ -110,10 +111,9 @@ namespace CP // private interface // - /// \brief the name under which the systematics list is stored in - /// the event store + /// \brief the handle for the systematics service private: - std::string m_systematicsListName {"systematics"}; + ServiceHandle<ISystematicsSvc> m_systematicsService {"SystematicsSvc", ""}; /// \brief the regular expression for affecting systematics private: @@ -134,25 +134,6 @@ namespace CP /// \brief the value of \ref isInitialized private: bool m_isInitialized = false; - - - /// \brief the type of the event store we use - private: - typedef std::decay<decltype(*((EL::AnaAlgorithm*)0)->evtStore())>::type StoreType; - - /// \brief the event store we use - private: - mutable StoreType *m_evtStore = nullptr; - - /// \brief the function to retrieve the event store - /// - /// This is an std::function to allow the parent to be either a - /// tool or an algorithm. Though we are not really supporting - /// tools as parents when using \ref SysListHandle, so in - /// principle this could be replaced with a pointer to the - /// algorithm instead. - private: - std::function<StoreType*()> m_evtStoreGetter; }; } diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.icc b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.icc index 753fc7c9905e..e501702249c7 100644 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.icc +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListHandle.icc @@ -21,11 +21,10 @@ namespace CP SysListHandle (T *owner, const std::string& propertyName, const std::string& propertyDescription) : AsgMessagingForward (owner) - , m_evtStoreGetter ([owner] () {return &*owner->evtStore();}) { - owner->declareProperty (propertyName, m_systematicsListName, + owner->declareProperty (propertyName, m_systematicsService, propertyDescription); - owner->declareProperty (propertyName + "Regex", m_affectingRegex, "affecting systematics for " + propertyDescription); + owner->declareProperty ("systematicsRegex", m_affectingRegex, "affecting systematics"); } diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListType.h b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListType.h index 57f7c8705b4d..cf5826e48e36 100644 --- a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListType.h +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SysListType.h @@ -28,10 +28,6 @@ namespace CP /// performant in all situations. This way at least I will get /// compilation errors if I change it. typedef std::vector<CP::SystematicSet> SysListType; - - /// \brief the default name for putting the systematics list into - /// the event store - const std::string& sysListDefaultName (); } #endif diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsHandlesDict.h b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsHandlesDict.h new file mode 100644 index 000000000000..807970a08349 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsHandlesDict.h @@ -0,0 +1,13 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Nils Krumnack + + +#ifndef SYSTEMATICS_HANDLES__SYSTEMATICS_HANDLES_DICT_H +#define SYSTEMATICS_HANDLES__SYSTEMATICS_HANDLES_DICT_H + +#include <SystematicsHandles/SystematicsSvc.h> + +#endif diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListLoaderAlg.h b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsSvc.h similarity index 55% rename from PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListLoaderAlg.h rename to PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsSvc.h index aa6beb74e7dc..41a28981b1a6 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/SysListLoaderAlg.h +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/SystematicsSvc.h @@ -1,22 +1,25 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ /// @author Nils Krumnack -#ifndef ASG_ANALYSIS_ALGORITHMS__SYS_LIST_LOADER_ALG_H -#define ASG_ANALYSIS_ALGORITHMS__SYS_LIST_LOADER_ALG_H +#ifndef SYSTEMATICS_HANDLES__SYSTEMATICS_SVC_H +#define SYSTEMATICS_HANDLES__SYSTEMATICS_SVC_H -#include <AnaAlgorithm/AnaAlgorithm.h> +#include <AsgServices/AsgService.h> #include <PATInterfaces/SystematicSet.h> -#include <SystematicsHandles/SysListType.h> +#include <SystematicsHandles/ISystematicsSvc.h> +#include <atomic> +#include <mutex> namespace CP { - /// \todo add documentation + /// \brief the canonical implementation of \ref ISystematicsSvc - class SysListLoaderAlg final : public EL::AnaAlgorithm + class SystematicsSvc final : public asg::AsgService, + virtual public ISystematicsSvc { // // public interface @@ -28,7 +31,7 @@ namespace CP /// \par Failures /// out of memory II public: - SysListLoaderAlg (const std::string& name, + SystematicsSvc (const std::string& name, ISvcLocator* pSvcLocator); @@ -39,9 +42,8 @@ namespace CP public: virtual ::StatusCode initialize () override; - - public: - virtual ::StatusCode execute () override; + virtual ::StatusCode finalize () override; + virtual const SysListType& systematicsVector () const override; @@ -49,11 +51,6 @@ namespace CP // private interface // - /// \brief the name under which to store the systematics in the - /// event store - private: - std::string m_systematicsName {sysListDefaultName()}; - /// \brief the names of the systematics to request private: std::vector<std::string> m_systematicsList; @@ -71,13 +68,18 @@ namespace CP private: float m_sigmaRecommended = 0; + /// \brief the list of actual systematics private: - std::vector<CP::SystematicSet> m_systematicsVector; + mutable std::vector<CP::SystematicSet> m_systematicsVector; + + /// \brief whether \ref m_systematicsVector was initialized + private: + mutable std::atomic<bool> m_hasVector {false}; - /// \brief whether the next event will be the first event + /// \brief a mutex for filling \ref m_systematicsVector private: - bool m_firstEvent = true; + mutable std::mutex m_vectorMutex; }; } diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/selection.xml b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/selection.xml new file mode 100644 index 000000000000..141c99724683 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/SystematicsHandles/selection.xml @@ -0,0 +1,6 @@ +<lcgdict> + + <class name="CP::ISystematicsSvc" /> + <class name="CP::SystematicsSvc" /> + +</lcgdict> diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/src/components/SystematicsHandles_entries.cxx b/PhysicsAnalysis/Algorithms/SystematicsHandles/src/components/SystematicsHandles_entries.cxx new file mode 100644 index 000000000000..de3af107bee9 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/src/components/SystematicsHandles_entries.cxx @@ -0,0 +1,9 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Nils Krumnack + +#include <SystematicsHandles/SystematicsSvc.h> + +DECLARE_COMPONENT (CP::SystematicsSvc) diff --git a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisAlgorithmsTest.py index 7c496b06b12b..41ff63a3be3a 100644 --- a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisAlgorithmsTest.py @@ -3,16 +3,15 @@ # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createService def makeSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - sysLoader = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - sysLoader.sigmaRecommended = 1 - algSeq += sysLoader + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the tau analysis algorithm sequence: from TauAnalysisAlgorithms.TauAnalysisSequence import makeTauAnalysisSequence diff --git a/PhysicsAnalysis/Algorithms/TriggerAnalysisAlgorithms/python/TriggerAnalysisAlgorithmsTest.py b/PhysicsAnalysis/Algorithms/TriggerAnalysisAlgorithms/python/TriggerAnalysisAlgorithmsTest.py index c0d82335ddd0..63d2292b4ed8 100644 --- a/PhysicsAnalysis/Algorithms/TriggerAnalysisAlgorithms/python/TriggerAnalysisAlgorithmsTest.py +++ b/PhysicsAnalysis/Algorithms/TriggerAnalysisAlgorithms/python/TriggerAnalysisAlgorithmsTest.py @@ -4,7 +4,7 @@ # @author Nils Krumnack from AnaAlgorithm.AlgSequence import AlgSequence -from AnaAlgorithm.DualUseConfig import createAlgorithm +from AnaAlgorithm.DualUseConfig import createAlgorithm, createService def makeSequence (dataType) : @@ -18,10 +18,9 @@ def makeSequence (dataType) : algSeq = AlgSequence() - # Set up the systematics loader/handler algorithm: - alg = createAlgorithm( 'CP::SysListLoaderAlg', 'SysLoaderAlg' ) - alg.sigmaRecommended = 1 - algSeq += alg + # Set up the systematics loader/handler service: + sysService = createService( 'CP::SystematicsSvc', 'SystematicsSvc', sequence = algSeq ) + sysService.sigmaRecommended = 1 # Include, and then set up the pileup analysis sequence: from TriggerAnalysisAlgorithms.TriggerAnalysisSequence import \ -- GitLab