diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/ObjectCutFlowHistAlg.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/ObjectCutFlowHistAlg.h index da3d2082511927b9d8aaa6f63823af4ddd2244db..233cdb36c826b28b3e71d8cb5b7b9094c0d7176d 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/ObjectCutFlowHistAlg.h +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/ObjectCutFlowHistAlg.h @@ -1,8 +1,9 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ /// @author Nils Krumnack +/// @author Baptiste Ravina #ifndef ASG_ANALYSIS_ALGORITHMS__OBJECT_CUT_FLOW_HIST_ALG_H @@ -11,7 +12,6 @@ #include <AnaAlgorithm/AnaAlgorithm.h> #include <AsgTools/PropertyWrapper.h> #include <SelectionHelpers/ISelectionNameSvc.h> -#include <SelectionHelpers/ISelectionReadAccessor.h> #include <SelectionHelpers/SysReadSelectionHandle.h> #include <SystematicsHandles/SysReadHandle.h> #include <SystematicsHandles/SysListHandle.h> @@ -19,19 +19,14 @@ namespace CP { - /// \brief an algorithm for dumping the kinematics of an IParticle - /// container into histograms - /// - /// This is mostly meant as a temporary helper algorithm to debug - /// the common CP algorithms as they get developed. + /// \brief an algorithm for dumping the object-level cutflow class ObjectCutFlowHistAlg final : public EL::AnaAlgorithm { /// \brief the standard constructor public: ObjectCutFlowHistAlg (const std::string& name, - ISvcLocator* pSvcLocator); - + ISvcLocator* pSvcLocator); public: StatusCode initialize () override; @@ -44,10 +39,10 @@ namespace CP private: SysListHandle m_systematicsList {this}; - /// \brief the jet collection we run on + /// \brief the particle collection we run on private: SysReadHandle<xAOD::IParticleContainer> m_inputHandle { - this, "input", "", "the input collection to run on"}; + this, "input", "", "the input particle container to run on"}; /// \brief the preselection we apply to our input private: @@ -66,13 +61,10 @@ namespace CP private: Gaudi::Property<std::string> m_histTitle {this, "histTitle", "object cut flow", "title for the created histograms"}; - - private: - std::vector<std::string> m_selection; - - /// the list of accessors and cut ignore list + /// \brief the input object selections for which to create a cutflow private: - std::vector<std::pair<std::unique_ptr<ISelectionReadAccessor>,unsigned> > m_accessors; + SysReadSelectionHandleArray m_selections { + this, "selections", {}, "the inputs to the object cutflow"}; /// \brief the total number of cuts configured (needed to /// configure histograms) diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/ObjectCutFlowHistAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/ObjectCutFlowHistAlg.cxx index 6d7c7fa3ee10e3b83c4b58ed8f3baa93f6339e76..24051cbac02a56a96a31cc07a535f742cdb22b1e 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/ObjectCutFlowHistAlg.cxx +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/ObjectCutFlowHistAlg.cxx @@ -1,8 +1,9 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ /// @author Nils Krumnack +/// @author Baptiste Ravina // @@ -11,7 +12,6 @@ #include <AsgAnalysisAlgorithms/ObjectCutFlowHistAlg.h> -#include <PATCore/AcceptInfo.h> #include <RootCoreUtils/StringUtil.h> #include <TH1.h> @@ -23,12 +23,10 @@ namespace CP { ObjectCutFlowHistAlg :: ObjectCutFlowHistAlg (const std::string& name, - ISvcLocator* pSvcLocator) + ISvcLocator* pSvcLocator) : AnaAlgorithm (name, pSvcLocator) { declareProperty ("histPattern", m_histPattern, "the pattern for histogram names"); - - declareProperty ("selection", m_selection, "the list of selection decorations"); } @@ -38,49 +36,28 @@ namespace CP { ANA_CHECK (m_inputHandle.initialize (m_systematicsList)); ANA_CHECK (m_preselection.initialize (m_systematicsList, m_inputHandle, SG::AllowEmpty)); + ANA_CHECK (m_selections.initialize (m_systematicsList, m_inputHandle)); ANA_CHECK (m_systematicsList.initialize()); ANA_CHECK (m_selectionNameSvc.retrieve()); // Total label m_labels.push_back ("total"); - - for (std::size_t iter = 0, end = m_selection.size(); iter != end; ++ iter) - { - unsigned ncuts = 0u; - std::unique_ptr<ISelectionReadAccessor> accessor; - ANA_CHECK (makeSelectionReadAccessor (m_selection[iter], accessor)); - - if (accessor->isBool()) - { - ANA_MSG_DEBUG ("selection " << m_selection[iter] << " is a bool, using 1 cut"); - ncuts = 1; - m_labels.push_back (accessor->label()); - } else if (const asg::AcceptInfo *acceptInfo = m_selectionNameSvc->getAcceptInfo (m_inputHandle.getNamePattern(), accessor->label()); - acceptInfo != nullptr) - { - ANA_MSG_DEBUG ("found accept info for " << m_inputHandle.getNamePattern() << " " << accessor->label()); - ncuts = acceptInfo->getNCuts(); - for (unsigned i = 0; i != ncuts; i++) - { - ANA_MSG_DEBUG ("using cut name from accept info: " << acceptInfo->getCutName (i)); - m_labels.push_back (acceptInfo->getCutName (i)); - } - } else - { - ANA_MSG_ERROR ("could not find accept info for " << m_inputHandle.getNamePattern() << " " << accessor->label()); - return StatusCode::FAILURE; + // Individual labels + for (size_t i{}; i < m_selections.size(); i++) { + std::string label = m_selections.at(i).getSelectionName(); + // Check if the string ends with "_%SYS%" + if (label.size() >= 6 && label.substr(label.size() - 6) == "_%SYS%") { + // Remove "_%SYS%" from the end of the string + label.erase(label.size() - 6); } - - m_accessors.push_back (std::make_pair (std::move (accessor), ncuts)); - m_allCutsNum += ncuts; - assert (m_allCutsNum+1 == m_labels.size()); + m_labels.push_back (label); + m_allCutsNum ++; } + assert (m_allCutsNum+1 == m_labels.size()); return StatusCode::SUCCESS; } - - StatusCode ObjectCutFlowHistAlg :: execute () { @@ -110,35 +87,20 @@ namespace CP } } - for (const xAOD::IParticle *particle : *input) - { - if (m_preselection.getBool (*particle, sys)) - { - bool keep = true; - unsigned cutIndex = 1; - histIter->second->Fill (0); - for (const auto& accessor : m_accessors) - { - const auto selection = accessor.first->getBits (*particle); - for (unsigned index = 0, end = accessor.second; - index != end; ++ index, ++ cutIndex) - { - if (selection & (1 << index)) - { - histIter->second->Fill (cutIndex); - } else - { - keep = false; - break; - } - } - if (!keep) - break; - } - } + for (const xAOD::IParticle *particle : *input) { + if (m_preselection.getBool (*particle, sys)) { + unsigned cutIndex = 1; + histIter->second->Fill (0); + for (size_t i{}; i < m_selections.size(); i++) { + if (m_selections.at(i).getBool (*particle, sys) > 0) { + histIter->second->Fill (cutIndex); + } + cutIndex++; + } + } } - } + } return StatusCode::SUCCESS; } } diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisConfig.py b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisConfig.py index 8bef719de42cf8f3b66ca7ad0c5fdc6aa12b3e39..a7185526483f09cc14b2d94cca9ebe06f37bf0de 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisConfig.py +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/AsgAnalysisConfig.py @@ -271,7 +271,7 @@ class ObjectCutFlowBlock (ConfigBlock): alg = config.createAlgorithm( 'CP::ObjectCutFlowHistAlg', 'CutFlowDumperAlg_' + self.containerName + '_' + self.selectionName + postfix ) alg.histPattern = 'cflow_' + self.containerName + "_" + self.selectionName + postfix + '_%SYS%' - alg.selection = config.getSelectionCutFlow (self.containerName, self.selectionName) + alg.selections = config.getSelectionCutFlow (self.containerName, self.selectionName) alg.input = config.readName (self.containerName) alg.histTitle = "Object Cutflow: " + self.containerName + "." + self.selectionName diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/OverlapAnalysisSequence.py b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/OverlapAnalysisSequence.py index e13f0072199eec9756ab235f608917effc79cfd1..f097dbbe61f1713243301a9368f0b8f424e703ee 100644 --- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/OverlapAnalysisSequence.py +++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/python/OverlapAnalysisSequence.py @@ -292,10 +292,10 @@ def makeOverlapAnalysisSequence( dataType, 'OverlapRemovalCutFlowDumperAlg_%s' % container[ 0 ] + postfix ) alg.histPattern = container[ 0 ] + postfix + '_OR_cflow_%SYS%' if inputLabel: - alg.selection = [ '%s,as_char' % inputLabel, + alg.selections = [ '%s,as_char' % inputLabel, '%s,as_char' % outputLabel ] else: - alg.selection = [ '%s,as_char' % outputLabel ] + alg.selections = [ '%s,as_char' % outputLabel ] seq.append( alg, inputPropName = { container[ 0 ] : 'input' } ) # Set up a view container for the type.