diff --git a/Reconstruction/PFlow/PFlowUtils/share/PFlowCalibHitDecorator_algorithms.py b/Reconstruction/PFlow/PFlowUtils/share/PFlowCalibHitDecorator_algorithms.py index c816b24d85495a105fd65de617735c89233f2a3a..037313837959564dd467ee332e202310091ef26f 100644 --- a/Reconstruction/PFlow/PFlowUtils/share/PFlowCalibHitDecorator_algorithms.py +++ b/Reconstruction/PFlow/PFlowUtils/share/PFlowCalibHitDecorator_algorithms.py @@ -14,4 +14,9 @@ from PFlowUtils.PFlowUtilsConf import PFlowCalibPFODecoratorAlgorithm PFlowCalibPFODecoratorAlgorithm = PFlowCalibPFODecoratorAlgorithm() PFlowCalibPFOTruthAttributerTool = CalibClusterTruthAttributerTool("PFlowCalibPFOTruthAttributerTool") PFlowCalibPFODecoratorAlgorithm.TruthAttributerTool = PFlowCalibPFOTruthAttributerTool +#allow flow element decoration if the eflowRec JO permits it +from eflowRec.eflowRecFlags import jobproperties +if(jobproperties.eflowRecFlags.useFlowElements==True): + PFlowCalibPFODecoratorAlgorithm.useFlowElements=True + topSequence+=PFlowCalibPFODecoratorAlgorithm diff --git a/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.cxx b/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.cxx index 851aa7bc421dc60757e429d056d9ac82df31ee83..1cdca27aa3d3725bbada89cf6fda7e21717f436f 100644 --- a/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.cxx +++ b/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.cxx @@ -1,5 +1,5 @@ /* - 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 "PFlowCalibPFODecoratorAlgorithm.h" @@ -13,17 +13,63 @@ StatusCode PFlowCalibPFODecoratorAlgorithm::initialize(){ ATH_CHECK(m_mapTruthBarcodeToTruthParticleReadHandleKey.initialize()); ATH_CHECK(m_pfoWriteDecorHandleKeyNLeadingTruthParticles.initialize()); + ATH_CHECK(m_feWriteDecorHandleKeyNLeadingTruthParticles.initialize()); ATH_CHECK(m_truthAttributerTool.retrieve()); return StatusCode::SUCCESS; } +StatusCode PFlowCalibPFODecoratorAlgorithm::LinkCalibHitPFO( +SG::WriteDecorHandle<xAOD::PFOContainer, std::vector< std::pair<unsigned int, double> > >& pfoWriteDecorHandle, +SG::ReadHandle<std::map<Identifier,std::vector<const CaloCalibrationHit*> > >& CalibHitReadHandle, +SG::ReadHandle<std::map<unsigned int,const xAOD::TruthParticle* > >& TruthParticleHandle +) const +{ + //Algorithm to produce links between PFO and CalibHits + StatusCode sc; + for (auto thisPFO : *pfoWriteDecorHandle){ + + const xAOD::CaloCluster* thisCaloCluster = thisPFO->cluster(0); + + std::vector<std::pair<unsigned int, double > > newBarCodeTruthPairs; + sc = m_truthAttributerTool->calculateTruthEnergies(*thisCaloCluster, m_numTruthParticles, *CalibHitReadHandle, *TruthParticleHandle, newBarCodeTruthPairs); + if (sc == StatusCode::FAILURE) return sc; + + for (const auto& thisPair : newBarCodeTruthPairs) ATH_MSG_DEBUG("Cluster Final loop: Particle with barcode " << thisPair.first << " has truth energy of " << thisPair.second << " for cluster with e, eta " << thisCaloCluster->e() << " and " << thisCaloCluster->eta()); + + pfoWriteDecorHandle(*thisPFO) = newBarCodeTruthPairs; + } + return StatusCode::SUCCESS; +} +// Same algorithm for FE as for PFO +StatusCode PFlowCalibPFODecoratorAlgorithm::LinkCalibHitPFO( +SG::WriteDecorHandle<xAOD::FlowElementContainer, std::vector< std::pair<unsigned int, double> > >& pfoWriteDecorHandle, +SG::ReadHandle<std::map<Identifier,std::vector<const CaloCalibrationHit*> > >& CalibHitReadHandle, +SG::ReadHandle<std::map<unsigned int,const xAOD::TruthParticle* > >& TruthParticleHandle)const +{ + + StatusCode sc; + for (auto thisFE : *pfoWriteDecorHandle){ + // retrieve calo cluster, first as the iparticle we retrieve then cast to calocluster ptr + const xAOD::IParticle* FE_Iparticle=thisFE->otherObjects().at(0); + const xAOD::CaloCluster* thisCaloCluster = dynamic_cast<const xAOD::CaloCluster*>(FE_Iparticle); + + std::vector<std::pair<unsigned int, double > > newBarCodeTruthPairs; + sc = m_truthAttributerTool->calculateTruthEnergies(*thisCaloCluster, m_numTruthParticles, *CalibHitReadHandle, *TruthParticleHandle, newBarCodeTruthPairs); + if (sc == StatusCode::FAILURE) return sc; + + for (const auto& thisPair : newBarCodeTruthPairs) ATH_MSG_DEBUG("Cluster Final loop: Particle with barcode " << thisPair.first << " has truth energy of " << thisPair.second << " for cluster with e, eta " << thisCaloCluster->e() << " and " << thisCaloCluster->eta()); + + pfoWriteDecorHandle(*thisFE) = newBarCodeTruthPairs; + } + return StatusCode::SUCCESS; +} StatusCode PFlowCalibPFODecoratorAlgorithm::execute(const EventContext& ctx) const{ SG::ReadHandle<std::map<Identifier,std::vector<const CaloCalibrationHit*> > > mapIdentifierToCalibHitsReadHandle(m_mapIdentifierToCalibHitsReadHandleKey, ctx); if(!mapIdentifierToCalibHitsReadHandle.isValid()){ - ATH_MSG_WARNING("Could not retrieve map between Identifier and calibraiton hits from Storegae"); + ATH_MSG_WARNING("Could not retrieve map between Identifier and calibraiton hits from Storegate"); return StatusCode::FAILURE; } @@ -32,22 +78,21 @@ StatusCode PFlowCalibPFODecoratorAlgorithm::execute(const EventContext& ctx) con ATH_MSG_WARNING("Could not retrieve map between truth barcode and truth particle from Storegate"); return StatusCode::FAILURE; } - + // pfo linker alg SG::WriteDecorHandle<xAOD::PFOContainer, std::vector< std::pair<unsigned int, double> > > pfoWriteDecorHandleNLeadingTruthParticles(m_pfoWriteDecorHandleKeyNLeadingTruthParticles, ctx); - StatusCode sc; - - for (auto thisPFO : *pfoWriteDecorHandleNLeadingTruthParticles){ + ATH_CHECK(this->LinkCalibHitPFO( + pfoWriteDecorHandleNLeadingTruthParticles, + mapIdentifierToCalibHitsReadHandle, + mapTruthBarcodeToTruthParticleReadHandle)); // end of check block - const xAOD::CaloCluster* thisCaloCluster = thisPFO->cluster(0); - - std::vector<std::pair<unsigned int, double > > newBarCodeTruthPairs; - sc = m_truthAttributerTool->calculateTruthEnergies(*thisCaloCluster, m_numTruthParticles, *mapIdentifierToCalibHitsReadHandle, *mapTruthBarcodeToTruthParticleReadHandle, newBarCodeTruthPairs); - if (sc == StatusCode::FAILURE) return sc; + if(m_useFlowElements){ + SG::WriteDecorHandle<xAOD::FlowElementContainer,std::vector<std::pair<unsigned int, double> > > feWriteDecorHandleNLeadingTruthParticles(m_feWriteDecorHandleKeyNLeadingTruthParticles,ctx); - for (const auto& thisPair : newBarCodeTruthPairs) ATH_MSG_DEBUG("Cluster Final loop: Particle with barcode " << thisPair.first << " has truth energy of " << thisPair.second << " for cluster with e, eta " << thisCaloCluster->e() << " and " << thisCaloCluster->eta()); - - pfoWriteDecorHandleNLeadingTruthParticles(*thisPFO) = newBarCodeTruthPairs; + ATH_CHECK(this->LinkCalibHitPFO( + feWriteDecorHandleNLeadingTruthParticles, + mapIdentifierToCalibHitsReadHandle, + mapTruthBarcodeToTruthParticleReadHandle)); // end of check block } return StatusCode::SUCCESS; diff --git a/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.h b/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.h index 0ab272466cb2fba706663d0dd87d6f1aae0a5984..72c2ebcec4cf435a6610e3a1d679244a35742eb4 100644 --- a/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.h +++ b/Reconstruction/PFlow/PFlowUtils/src/PFlowCalibPFODecoratorAlgorithm.h @@ -1,5 +1,5 @@ /* - 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 PFLOWCALIBPFODECORATORALGORITHM_H @@ -15,11 +15,15 @@ //EDM Container Classes #include "xAODPFlow/PFOContainer.h" +#include "xAODPFlow/FlowElementContainer.h" //C++ classes #include <map> #include <vector> +//Core classes for some private function classdefs +#include "StoreGate/WriteDecorHandle.h" + /** This algorithm decorates xAOD::PFO with calibration hit truth information It relies on upstream creation of several maps in CaloCalibClusterTruthMapMakerAlgorithm, stored in Storegate, to provide fast access to required information. @@ -41,6 +45,7 @@ public: virtual StatusCode finalize() override; private: + /** ReadHandleKey for the map between Identifiers and sets of calibration hits */ SG::ReadHandleKey<std::map<Identifier,std::vector<const CaloCalibrationHit*> > > m_mapIdentifierToCalibHitsReadHandleKey{this,"IdentifierToCalibHitsMapName","IdentifierToCalibHitsMap","ReadHandleKey for the map between Identifieirs and sets of calibration hits"}; @@ -50,11 +55,29 @@ private: /** Write handle key to decorate PFO with threeN leading truth particle barcode and energy */ SG::WriteDecorHandleKey<xAOD::PFOContainer> m_pfoWriteDecorHandleKeyNLeadingTruthParticles{this,"PFOWriteDecorHandleKey_NLeadingTruthParticles","JetETMissNeutralParticleFlowObjects.calpfo_NLeadingTruthParticleBarcodeEnergyPairs"}; + /** Write handle key to decorate Flow Element with three N leading truth particle barcode and energy (similar implementation as for PFO) */ + SG::WriteDecorHandleKey<xAOD::FlowElementContainer> m_feWriteDecorHandleKeyNLeadingTruthParticles{this,"FlowElementWriteDecorHandleKey_NLeadingTruthParticles","JetETMissNeutralFlowElements.calfe_NLeadingTruthParticleBarcodeEnergyPairs"}; + /** ToolHandle to a tool to create the calibration hit truth information that we need for the decoration */ ToolHandle<ICaloCalibClusterTruthAttributerTool> m_truthAttributerTool{this,"TruthAttributerTool",""," ToolHandle to a tool to create the calibration hit truth information that we need for the decoration"}; /** Allow user to set the number of truth particles per clusterCaloCluster or PFO, in descending pt order, for which to store calibration hit enery */ Gaudi::Property<unsigned int> m_numTruthParticles{this,"NumTruthParticles",3,"Set number of truth particles per CaloCluster/PFO for which we store calibration hit energy"}; + + + Gaudi::Property<bool> m_useFlowElements{this,"useFlowElements",false,"Set decoration of flow element container as well as PFO"}; + + // functions to do the links between either PFO or FlowElements + StatusCode LinkCalibHitPFO( + SG::WriteDecorHandle<xAOD::FlowElementContainer, std::vector< std::pair<unsigned int, double> > >& pfoWriteDecorHandle, + SG::ReadHandle<std::map<Identifier,std::vector<const CaloCalibrationHit*> > >& CalibHitHandle, + SG::ReadHandle<std::map<unsigned int,const xAOD::TruthParticle* > >& TruthParticleHandle) const; + + StatusCode LinkCalibHitPFO( + SG::WriteDecorHandle<xAOD::PFOContainer, std::vector< std::pair<unsigned int, double> > >& pfoWriteDecorHandle, + SG::ReadHandle<std::map<Identifier,std::vector<const CaloCalibrationHit*> > >& CalibHitHandle, + SG::ReadHandle<std::map<unsigned int,const xAOD::TruthParticle* > >& TruthParticleHandle + ) const; }; #endif