diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h index 5a07aec0b3a51ede12c83e920784befa275713c7..7d47e60c7d9d0b470d2ed023b85da2aa596c65fc 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h @@ -17,6 +17,7 @@ #include <AsgAnalysisAlgorithms/AsgLeptonTrackSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgOriginalObjectLinkAlg.h> #include <AsgAnalysisAlgorithms/AsgSelectionAlg.h> +#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgViewFromSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgxAODNTupleMakerAlg.h> #include <AsgAnalysisAlgorithms/EventFlagSelectionAlg.h> diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..40e4c81c23c2706f51a46c31b06659980a56e817 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Tadej Novak + +#ifndef ASG_ANALYSIS_ALGORITHMS__UNION_SELECTION_ALG_H +#define ASG_ANALYSIS_ALGORITHMS__UNION_SELECTION_ALG_H + +#include <AnaAlgorithm/AnaAlgorithm.h> +#include <SelectionHelpers/SysReadSelectionHandle.h> +#include <SelectionHelpers/ISelectionWriteAccessor.h> +#include <SystematicsHandles/SysReadHandle.h> +#include <SystematicsHandles/SysListHandle.h> +#include <xAODBase/IParticleContainer.h> + + +namespace CP +{ + /// \brief an algorithm for selection an union of objects that pass + /// at least one systematics + + class AsgUnionSelectionAlg final : public EL::AnaAlgorithm + { + /// \brief the standard constructor + public: + AsgUnionSelectionAlg (const std::string& name, + ISvcLocator* pSvcLocator); + + + public: + virtual StatusCode initialize () override; + + public: + virtual StatusCode execute () override; + + + + /// \brief the systematics list we run and have containers + private: + SysListHandle m_systematicsList {this}; + + /// \brief the particle continer we run on + private: + SysReadHandle<xAOD::IParticleContainer> m_particlesHandle { + this, "particles", "", "the asg collection to run on"}; + + /// \brief the preselection we apply to our input + private: + SysReadSelectionHandle m_preselection { + this, "preselection", "", "the preselection to apply"}; + + /// \brief the decoration of the selection + private: + std::string m_selectionDecoration; + + /// \brief the accessor for \ref m_selectionDecoration + private: + std::unique_ptr<ISelectionWriteAccessor> m_selectionAccessor; + }; + +} // namespace CP + +#endif diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml index f50c3eacb3577567ba96b066bae1484eba746e64..10eea8a1ab7e2819aef7fbfe5fd410deda1385b0 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml @@ -10,6 +10,7 @@ <class name="CP::AsgLeptonTrackSelectionAlg" /> <class name="CP::AsgOriginalObjectLinkAlg" /> <class name="CP::AsgSelectionAlg" /> + <class name="CP::AsgUnionSelectionAlg" /> <class name="CP::AsgViewFromSelectionAlg" /> <class name="CP::AsgxAODNTupleMakerAlg" /> <class name="CP::EventFlagSelectionAlg" /> diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx index b169e0218ff99e9df24a6bfff0c7d1e57151c53a..d62c1c6b59cff1abbf51405119d4b1d84c260b02 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx @@ -34,21 +34,27 @@ namespace CP StatusCode AsgSelectionAlg :: initialize () { - ANA_CHECK (m_selectionTool.retrieve()); - m_systematicsTool = dynamic_cast<ISystematicsTool*>(&*m_selectionTool); - if (m_systematicsTool) - ANA_CHECK (m_systematicsList.addSystematics (*m_systematicsTool)); + if (!m_selectionTool.empty()) + { + ANA_CHECK (m_selectionTool.retrieve()); + m_systematicsTool = dynamic_cast<ISystematicsTool*>(&*m_selectionTool); + if (m_systematicsTool) + ANA_CHECK (m_systematicsList.addSystematics (*m_systematicsTool)); + } ANA_CHECK (m_particlesHandle.initialize (m_systematicsList)); ANA_CHECK (m_preselection.initialize (m_systematicsList, m_particlesHandle, SG::AllowEmpty)); ANA_CHECK (m_selectionHandle.initialize (m_systematicsList, m_particlesHandle)); ANA_CHECK (m_systematicsList.initialize()); - Root::TAccept blankAccept = m_selectionTool->getTAccept(); - // Just in case this isn't initially set up as a failure clear it this one - // time. This only calls reset on the bitset - blankAccept.clear(); - m_setOnFail = selectionFromAccept(blankAccept); + if (!m_selectionTool.empty()) + { + Root::TAccept blankAccept = m_selectionTool->getTAccept(); + // Just in case this isn't initially set up as a failure clear it this one + // time. This only calls reset on the bitset + blankAccept.clear(); + m_setOnFail = selectionFromAccept(blankAccept); + } return StatusCode::SUCCESS; } @@ -69,12 +75,26 @@ namespace CP { if (m_preselection.getBool (*particle, sys)) { - m_selectionHandle.setBits - (*particle, selectionFromAccept (m_selectionTool->accept (particle)), sys); + if (!m_selectionTool.empty()) + { + m_selectionHandle.setBits + (*particle, selectionFromAccept (m_selectionTool->accept (particle)), sys); + } + else + { + m_selectionHandle.setBool (*particle, true, sys); + } } else { - m_selectionHandle.setBits(*particle, m_setOnFail, sys); + if (!m_selectionTool.empty()) + { + m_selectionHandle.setBits (*particle, m_setOnFail, sys); + } + else + { + m_selectionHandle.setBool (*particle, false, sys); + } } } } diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fea42a4f2f0d919dd46d86dfa7f750eb4f9254c9 --- /dev/null +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +/// @author Tadej Novak + +// +// includes +// + +#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h> + +#include <xAODBase/IParticle.h> + +// +// method implementations +// + +namespace CP +{ + AsgUnionSelectionAlg :: + AsgUnionSelectionAlg (const std::string& name, + ISvcLocator* pSvcLocator) + : AnaAlgorithm (name, pSvcLocator) + { + declareProperty ("selectionDecoration", m_selectionDecoration, "the decoration for the union selection"); + } + + + + StatusCode AsgUnionSelectionAlg :: + initialize () + { + if (m_selectionDecoration.empty()) + { + ANA_MSG_ERROR("Selection decoration can not be empty."); + return StatusCode::FAILURE; + } + + ANA_CHECK (makeSelectionWriteAccessor (m_selectionDecoration, m_selectionAccessor)); + + ANA_CHECK (m_particlesHandle.initialize(m_systematicsList)); + ANA_CHECK (m_preselection.initialize (m_systematicsList, m_particlesHandle)); + ANA_CHECK (m_systematicsList.initialize()); + + return StatusCode::SUCCESS; + } + + + + StatusCode AsgUnionSelectionAlg :: + execute () + { + std::vector<bool> selections; + + // first loop through systematics and define if particle passes each of them + for (const auto& sys : m_systematicsList.systematicsVector()) + { + const xAOD::IParticleContainer *particles{}; + ANA_CHECK (m_particlesHandle.retrieve (particles, sys)); + + if (selections.empty()) + { + selections.resize(particles->size(), false); + } + else if (selections.size() != particles->size()) + { + ANA_MSG_ERROR("All input containers should have the same size."); + return StatusCode::FAILURE; + } + + for (size_t i{}; i < particles->size(); i++) + { + selections[i] = selections[i] || m_preselection.getBool (*particles->at(i), sys); + } + } + + // Now decorate the selection decoration + // Looping over systematics is needed to ensure all containers are processed + for (const auto& sys : m_systematicsList.systematicsVector()) + { + const xAOD::IParticleContainer *particles{}; + ANA_CHECK (m_particlesHandle.retrieve (particles, sys)); + + for (size_t i{}; i < particles->size(); i++) + { + m_selectionAccessor->setBool (*particles->at(i), selections[i]); + } + } + + return StatusCode::SUCCESS; + } + +} // namespace CP diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx index 95d84cf630e7f78a2107fb57d122767344e1a092..955469e857145ea341503afbe10f32276f0638d9 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx @@ -16,6 +16,7 @@ #include <AsgAnalysisAlgorithms/AsgLeptonTrackSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgOriginalObjectLinkAlg.h> #include <AsgAnalysisAlgorithms/AsgSelectionAlg.h> +#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgViewFromSelectionAlg.h> #include <AsgAnalysisAlgorithms/AsgxAODNTupleMakerAlg.h> #include <AsgAnalysisAlgorithms/EventFlagSelectionAlg.h> @@ -40,6 +41,7 @@ DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgEventScaleFactorAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgLeptonTrackSelectionAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgOriginalObjectLinkAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgSelectionAlg) +DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgUnionSelectionAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgViewFromSelectionAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgxAODNTupleMakerAlg) DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, EventFlagSelectionAlg) @@ -64,6 +66,7 @@ DECLARE_FACTORY_ENTRIES(AsgAnalysisAlgorithms) { DECLARE_NAMESPACE_ALGORITHM (CP, AsgLeptonTrackSelectionAlg) DECLARE_NAMESPACE_ALGORITHM (CP, AsgOriginalObjectLinkAlg) DECLARE_NAMESPACE_ALGORITHM (CP, AsgSelectionAlg) + DECLARE_NAMESPACE_ALGORITHM (CP, AsgUnionSelectionAlg) DECLARE_NAMESPACE_ALGORITHM (CP, AsgViewFromSelectionAlg) DECLARE_NAMESPACE_ALGORITHM (CP, AsgxAODNTupleMakerAlg) DECLARE_NAMESPACE_ALGORITHM (CP, EventFlagSelectionAlg) diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py index 13adb4d6b4edcc92c086fbe7a08ac0e2723c058e..3beeab478d75600470004691aa0779bcffdf70ca 100644 --- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py @@ -290,7 +290,6 @@ def makeElectronWorkingPointSequence( seq, dataType, workingPoint, # Set up an algorithm used for decorating baseline electron selection: alg = createAlgorithm( 'CP::AsgSelectionAlg', 'ElectronSelectionSummary' + postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' ) alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char' seq.append( alg, inputPropName = 'particles', stageName = 'selection', diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py index a133f1d81ad0371cee5e55155ab4b6707a7581a9..cdf64109444183846d55c1dc6fcbf72320f50279 100644 --- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py @@ -287,7 +287,6 @@ def makePhotonWorkingPointSequence( seq, dataType, workingPoint, postfix = '', # Set up an algorithm used for decorating baseline photon selection: alg = createAlgorithm( 'CP::AsgSelectionAlg', 'PhotonSelectionSummary' + postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' ) alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char' seq.append( alg, inputPropName = 'particles', stageName = 'selection', diff --git a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py index 423f5d3b9d278225fb4e2f851ecd4f48165befcd..8d1f64b419fb025bbf2bdb6e84d98871bf98de44 100644 --- a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py @@ -239,7 +239,6 @@ def makeMuonWorkingPointSequence( seq, dataType, workingPoint, postfix = '', # Set up an algorithm used for decorating baseline muon selection: alg = createAlgorithm( 'CP::AsgSelectionAlg', 'MuonSelectionSummary' + postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' ) alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char' seq.append( alg, inputPropName = 'particles', stageName = 'selection', diff --git a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py index 7c970a84cce4cf3911e9f920c2a91190dd1f1d89..8b328b90c94e46d4c8b4415bb69fd7764189a052 100644 --- a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py @@ -178,10 +178,9 @@ def makeTauWorkingPointSequence( seq, dataType, workingPoint, postfix = '', # Set up an algorithm used for decorating baseline tau selection: alg = createAlgorithm( 'CP::AsgSelectionAlg', 'TauSelectionSummary' + postfix ) - addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' ) alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char' seq.append( alg, inputPropName = 'particles', stageName = 'selection', - dynConfig = {'selectionTool.selectionFlags' : lambda meta : meta["selectionDecorNames"][:]} ) + dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNames"])} ) pass