diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/CMakeLists.txt b/PhysicsAnalysis/AnalysisCommon/EventUtils/CMakeLists.txt index 73a5d549f74a19aaa99913585e8933fc1a235eaa..79357c8409121c3e9c760f959c7ab9159a2a84bb 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/CMakeLists.txt +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/CMakeLists.txt @@ -11,4 +11,4 @@ atlas_add_component( EventUtils src/*.cxx src/components/*.cxx INCLUDE_DIRS ${Boost_INCLUDE_DIRS} - LINK_LIBRARIES ${Boost_LIBRARIES} AthAnalysisBaseCompsLib AthContainers AthContainersInterfaces AthLinks AthenaBaseComps AthenaKernel EventInfo xAODBase xAODCaloEvent xAODCore xAODCutFlow xAODEgamma xAODEventInfo xAODJet xAODMuon xAODPFlow xAODParticleEvent xAODTau xAODTracking xAODTruth GaudiKernel PATCoreLib ExpressionEvaluationLib TrigDecisionToolLib DerivationFrameworkInterfaces ) + LINK_LIBRARIES ${Boost_LIBRARIES} AsgTools AthAnalysisBaseCompsLib AthContainers AthContainersInterfaces AthLinks AthenaBaseComps AthenaKernel EventInfo xAODBase xAODCaloEvent xAODCore xAODCutFlow xAODEgamma xAODEventInfo xAODJet xAODMuon xAODPFlow xAODParticleEvent xAODTau xAODTracking xAODTruth GaudiKernel PATCoreLib ExpressionEvaluationLib TrigDecisionToolLib DerivationFrameworkInterfaces ) diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx index 7642a29a3d29b82625be3b151c3385bf2a1890b6..4220165760fb62d45e60dd4a1152c8d5661487b6 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx @@ -39,7 +39,7 @@ CutAlg::CutAlg( const std::string& name, m_cut(""), m_nEventsProcessed(0) { - declareProperty("Cut", m_cut="", "The name of the output container" ); + declareProperty("Cut", m_cut="", "The cut expression" ); declareProperty("TrigDecisionTool", m_trigDecisionTool, "If you do not use trigger decisions and want to ensure the TrigDecisionTool is not loaded, set this to a blank string"); } diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx index 86e11806ff28db10d4c370901464c7324493341a..e65d23e79b8f36019f87006e3c675444e33dbcc2 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx @@ -1,9 +1,9 @@ ///////////////////////// -*- C++ -*- ///////////////////////////// - -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + // EventQualityFilterAlg.cxx // Implementation file for class EventQualityFilterAlg // Author: Karsten Koeneke <karsten.koeneke@cern.ch> @@ -16,6 +16,10 @@ // EDM includes #include "xAODEventInfo/EventInfo.h" +// FrameWork includes +#include "AsgDataHandles/ReadHandle.h" +#include "AsgTools/CurrentContext.h" + /////////////////////////////////////////////////////////////////// // Public methods: @@ -62,6 +66,7 @@ StatusCode EventQualityFilterAlg::initialize() ATH_MSG_DEBUG( "Using: " << m_useSCTError ); ATH_MSG_DEBUG( "Using: " << m_useCoreError ); // ATH_MSG_DEBUG( "Using: " << m_useTileTripReader ); + ATH_CHECK(m_eventInfo.initialize()); return StatusCode::SUCCESS; } @@ -79,10 +84,15 @@ StatusCode EventQualityFilterAlg::execute() { ATH_MSG_DEBUG ("Executing " << name() << "..."); + const EventContext& ctx = Gaudi::Hive::currentContext(); // Get the EventInfo object - const xAOD::EventInfo* eventInfo = nullptr; - ATH_CHECK( evtStore()->retrieve(eventInfo) ); + SG::ReadHandle<xAOD::EventInfo> eventInfo(m_eventInfo, ctx); + if (!eventInfo.isValid()) { + ATH_MSG_ERROR("Could not retrieve EventInfo!"); + return StatusCode::FAILURE; + } + // Only do the event vetoing on data diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h index b62e0516700163d82933c99fd9a18eb40a611e31..b19bc46bee0cf48de4b25c3ee06dbab7adfb2a0c 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h @@ -1,7 +1,7 @@ ///////////////////////// -*- C++ -*- ///////////////////////////// /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ // EventQualityFilterAlg.h @@ -17,6 +17,7 @@ // FrameWork includes #include "AthenaBaseComps/AthFilterAlgorithm.h" +#include "AsgDataHandles/ReadHandleKey.h" @@ -69,6 +70,9 @@ class EventQualityFilterAlg // /// Flag to turn on/off checking of tile trip information // BooleanProperty m_useTileTripReader; + /// EventInfo read handle + SG::ReadHandleKey<xAOD::EventInfo> m_eventInfo {this, "EventInfo", "EventInfo", "EventInfo key"}; + }; diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx index 50558acd75fca99d9d94e3097b4f8dcc784cbf8a..8656e485190678f4dddc9d5e53000924b8dc700e 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx @@ -1,7 +1,7 @@ ///////////////////////// -*- C++ -*- ///////////////////////////// /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ // ParticleSelectionAlg.cxx @@ -12,8 +12,6 @@ // EventUtils includes #include "ParticleSelectionAlg.h" -// STL includes - // FrameWork includes #include "Gaudi/Property.h" #include "DerivationFrameworkInterfaces/IAugmentationTool.h" @@ -57,7 +55,6 @@ #include "xAODCutFlow/CutBookkeeperContainer.h" #include "xAODCutFlow/CutBookkeeperAuxContainer.h" - /////////////////////////////////////////////////////////////////// // Public methods: /////////////////////////////////////////////////////////////////// @@ -67,8 +64,8 @@ ParticleSelectionAlg::ParticleSelectionAlg( const std::string& name, ISvcLocator* pSvcLocator ) : ::AthAnalysisAlgorithm( name, pSvcLocator ), + m_selTools(), // makes these tools public m_evtInfoName("EventInfo"), - m_inPrimVtxCont("PrimaryVertices"), m_inCollKey(""), m_outCollKey(""), m_writeSplitAux(true), @@ -83,11 +80,9 @@ ParticleSelectionAlg::ParticleSelectionAlg( const std::string& name, m_contType(UNKNOWN), m_cutBKStartIdx(0), m_selToolIdxOffset(), - m_selWPVToolIdxOffset(), m_idxSelParster(0) { declareProperty("EventInfo", m_evtInfoName, "Input container name"); - declareProperty("PrimaryVertexContainer", m_inPrimVtxCont, "The input primary vertex container name"); declareProperty("InputContainer", m_inCollKey, "Input container name"); declareProperty("OutputContainer", m_outCollKey, "The name of the output container with the deep copy of selected xAOD::IParticles"); @@ -96,6 +91,7 @@ ParticleSelectionAlg::ParticleSelectionAlg( const std::string& name, declareProperty("OutputContainerOwnershipPolicy", m_outOwnPolicyName, "Defines the ownership policy of the output container (default: 'OWN_ELEMENTS'; also allowed: 'VIEW_ELEMENTS')"); + declareProperty("SelectionToolList", m_selTools, "The list of IAsgSelectionTools"); declareProperty("Selection", m_selection, "The selection string that defines which xAOD::IParticles to select from the container"); @@ -121,13 +117,15 @@ StatusCode ParticleSelectionAlg::initialize() ATH_MSG_DEBUG ("Initializing " << name() << "..."); // Print out the used configuration - ATH_MSG_DEBUG ( " using = " << m_inCollKey ); - ATH_MSG_DEBUG ( " using = " << m_outCollKey ); - ATH_MSG_DEBUG ( " using = " << m_writeSplitAux ); - ATH_MSG_DEBUG ( " using = " << m_outOwnPolicyName ); - ATH_MSG_DEBUG ( " using = " << m_selection ); + ATH_MSG_DEBUG ( " using EventInfo = " << m_evtInfoName ); + ATH_MSG_DEBUG ( " using InputContainer = " << m_inCollKey ); + ATH_MSG_DEBUG ( " using OutputContainer = " << m_outCollKey ); + ATH_MSG_DEBUG ( " using WriteSplitOutputContainer = " << m_writeSplitAux ); + ATH_MSG_DEBUG ( " using OutputContainerOwnershipPolicy = " << m_outOwnPolicyName ); + ATH_MSG_DEBUG ( " using SelectionToolList = " << m_selTools ); + ATH_MSG_DEBUG ( " using Selection = " << m_selection ); ATH_MSG_DEBUG ( " using DoCutBookkeeping = " << m_doCutFlow ); - ATH_MSG_DEBUG ( " using = " << m_cutBKCName ); + ATH_MSG_DEBUG ( " using CutBookkeeperContainer = " << m_cutBKCName ); // initialize proxy loaders for expression parsing if ( !(m_selection.value().empty()) ){ @@ -154,6 +152,9 @@ StatusCode ParticleSelectionAlg::initialize() return StatusCode::FAILURE; } + // Retrieve all tools + ATH_CHECK( m_selTools.retrieve() ); + ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." ); return StatusCode::SUCCESS; } @@ -164,6 +165,9 @@ StatusCode ParticleSelectionAlg::finalize() { ATH_MSG_DEBUG ("Finalizing " << name() << "..."); + // Release all tools and services + ATH_CHECK( m_selTools.release() ); + // Clean up the memory if (m_parser) { delete m_parser; @@ -218,6 +222,34 @@ StatusCode ParticleSelectionAlg::start() ATH_MSG_VERBOSE( "Recorded xAOD::CutBookkeeperContainer " << m_cutBKCName.value() << "Aux." ); } + //------------- for the AsgSelectionTools -------------- + // Now, register one CutBookkeeper per cut that will be applied. + // For each of the registered tools, get the TAccept and ask it for all known cuts. + for ( std::size_t toolIdx=0; toolIdx < m_selTools.size(); ++toolIdx ){ + const ToolHandle<IAsgSelectionTool>& tool = m_selTools[toolIdx]; + // Fill the index bookkeeping at what index in the CutBookkeeperContainer + // the CutBookkeepers for this tool start. + m_selToolIdxOffset.push_back( cutBKCont->size() ); + // Get some needed quantities + const std::string toolName = tool->name(); + const asg::AcceptInfo& acceptInfo = tool->getAcceptInfo(); + const unsigned int nCuts = acceptInfo.getNCuts(); + for ( unsigned int iCut=0; iCut<nCuts; ++iCut ){ + // Get the name and description of this cut + const std::string cutName = acceptInfo.getCutName(iCut); + const std::string cutDescr = acceptInfo.getCutDescription(iCut); + // Create a new xAOD::CutBookkeeper and add it to the container + xAOD::CutBookkeeper* cutBK = new xAOD::CutBookkeeper(); + cutBKCont->push_back(cutBK); + // Now, set its properties + cutBK->setName(toolName+"_"+cutName); + cutBK->setDescription(cutDescr); + cutBK->setCutLogic(xAOD::CutBookkeeper::CutLogic::REQUIRE); // Each cut must be passed, thus REQUIRE, i.e, logical AND + cutBK->setInputStream(inputStreamName); + cutBK->setCycle(maxInputCycle); + } + } + //------------- for the ExpressionParsing in this algorithm -------------- if ( !(m_selection.value().empty()) ){ // Create a new xAOD::CutBookkeeper and add it to the container diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h index 3c17dd6afa9fcf8f431882e9f03b9b35816beb4b..b5acec334ad0d0411af3f8dfa35c0d532674a2d5 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h @@ -1,7 +1,7 @@ ///////////////////////// -*- C++ -*- ///////////////////////////// /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ // ParticleSelectionAlg.h @@ -11,10 +11,6 @@ #ifndef EVENTUTILS_PARTICLESELECTIONALG_H #define EVENTUTILS_PARTICLESELECTIONALG_H 1 -// STL includes -#include <string> -#include <vector> - // FrameWork includes #include "GaudiKernel/ToolHandle.h" // #include "GaudiKernel/ServiceHandle.h" @@ -22,6 +18,11 @@ #include "AthAnalysisBaseComps/AthAnalysisAlgorithm.h" #include "xAODBase/IParticleContainer.h" //#include "TrigDecisionTool/TrigDecisionTool.h" +#include "PATCore/IAsgSelectionTool.h" + +// STL includes +#include <string> +#include <vector> // // Forward declarations // namespace Trig{ @@ -76,12 +77,12 @@ class ParticleSelectionAlg // Private data: /////////////////////////////////////////////////////////////////// private: + /// The list of IAsgSelectionTools + ToolHandleArray<IAsgSelectionTool> m_selTools; + /// Name of the EventInfo object StringProperty m_evtInfoName; - /// Name of the PrimaryVertex container - StringProperty m_inPrimVtxCont; - /// Input container name StringProperty m_inCollKey; @@ -153,10 +154,6 @@ class ParticleSelectionAlg /// starting index of the corresponding CutBookKeeper inside the CutBookkeeperContainer. std::vector<std::size_t> m_selToolIdxOffset; - /// The list of pairs of the tool index of the AsgSelectionWithVertexTools and the - /// starting index of the corresponding CutBookKeeper inside the CutBookkeeperContainer. - std::vector<std::size_t> m_selWPVToolIdxOffset; - /// Store the index of the CutBookKeeper in the CutBookkeeperContainer for the /// selection using the ExpressionParser std::size_t m_idxSelParster; diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.icc b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.icc index 84370ef7b9c8c34021cd3454469d9d9b0098e633..2d4ed4e6c4b4c7aec25b595137105918c29ba444 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.icc +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.icc @@ -1,7 +1,7 @@ // Dear emacs, this is -*- c++ -*- /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ @@ -9,8 +9,6 @@ #include "xAODCore/AuxContainerBase.h" #include "AthContainers/ConstDataVector.h" #include "xAODEventInfo/EventInfo.h" -#include "xAODTracking/VertexContainer.h" -#include "xAODTracking/Vertex.h" #include "xAODCutFlow/CutBookkeeperContainer.h" #include "PATCore/AcceptInfo.h" #include "PATCore/AcceptData.h" @@ -82,6 +80,32 @@ StatusCode ParticleSelectionAlg::selectParticles(const xAOD::IParticleContainer* // the remainder of the cuts will not even be tried bool passEverything = true; + //------------- for the AsgSelectionTools -------------- + // Loop over all selection tools + ATH_MSG_VERBOSE("Loop over all selection tools"); + for ( std::size_t toolIdx=0; toolIdx < m_selTools.size(); ++toolIdx ){ + if (passEverything){ + ATH_MSG_VERBOSE("Now going to try AsgSelectionTools number " << toolIdx ); + const asg::AcceptData acceptData = m_selTools[toolIdx]->accept(part); + if (!m_doCutFlow){ passEverything &= static_cast<bool>(acceptData); } + else { + const std::size_t cbkStartIdx = m_selToolIdxOffset[toolIdx]; + const unsigned int nCuts = acceptData.getNCuts(); + for ( unsigned int iCut=0; iCut<nCuts; ++iCut ){ + passEverything &= acceptData.getCutResult(iCut); + if (passEverything){ + const std::size_t currentCBKIdx = cbkStartIdx + iCut; + xAOD::CutBookkeeper* cutBK = cutBKCont->at(currentCBKIdx); + cutBK->addNAcceptedEvents(1); + cutBK->addSumOfEventWeights(eventWeight); + cutBK->addSumOfEventWeightsSquared(eventWeight*eventWeight); + } + } + } // Done doing detailed particle cut-flow for this tool + ATH_MSG_VERBOSE("AsgSelectionTools number " << toolIdx << " passed/failed: " << passEverything ); + } + } + //------------- for the ExpressionParsing in this algorithm -------------- ATH_MSG_VERBOSE("Looking at expression parser result: " << passEverything); if ( passEverything && !(resultVec.empty()) ){ diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f5ad85275d7fda499fa4e9ee13f2a4490c6a552c --- /dev/null +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx @@ -0,0 +1,158 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// ParticleSortingAlg.cxx +// Implementation file for class ParticleSortingAlg +// Author: Karsten Koeneke <karsten.koeneke@cern.ch> +/////////////////////////////////////////////////////////////////// + +// EventUtils includes +#include "ParticleSortingAlg.h" + +// FrameWork includes +#include "Gaudi/Property.h" +#include "GaudiKernel/IJobOptionsSvc.h" +#include "DerivationFrameworkInterfaces/IAugmentationTool.h" + +/////////////////////////////////////////////////////////////////// +// Public methods: +/////////////////////////////////////////////////////////////////// + +// Constructors +//////////////// +ParticleSortingAlg::ParticleSortingAlg( const std::string& name, + ISvcLocator* pSvcLocator ) : + ::AthAlgorithm( name, pSvcLocator ), + m_jos("JobOptionsSvc", name), + m_tool("ParticleSortingTool/ParticleSortingTool", this), + m_inCollKey(""), + m_setInCollKey(false), + m_outCollKey(""), + m_setOutCollKey(false), + m_sortVar("pt"), + m_setSortVar(false), + m_sortDescending(true), + m_setSortDescending(false), + m_nEventsProcessed(0) +{ + declareProperty("JobOptionsSvc", m_jos, "The JobOptionService instance."); + + declareProperty("SortingTool", m_tool, "The private ParticleSortingTool" ); + + declareProperty("InputContainer", m_inCollKey="", "Input container name" ); + m_inCollKey.declareUpdateHandler( &ParticleSortingAlg::setupInputContainer, this ); + + declareProperty("OutputContainer", m_outCollKey="", + "The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects" ); + m_outCollKey.declareUpdateHandler( &ParticleSortingAlg::setupOutputContainer, this ); + + declareProperty("SortVariable", m_sortVar="pt", + "Define by what parameter to sort (default: 'pt'; allowed: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity')" ); + m_sortVar.declareUpdateHandler( &ParticleSortingAlg::setupSortVar, this ); + + declareProperty("SortDescending", m_sortDescending=true, + "Define if the container should be sorted in a descending order (default=true)" ); + m_sortDescending.declareUpdateHandler( &ParticleSortingAlg::setupSortDescending, this ); +} + + + +// Destructor +/////////////// +ParticleSortingAlg::~ParticleSortingAlg() +{} + + + +// Athena Algorithm's Hooks +//////////////////////////// +StatusCode ParticleSortingAlg::initialize() +{ + ATH_MSG_DEBUG ("Initializing " << name() << "..."); + + // Print out the used configuration + ATH_MSG_DEBUG ( " using = " << m_jos ); + ATH_MSG_DEBUG ( " using = " << m_tool ); + ATH_MSG_DEBUG ( " using = " << m_inCollKey ); + ATH_MSG_DEBUG ( " using = " << m_outCollKey ); + ATH_MSG_DEBUG ( " using = " << m_sortVar ); + ATH_MSG_DEBUG ( " using = " << m_sortDescending ); + + + // Initialize the counters to zero + m_nEventsProcessed = 0 ; + + + // Get the JobOptionService + // We will use this to set the properties of our private skimming tool + // from the properties of this algorithm. + ATH_MSG_VERBOSE( "Getting the JobOptionService"); + ATH_CHECK( m_jos.retrieve() ); + + // Get the full name of the private skimTool + ATH_MSG_VERBOSE( "Getting the full name of the tool"); + const std::string& fullToolName = this->name() + "." + m_tool.name(); + ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName ); + + // Now, set all properties of the private skimTool that were acutally configured + if (m_setInCollKey) { + ATH_MSG_DEBUG( "Setting property" << m_inCollKey + << " of private tool with name: '" << fullToolName << "'" ); + ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_inCollKey) ); + } + if (m_setOutCollKey) { + ATH_MSG_DEBUG( "Setting property" << m_outCollKey + << " of private tool with name: '" << fullToolName << "'" ); + ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outCollKey) ); + } + if (m_setSortVar) { + ATH_MSG_DEBUG( "Setting property" << m_sortVar + << " of private tool with name: '" << fullToolName << "'" ); + ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_sortVar) ); + } + if (m_setSortDescending) { + ATH_MSG_DEBUG( "Setting property" << m_sortDescending + << " of private tool with name: '" << fullToolName << "'" ); + ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_sortDescending) ); + } + ATH_MSG_DEBUG( "Done setting properties of the tool"); + + // Get the skimming tool + ATH_CHECK( m_tool.retrieve() ); + + ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." ); + + return StatusCode::SUCCESS; +} + + + +StatusCode ParticleSortingAlg::finalize() +{ + ATH_MSG_DEBUG ("Finalizing " << name() << "..."); + + // Release all tools and services + ATH_CHECK( m_jos.release() ); + ATH_CHECK( m_tool.release() ); + + return StatusCode::SUCCESS; +} + + + +StatusCode ParticleSortingAlg::execute() +{ + // Increase the event counter + ++m_nEventsProcessed; + + // Simple status message at the beginning of each event execute, + ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." ); + + // Call the tool + ATH_CHECK( m_tool->addBranches() ); + + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..763f04c952cab1305f4467bf3595943579326178 --- /dev/null +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h @@ -0,0 +1,149 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// ParticleSortingAlg.h +// Header file for class ParticleSortingAlg +// Author: Karsten Koeneke <karsten.koeneke@cern.ch> +/////////////////////////////////////////////////////////////////// +#ifndef EVENTUTILS_PARTICLESORTINGALG_H +#define EVENTUTILS_PARTICLESORTINGALG_H 1 + +// FrameWork includes +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" + +// STL includes +#include <string> + +// Forward declarations +class IJobOptionsSvc; +namespace DerivationFramework { + class IAugmentationTool; +} + +class ParticleSortingAlg + : public ::AthAlgorithm +{ + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Copy constructor: + + /// Constructor with parameters: + ParticleSortingAlg( const std::string& name, ISvcLocator* pSvcLocator ); + + /// Destructor: + virtual ~ParticleSortingAlg(); + + /// Athena algorithm's initalize hook + virtual StatusCode initialize(); + + /// Athena algorithm's execute hook + virtual StatusCode execute(); + + /// Athena algorithm's finalize hook + virtual StatusCode finalize(); + + +private: + // The update handlers + + /// This internal method will realize if a user sets the 'InputContainer' property + void setupInputContainer( Gaudi::Details::PropertyBase& /*prop*/ ); + + /// This internal method will realize if a user sets the 'OutputContainer' property + void setupOutputContainer( Gaudi::Details::PropertyBase& /*prop*/ ); + + /// This internal method will realize if a user sets the 'SortVariable' property + void setupSortVar( Gaudi::Details::PropertyBase& /*prop*/ ); + + /// This internal method will realize if a user sets the 'SortDeceding' property + void setupSortDescending( Gaudi::Details::PropertyBase& /*prop*/ ); + + + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + /// The job options service (will be used to forward this algs properties to + /// the private tool) + ServiceHandle<IJobOptionsSvc> m_jos; + + /// The ToolHandle to the private ParticleSortingTool + ToolHandle<DerivationFramework::IAugmentationTool> m_tool; + + /// Input container name + StringProperty m_inCollKey; + + /// This boolean is true if the user sets the 'InputContainer' property + bool m_setInCollKey; + + + /// The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects + StringProperty m_outCollKey; + + /// This boolean is true if the user sets the 'OutputContainer' property + bool m_setOutCollKey; + + + /// Define by what parameter to sort (default: 'pt') + StringProperty m_sortVar; + + /// This boolean is true if the user sets the 'SortVariable' property + bool m_setSortVar; + + + /// Define if the container should be sorted in a descending order (default=true) + BooleanProperty m_sortDescending; + + /// This boolean is true if the user sets the 'SortDescending' property + bool m_setSortDescending; + + + /// Internal event counter + unsigned long m_nEventsProcessed; + +}; + + + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + +/// This internal method will realize if a user sets the 'InputContainer' property +inline void ParticleSortingAlg::setupInputContainer( Gaudi::Details::PropertyBase& /*prop*/ ) { + m_setInCollKey = true; + return; +} + +/// This internal method will realize if a user sets the 'OutputContainer' property +inline void ParticleSortingAlg::setupOutputContainer( Gaudi::Details::PropertyBase& /*prop*/ ) { + m_setOutCollKey = true; + return; +} + +/// This internal method will realize if a user sets the 'SortVariable' property +inline void ParticleSortingAlg::setupSortVar( Gaudi::Details::PropertyBase& /*prop*/ ) +{ + m_setSortVar = true; + return; +} + +/// This internal method will realize if a user sets the 'SortDeceding' property +inline void ParticleSortingAlg::setupSortDescending( Gaudi::Details::PropertyBase& /*prop*/ ) +{ + m_setSortDescending = true; + return; +} + + +#endif //> !EVENTUTILS_PARTICLESORTINGALG_H diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..876c7e005d22ee27a6c552c9dd4a51180907afc3 --- /dev/null +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx @@ -0,0 +1,318 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// ParticleSortingTool.cxx +// Implementation file for class ParticleSortingTool +// Author: Karsten Koeneke <karsten.koeneke@cern.ch> +/////////////////////////////////////////////////////////////////// + +// EventUtils includes +#include "ParticleSortingTool.h" + +// EDM includes +#include "xAODBase/IParticle.h" +#include "xAODBase/IParticleContainer.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODJet/JetContainer.h" +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/PhotonContainer.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODPFlow/PFOContainer.h" +#include "xAODTracking/NeutralParticleContainer.h" +#include "xAODTracking/TrackParticleContainer.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODParticleEvent/CompositeParticleContainer.h" +#include "xAODParticleEvent/ParticleContainer.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "AthContainers/ConstDataVector.h" + +// Constructors +//////////////// +ParticleSortingTool::ParticleSortingTool( const std::string& type, + const std::string& name, + const IInterface* parent ) : + ::AthAlgTool ( type, name, parent ), + m_inCollKey(""), + m_outCollKey(""), + m_sortVar("pt"), + m_sortDescending(true), + m_contID(0), + m_sortID(0), + m_nEventsProcessed(0) +{ + declareInterface< DerivationFramework::IAugmentationTool >(this); + + declareProperty("InputContainer", m_inCollKey="", "Input container name" ); + + declareProperty("OutputContainer", m_outCollKey="", + "The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects" ); + + declareProperty("SortVariable", m_sortVar="pt", + "Define by what parameter to sort (default: 'pt'; allowed: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity')" ); + + declareProperty("SortDescending", m_sortDescending=true, + "Define if the container should be sorted in a descending order (default=true)" ); +} + + +// Destructor +/////////////// +ParticleSortingTool::~ParticleSortingTool() +{} + + + +// Athena algtool's Hooks +//////////////////////////// +StatusCode ParticleSortingTool::initialize() +{ + ATH_MSG_DEBUG ("Initializing " << name() << "..."); + + // Print out the used configuration + ATH_MSG_DEBUG ( " using = " << m_inCollKey ); + ATH_MSG_DEBUG ( " using = " << m_outCollKey ); + + // initialize the counters + m_contID = 0; + m_sortID = 0; + m_nEventsProcessed = 0; + + // Figure out how to sort + if ( m_sortVar.value() == "pt" ) { m_sortID = 1; } + else if ( m_sortVar.value() == "eta" ) { m_sortID = 2; } + else if ( m_sortVar.value() == "phi" ) { m_sortID = 3; } + else if ( m_sortVar.value() == "m" ) { m_sortID = 4; } + else if ( m_sortVar.value() == "e" ) { m_sortID = 5; } + else if ( m_sortVar.value() == "rapidity" ) { m_sortID = 6; } + else { + ATH_MSG_INFO("Didn't find a valid value for SortVariable=" << m_sortVar.value() << "." + << " Assuming it's an auxdata member"); + m_sortID = 7; + } + if ( m_sortDescending.value() ) { m_sortID *= -1; } + + return StatusCode::SUCCESS; +} + + + + +StatusCode ParticleSortingTool::finalize() +{ + ATH_MSG_DEBUG ("Finalizing " << name() << "..."); + + return StatusCode::SUCCESS; +} + + + +// Declare a short pre-processor macro to deal with the different container types +#define COPY_AND_SORT_CONTAINER( CONTAINERTYPE ) \ +else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \ + ATH_MSG_DEBUG("Trying to copy, sort, and record container of type "#CONTAINERTYPE ); \ + const CONTAINERTYPE* inCont; \ + ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \ + CONTAINERTYPE* outCont = new CONTAINERTYPE( SG::VIEW_ELEMENTS ); \ + *outCont = *inCont; \ + ATH_CHECK( evtStore()->record ( outCont, m_outCollKey.value() ) ); \ + ATH_CHECK( this->doSort(outCont) ); \ +} + + +// Declare a short pre-processor macro to deal with the different container types +#define OVERWRITE_AND_SORT_CONTAINER( CONTAINERTYPE ) \ +else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \ + ATH_MSG_DEBUG("Trying to copy, sort, and overwrite container of type "#CONTAINERTYPE ); \ + const CONTAINERTYPE* inCont; \ + ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \ + ConstDataVector<CONTAINERTYPE>* outCont = new ConstDataVector<CONTAINERTYPE>( SG::VIEW_ELEMENTS ); \ + for ( const CONTAINERTYPE::base_value_type* inPart : *inCont ){ \ + outCont->push_back(inPart); \ + } \ + ATH_CHECK( evtStore()->overwrite( outCont, m_inCollKey.value() ) ); \ + ATH_CHECK( this->doSortConst<CONTAINERTYPE>(outCont) ); \ +} + + + +StatusCode ParticleSortingTool::addBranches() const +{ + // Increase the event counter + ++m_nEventsProcessed; + + // Simple status message at the beginning of each event execute, + ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." ); + + if ( m_outCollKey.value().empty() ) { + // Try to get the input container as non-const + ATH_MSG_DEBUG("Got an empty 'OutputCollection' property. " + << "Trying to retrieve a non-const version of the 'InputContainer'..."); + xAOD::IParticleContainer* inCont = evtStore()->tryRetrieve<xAOD::IParticleContainer>( m_inCollKey.value() ); + if (inCont){ ATH_CHECK( this->doSort(inCont) ); } + else { + ATH_MSG_DEBUG("We couldn't retrieve a non-const version of the input container... try const."); + const xAOD::IParticleContainer* inCont2 = nullptr; + ATH_CHECK( evtStore()->retrieve( inCont2, m_inCollKey.value()) ); + // Now, do the copy and sorting and overwriting of all known container types + if (false) { + } + OVERWRITE_AND_SORT_CONTAINER(xAOD::MuonContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::ElectronContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::PhotonContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::TauJetContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::JetContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::PFOContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::NeutralParticleContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::TrackParticleContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::TruthParticleContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::CompositeParticleContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::ParticleContainer) + OVERWRITE_AND_SORT_CONTAINER(xAOD::CaloClusterContainer) + else { + ATH_MSG_ERROR("Couln't find the provided intput container in store gate for later overwriting"); + return StatusCode::FAILURE; + } + } + } + else { + ATH_MSG_DEBUG("Got a non-empty 'OutputCollection' property. " + << "Trying to retrieve a const version of the 'InputContainer'..."); + + // Now, do the copy and sorting of all known container types + if (false) { + } + COPY_AND_SORT_CONTAINER(xAOD::MuonContainer) + COPY_AND_SORT_CONTAINER(xAOD::ElectronContainer) + COPY_AND_SORT_CONTAINER(xAOD::PhotonContainer) + COPY_AND_SORT_CONTAINER(xAOD::TauJetContainer) + COPY_AND_SORT_CONTAINER(xAOD::JetContainer) + COPY_AND_SORT_CONTAINER(xAOD::PFOContainer) + COPY_AND_SORT_CONTAINER(xAOD::NeutralParticleContainer) + COPY_AND_SORT_CONTAINER(xAOD::TrackParticleContainer) + COPY_AND_SORT_CONTAINER(xAOD::TruthParticleContainer) + COPY_AND_SORT_CONTAINER(xAOD::CompositeParticleContainer) + COPY_AND_SORT_CONTAINER(xAOD::ParticleContainer) + COPY_AND_SORT_CONTAINER(xAOD::CaloClusterContainer) + else { + ATH_MSG_ERROR("Couln't find the provided intput container in store gate"); + return StatusCode::FAILURE; + } + + } + + return StatusCode::SUCCESS; +} + + + +StatusCode ParticleSortingTool::doSort( xAOD::IParticleContainer* cont ) const +{ + if ( !cont ) { + ATH_MSG_ERROR("No container to be sorted"); + return StatusCode::FAILURE; + } + // Actually do the sorting, using a C++11 lambda function construct + // to be able to use the member function here + if ( std::abs(m_sortID) == 1 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->comparePt(a,b); + } ); + } + else if ( std::abs(m_sortID) == 2 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareEta(a,b); + } ); + } + else if ( std::abs(m_sortID) == 3 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->comparePhi(a,b); + } ); + } + else if ( std::abs(m_sortID) == 4 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareMass(a,b); + } ); + } + else if ( std::abs(m_sortID) == 5 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareEnergy(a,b); + } ); + } + else if ( std::abs(m_sortID) == 6 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareRapidity(a,b); + } ); + } + else if ( std::abs(m_sortID) == 7 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareAuxData(a,b); + } ); + } + + return StatusCode::SUCCESS; +} + + +bool ParticleSortingTool::comparePt( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->pt(); + const double b = partB->pt(); + return this->compareDouble(a,b); +} + + +bool ParticleSortingTool::compareEta( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->eta(); + const double b = partB->eta(); + return this->compareDouble(a,b); +} + + +bool ParticleSortingTool::comparePhi( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->phi(); + const double b = partB->phi(); + return this->compareDouble(a,b); +} + + +bool ParticleSortingTool::compareMass( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->m(); + const double b = partB->m(); + return this->compareDouble(a,b); +} + + +bool ParticleSortingTool::compareEnergy( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->e(); + const double b = partB->e(); + return this->compareDouble(a,b); +} + + +bool ParticleSortingTool::compareRapidity( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->rapidity(); + const double b = partB->rapidity(); + return this->compareDouble(a,b); +} + +bool ParticleSortingTool::compareAuxData( const xAOD::IParticle* partA, + const xAOD::IParticle* partB ) const +{ + const double a = partA->auxdata<float>( this->m_sortVar.value() ); + const double b = partB->auxdata<float>( this->m_sortVar.value() ); + return this->compareDouble(a,b); +} diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h new file mode 100644 index 0000000000000000000000000000000000000000..dc097711cfb25798ce5dcdc24dd85b4188fc18b1 --- /dev/null +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h @@ -0,0 +1,183 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// ParticleSortingTool.h +// Header file for class ParticleSortingTool +// Author: Karsten Koeneke <karsten.koeneke@cern.ch> +/////////////////////////////////////////////////////////////////// +#ifndef EVENTUTILS_PARTICLESORTINGTOOL_H +#define EVENTUTILS_PARTICLESORTINGTOOL_H 1 + +// FrameWork includes +#include "AthenaBaseComps/AthAlgTool.h" +#include "DerivationFrameworkInterfaces/IAugmentationTool.h" +#include "CxxUtils/fpcompare.h" + +// EDM inlcudes +#include "xAODBase/IParticle.h" +#include "xAODBase/IParticleContainer.h" +#include "AthContainers/ConstDataVector.h" + +// STL includes +#include <vector> +#include <string> +#include <cmath> + +class ParticleSortingTool + : virtual public ::DerivationFramework::IAugmentationTool, + public ::AthAlgTool +{ + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// +public: + + // Copy constructor: + + /// Constructor with parameters: + ParticleSortingTool( const std::string& type, + const std::string& name, + const IInterface* parent ); + + /// Destructor: + virtual ~ParticleSortingTool(); + + /// Athena algtool's initialize + virtual StatusCode initialize() override; + + /// Athena algtool's finalize + virtual StatusCode finalize() override; + + + /// Implement the method from the ISkimmingTool interface + virtual StatusCode addBranches() const final override; + + + +// Private methods +private: + + /// Helper method that implements the call to the right sort function + StatusCode doSort( xAOD::IParticleContainer* cont ) const; + + /// Helper method to sort a ConstDataVector + template<class CONTAINERTYPE> + StatusCode doSortConst( ConstDataVector<CONTAINERTYPE>* cont ) const; + + /// The method to compare the particle's pt + bool comparePt( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare the particle's eta + bool compareEta( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare the particle's phi + bool comparePhi( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare the particle's mass + bool compareMass( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare the particle's energy + bool compareEnergy( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare the particle's rapidity + bool compareRapidity( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// The method to compare an auxdata member of the particle + bool compareAuxData( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const; + + /// Method to compare two doubles + inline bool compareDouble( double a, double b ) const; + + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// +private: + + /// Input container name + StringProperty m_inCollKey; + + /// The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects + StringProperty m_outCollKey; + + /// Define by what parameter to sort (default: 'pt') + StringProperty m_sortVar; + + /// Define if the container should be sorted in a descending order (default=true) + BooleanProperty m_sortDescending; + + + /// Internal container type identifier + mutable unsigned int m_contID; + + /// Internal identifier for the type of sorting + mutable int m_sortID; + + /// Internal event counter + mutable unsigned long m_nEventsProcessed; + +}; + + +inline bool ParticleSortingTool::compareDouble( double a, double b ) const +{ + if ( m_sortID < 0 ) { return CxxUtils::fpcompare::greater(a,b); } + else { return CxxUtils::fpcompare::less(a,b); } +} + + +template<class CONTAINERTYPE> +StatusCode ParticleSortingTool::doSortConst( ConstDataVector<CONTAINERTYPE>* cont ) const +{ + if ( !cont ) { + ATH_MSG_ERROR("No ConstDataVector to be sorted"); + return StatusCode::FAILURE; + } + // Actually do the sorting, using a C++11 lambda function construct + // to be able to use the member function here + if ( std::abs(m_sortID) == 1 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->comparePt(a,b); + } ); + } + else if ( std::abs(m_sortID) == 2 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareEta(a,b); + } ); + } + else if ( std::abs(m_sortID) == 3 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->comparePhi(a,b); + } ); + } + else if ( std::abs(m_sortID) == 4 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareMass(a,b); + } ); + } + else if ( std::abs(m_sortID) == 5 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareEnergy(a,b); + } ); + } + else if ( std::abs(m_sortID) == 6 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareRapidity(a,b); + } ); + } + else if ( std::abs(m_sortID) == 7 ) { + cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) { + return this->compareAuxData(a,b); + } ); + } + + return StatusCode::SUCCESS; +} + + + +#endif //> !EVENTUTILS_PARTICLESORTINGTOOL_H diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx index 4a60ef060d833692aeaa4e0acef5b62e3d1e69be..1f217ab44bc034c41a03ce489c916891a10c2e04 100644 --- a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx +++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx @@ -1,3 +1,5 @@ +#include "../ParticleSortingTool.h" +#include "../ParticleSortingAlg.h" #include "../CutTool.h" #include "../CutAlg.h" #include "../ParticleSelectionTool.h" @@ -7,6 +9,8 @@ #include "../TriggerSelectionAlg.h" #include "../EventDecisionAlg.h" +DECLARE_COMPONENT( ParticleSortingTool ) +DECLARE_COMPONENT( ParticleSortingAlg ) DECLARE_COMPONENT( CutTool ) DECLARE_COMPONENT( CutAlg ) DECLARE_COMPONENT( ParticleSelectionTool ) @@ -15,4 +19,3 @@ DECLARE_COMPONENT( EventQualityFilterAlg ) DECLARE_COMPONENT( ParticleRemoverAlg ) DECLARE_COMPONENT( TriggerSelectionAlg ) DECLARE_COMPONENT( EventDecisionAlg ) - diff --git a/PhysicsAnalysis/AnalysisCommon/PATCore/PATCore/IAsgSelectionTool.h b/PhysicsAnalysis/AnalysisCommon/PATCore/PATCore/IAsgSelectionTool.h index 791dea0bd9e28e910ff64d45da45849ab38590df..6e8e2db1902e75551b246c6bc9f1b8bcdc3696f9 100644 --- a/PhysicsAnalysis/AnalysisCommon/PATCore/PATCore/IAsgSelectionTool.h +++ b/PhysicsAnalysis/AnalysisCommon/PATCore/PATCore/IAsgSelectionTool.h @@ -1,7 +1,7 @@ ///////////////////////// -*- C++ -*- ///////////////////////////// /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ // IAsgSelectionTool.h @@ -11,9 +11,6 @@ #ifndef PATCORE_IASGSELECTIONTOOL_H #define PATCORE_IASGSELECTIONTOOL_H 1 -// STL includes - - // FrameWork includes #include "AsgTools/IAsgTool.h" @@ -26,7 +23,6 @@ namespace xAOD{ class IParticle; } - class IAsgSelectionTool : virtual public asg::IAsgTool { @@ -51,6 +47,6 @@ class IAsgSelectionTool virtual asg::AcceptData accept( const xAOD::IParticle* /*part*/ ) const = 0; -}; +}; #endif //> !PATCORE_IASGSELECTIONTOOL_H