diff --git a/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h b/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h index a97a52392c333f41b65407dfd0c1b598da8c5286..a1b989446149ac9a04c0c55e90ebdba60aceeab1 100644 --- a/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h +++ b/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h @@ -1,18 +1,18 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef PFOCHARGEDCREATORALGORITHM_H #define PFOCHARGEDCREATORALGORITHM_H #include "eflowRec/eflowCaloObject.h" -#include "AthenaBaseComps/AthAlgorithm.h" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" #include "GaudiKernel/ToolHandle.h" #include "StoreGate/DataHandle.h" #include "xAODPFlow/PFOContainer.h" -class PFOChargedCreatorAlgorithm : public AthAlgorithm { +class PFOChargedCreatorAlgorithm : public AthReentrantAlgorithm { public: @@ -21,14 +21,12 @@ public: ~PFOChargedCreatorAlgorithm() {} StatusCode initialize(); - StatusCode execute(); + StatusCode execute(const EventContext&) const; StatusCode finalize(); private: /** Create the charged PFO */ - void createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters, SG::WriteHandle<xAOD::PFOContainer>& chargedPFOContainerWriteHandle); - /** Function to add links to the vertex to which a charged PFO is matched (using the tracking CP loose vertex association tool) */ - void addVertexLinksToChargedPFO(const xAOD::VertexContainer* theVertexContainer, SG::WriteHandle<xAOD::PFOContainer>& chargedPFOContainerWriteHandle); + void createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters, SG::WriteHandle<xAOD::PFOContainer>& chargedPFOContainerWriteHandle) const; /** Toggle EOverP algorithm mode, whereby no charged shower subtraction is performed */ Gaudi::Property<bool> m_eOverPMode{this,"EOverPMode",false,"Toggle EOverP algorithm mode, whereby no charged shower subtraction is performed"}; diff --git a/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h b/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h index eb930ce28e471bcbfc6938236264dd3ad183b87f..40b7b7c2d558d51536dc21b0d1db187a8927de79 100644 --- a/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h +++ b/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h @@ -1,12 +1,12 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef PFONEUTRALCREATORALGORITHM_H #define PFONEUTRALCREATORALGORITHM_H #include "eflowRec/eflowCaloObject.h" -#include "AthenaBaseComps/AthAlgorithm.h" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" #include "GaudiKernel/ToolHandle.h" #include "StoreGate/DataHandle.h" @@ -14,7 +14,7 @@ #include "xAODPFlow/PFO.h" #include "xAODPFlow/PFOContainer.h" -class PFONeutralCreatorAlgorithm : public AthAlgorithm { +class PFONeutralCreatorAlgorithm : public AthReentrantAlgorithm { public: @@ -25,16 +25,16 @@ public: static const InterfaceID& interfaceID(); StatusCode initialize(); - StatusCode execute(); + StatusCode execute(const EventContext& ctx) const; StatusCode finalize(); private: /** Create the chargedneutral PFO */ - void createNeutralPFO(const eflowCaloObject& energyFlowCaloObject,SG::WriteHandle<xAOD::PFOContainer>& neutralPFOContainerWriteHandle, SG::WriteHandle<xAOD::PFOContainer>* neutralPFOContainerWriteHandle_nonModified); + StatusCode createNeutralPFO(const eflowCaloObject& energyFlowCaloObject, xAOD::PFOContainer* neutralPFOContainer, xAOD::PFOContainer* neutralPFOContainer_nonModified) const; /** Function to add cluster moments onto PFO */ - void addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO); + void addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO) const; /** Toggle EOverP algorithm mode, whereby no charged shower subtraction is performed */ Gaudi::Property<bool> m_eOverPMode{this,"EOverPMode",false,"Toggle EOverP algorithm mode, whereby no charged shower subtraction is performed"}; diff --git a/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx index fce83ce909c57b149005008fc8398fc653809a82..a9611817b9ed690aa234ab52cacce6119cfc282b 100644 --- a/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx +++ b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx @@ -1,9 +1,11 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "eflowRec/PFOChargedCreatorAlgorithm.h" +#include <algorithm> + #include "eflowRec/eflowRecCluster.h" #include "eflowRec/eflowRecTrack.h" #include "eflowRec/eflowTrackClusterLink.h" @@ -11,7 +13,7 @@ #include "xAODPFlow/PFOAuxContainer.h" PFOChargedCreatorAlgorithm::PFOChargedCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator) : - AthAlgorithm(name,pSvcLocator) + AthReentrantAlgorithm(name,pSvcLocator) { } @@ -24,23 +26,25 @@ StatusCode PFOChargedCreatorAlgorithm::initialize(){ return StatusCode::SUCCESS; } -StatusCode PFOChargedCreatorAlgorithm::execute(){ +StatusCode PFOChargedCreatorAlgorithm::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("Processing eflowCaloObjectContainer"); - SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle(m_chargedPFOContainerWriteHandleKey); + SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle(m_chargedPFOContainerWriteHandleKey,ctx); ATH_CHECK(chargedPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); /* Create Charged PFOs from all eflowCaloObjects */ - SG::ReadHandle<eflowCaloObjectContainer> eflowCaloObjectContainerReadHandle(m_eflowCaloObjectContainerReadHandleKey); + SG::ReadHandle<eflowCaloObjectContainer> eflowCaloObjectContainerReadHandle(m_eflowCaloObjectContainerReadHandleKey,ctx); for (auto thisEflowCaloObject : *eflowCaloObjectContainerReadHandle) createChargedPFO(*thisEflowCaloObject,true,chargedPFOContainerWriteHandle); + std::sort(chargedPFOContainerWriteHandle->begin(), chargedPFOContainerWriteHandle->end(), [] (const xAOD::PFO* pfo1, const xAOD::PFO* pfo2) {return pfo1->pt()>pfo2->pt();}); + return StatusCode::SUCCESS; } StatusCode PFOChargedCreatorAlgorithm::finalize(){ return StatusCode::SUCCESS; } -void PFOChargedCreatorAlgorithm::createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters, SG::WriteHandle<xAOD::PFOContainer>& chargedPFOContainerWriteHandle){ +void PFOChargedCreatorAlgorithm::createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters, SG::WriteHandle<xAOD::PFOContainer>& chargedPFOContainerWriteHandle) const { /* Loop over all tracks in the eflowCaloObject */ int nTracks = energyFlowCaloObject.nTracks(); diff --git a/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx index f42045c56da39bb1dc912580b550a9316298b149..00dd296913bb947fc4285cd56c7f52c63ee85313 100644 --- a/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx +++ b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx @@ -1,9 +1,11 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "eflowRec/PFONeutralCreatorAlgorithm.h" +#include <algorithm> + #include "eflowRec/eflowCaloObject.h" #include "eflowRec/eflowRecCluster.h" #include "eflowRec/eflowTrackClusterLink.h" @@ -11,7 +13,7 @@ #include "xAODPFlow/PFOAuxContainer.h" PFONeutralCreatorAlgorithm::PFONeutralCreatorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator) : - AthAlgorithm(name, pSvcLocator) + AthReentrantAlgorithm(name, pSvcLocator) { } @@ -26,29 +28,51 @@ StatusCode PFONeutralCreatorAlgorithm::initialize(){ } -StatusCode PFONeutralCreatorAlgorithm::execute(){ +StatusCode PFONeutralCreatorAlgorithm::execute(const EventContext& ctx) const { ATH_MSG_DEBUG("Executing"); - SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle(m_neutralPFOContainerWriteHandleKey); - ATH_CHECK(neutralPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); - std::unique_ptr<SG::WriteHandle<xAOD::PFOContainer> > p_neutralPFOContainerWriteHandle_nonModified(nullptr); - if (m_LCMode) { - p_neutralPFOContainerWriteHandle_nonModified = std::make_unique<SG::WriteHandle<xAOD::PFOContainer> >(m_neutralPFOContainerWriteHandleKey_nonModified); - ATH_CHECK(p_neutralPFOContainerWriteHandle_nonModified->record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); - } - /* Create Neutral PFOs from all eflowCaloObjects */ - SG::ReadHandle<eflowCaloObjectContainer> eflowCaloObjectContainerReadHandle(m_eflowCaloObjectContainerReadHandleKey); + SG::ReadHandle<eflowCaloObjectContainer> eflowCaloObjectContainerReadHandle(m_eflowCaloObjectContainerReadHandleKey,ctx); + + // Always create at least one PFO container & aux + auto neutralPFOContainer = std::make_unique<xAOD::PFOContainer>(); + auto neutralPFOContainerAux = std::make_unique<xAOD::PFOAuxContainer>(); + neutralPFOContainer->setStore(neutralPFOContainerAux.get()); + // The non-modified container is only used for LC PFOs + std::unique_ptr<xAOD::PFOContainer> neutralPFOContainer_nonModified(nullptr); + std::unique_ptr<xAOD::PFOAuxContainer> neutralPFOContainerAux_nonModified(nullptr); + if(m_LCMode) { + neutralPFOContainer_nonModified = std::make_unique<xAOD::PFOContainer>(); + neutralPFOContainerAux_nonModified = std::make_unique<xAOD::PFOAuxContainer>(); + neutralPFOContainer->setStore(neutralPFOContainerAux_nonModified.get()); + } + ATH_MSG_DEBUG("Looping over eflowCaloObjects"); - for (auto thisEflowCaloObject : *eflowCaloObjectContainerReadHandle) createNeutralPFO(*thisEflowCaloObject, neutralPFOContainerWriteHandle, p_neutralPFOContainerWriteHandle_nonModified.get()); + // Create PFOs and fill the containers + for (auto thisEflowCaloObject : *eflowCaloObjectContainerReadHandle) { + if( createNeutralPFO(*thisEflowCaloObject, neutralPFOContainer.get(), neutralPFOContainer_nonModified.get()).isFailure() ) { + ATH_MSG_WARNING("Problem encountered while creating neutral PFOs"); + return StatusCode::SUCCESS; + } + } + + // Record the output containers + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle(m_neutralPFOContainerWriteHandleKey,ctx); + std::sort(neutralPFOContainer->begin(), neutralPFOContainer->end(), [] (const xAOD::PFO* pfo1, const xAOD::PFO* pfo2) {return pfo1->pt()>pfo2->pt();}); + ATH_CHECK( neutralPFOContainerWriteHandle.record(std::move(neutralPFOContainer),std::move(neutralPFOContainerAux)) ); + if(m_LCMode) { + std::sort(neutralPFOContainer_nonModified->begin(), neutralPFOContainer_nonModified->end(), [] (const xAOD::PFO* pfo1, const xAOD::PFO* pfo2) {return pfo1->pt()>pfo2->pt();}); + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle_nonModified(m_neutralPFOContainerWriteHandleKey,ctx); + ATH_CHECK( neutralPFOContainerWriteHandle_nonModified.record(std::move(neutralPFOContainer_nonModified),std::move(neutralPFOContainerAux_nonModified)) ); + } return StatusCode::SUCCESS; } StatusCode PFONeutralCreatorAlgorithm::finalize(){ return StatusCode::SUCCESS; } -void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyFlowCaloObject,SG::WriteHandle<xAOD::PFOContainer>& neutralPFOContainerWriteHandle, SG::WriteHandle<xAOD::PFOContainer>* neutralPFOContainerWriteHandle_nonModified){ +StatusCode PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyFlowCaloObject, xAOD::PFOContainer* neutralPFOContainer, xAOD::PFOContainer* neutralPFOContainer_nonModified) const { unsigned int nClusters = energyFlowCaloObject.nClusters(); @@ -72,12 +96,17 @@ void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyF xAOD::PFO* thisPFO = new xAOD::PFO(); if (m_LCMode) { if (thisEfRecCluster->isTouchable()) { - neutralPFOContainerWriteHandle->push_back(thisPFO); + neutralPFOContainer->push_back(thisPFO); } else { - (*neutralPFOContainerWriteHandle_nonModified)->push_back(thisPFO); + if(neutralPFOContainer_nonModified) { + neutralPFOContainer_nonModified->push_back(thisPFO); + } else { + ATH_MSG_WARNING("Got a nullptr for non-modified nPFO container!"); + return StatusCode::FAILURE; + } } } else { - neutralPFOContainerWriteHandle->push_back(thisPFO); + neutralPFOContainer->push_back(thisPFO); } ATH_MSG_VERBOSE(" Get original cluster link"); @@ -278,9 +307,10 @@ void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyF thisPFO->setAttribute(myAttribute_TIMING, clusterTiming); } } + return StatusCode::SUCCESS; } -void PFONeutralCreatorAlgorithm::addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO){ +void PFONeutralCreatorAlgorithm::addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO) const { double moment = 0.0; bool isRetrieved = theCluster.retrieveMoment(momentType, moment);