diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METAssociationTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociationTool.h new file mode 100644 index 0000000000000000000000000000000000000000..17225519ae3a2f6c9dff64e7f6f4eae9f77b6711 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociationTool.h @@ -0,0 +1,117 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssociationTool.h +// Header file for class METAssociationTool +// +// This is a scheduler for the MET Reconstruction, and sets up +// the sequence in which the individual terms are constructed. +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METASSOCIATIONTOOL_H +#define METRECONSTRUCTION_METASSOCIATIONTOOL_H 1 + +// STL includes +#include <string> + +// FrameWork includes +#include "AsgTools/ToolHandle.h" +#include "AsgTools/AsgTool.h" + +// METRecoInterface includes +#include "METRecoInterface/IMETRecoTool.h" +#include "METRecoInterface/IMETAssocToolBase.h" + +// EDM includes +#include "xAODMissingET/MissingETContainer.h" +#include "xAODMissingET/MissingETAssociationMap.h" +#include "xAODMissingET/MissingETAuxAssociationMap.h" + +// Timing +#include "TStopwatch.h" + +// Forward declaration + +namespace met{ + /* @brief Top-level class scheduling MET reconstruction tools + * + * @author Peter Loch <loch_AT_physics.arizona.edu> + * @author Silvia Resconi <Silvia.Resconi_AT_cern.ch> + * @author Teng Jian Khoo <Teng.Jian.Khoo_AT_cern.ch> + * + * @date Nov. 21, 2013 + * @version v1.0 + * + * The METAssociationTool can be called within an Athena algorithm or a ROOT programme + * to carry out the reconstruction of a MET configuration, and will produce a + * MissingETContainer, the contents of which will be the MissingET objects produced + * by the various tools scheduled by METAssociationTool. + * + */ + class METAssociationTool final + : virtual public asg::AsgTool, + virtual public IMETRecoTool + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METAssociationTool, IMETRecoTool) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name (does this have to be a non-const + // std::string and not a const reference?) + METAssociationTool(const std::string& name); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode execute() const; + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + + /// Default constructor: + METAssociationTool(); + virtual ~METAssociationTool(); + + // Run the MET tools here + StatusCode buildMET(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const; + + // Data members + std::string m_metsuffix; + std::string m_mapname; + std::string m_corename; + ToolHandleArray<IMETAssocToolBase> m_metassociators; + + }; + +} + +// I/O operators +////////////////////// + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + + +#endif //> !METRECONSTRUCTION_METASSOCIATIONTOOL_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..8173aebbbb6c10817ffe0d4956f4777dd990f4ee --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METAssociator.h @@ -0,0 +1,124 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssociator.h +// Header file for class METAssociator +// +// This is the base class for tools that construct MET terms +// from other object collections. +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METASSOCIATOR_H +#define METRECONSTRUCTION_METASSOCIATOR_H + +// STL includes +#include <string> + +// FrameWork includes +#include "AsgTools/AsgTool.h" +#include "AsgTools/ToolHandle.h" + +// Tracking Tool +#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h" + +// METRecoInterface includes +#include "METRecoInterface/IMETAssocToolBase.h" + +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/Vertex.h" +#include "xAODPFlow/PFOContainer.h" +#include "xAODPFlow/PFO.h" +#include "PFlowUtils/IRetrievePFOTool.h" + +namespace met { + class METAssociator + : virtual public asg::AsgTool, + virtual public IMETAssocToolBase + { + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor w/ name + METAssociator(const std::string& name); + // Default Destructor + virtual ~METAssociator(); + + // AsgTool Handles + virtual StatusCode initialize(); + virtual StatusCode execute (xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + virtual StatusCode finalize (); + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + protected: + + std::string m_input_data_key; + std::string m_pvcoll; + std::string m_trkcoll; + std::string m_clcoll; + + bool m_pflow; + int m_signalstate; + + ToolHandle<CP::IRetrievePFOTool> m_pfotool; + std::vector<const xAOD::TrackParticle*> m_goodtracks; + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; + + // reconstruction process to be defined in the individual tools + // pure virtual -- we have no default + virtual StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) = 0; + StatusCode retrieveConstituents(const xAOD::CaloClusterContainer*& tcCont,const xAOD::Vertex*& pv,const xAOD::TrackParticleContainer*& trkCont,const xAOD::PFOContainer*& pfoCont); + + void filterTracks(const xAOD::TrackParticleContainer* tracks, + const xAOD::Vertex* pv); + bool acceptTrack (const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) const; + bool acceptChargedPFO(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) const; + bool isGoodEoverP(const xAOD::TrackParticle* trk,const xAOD::CaloClusterContainer*& tcCont) const; + + StatusCode fillAssocMap(xAOD::MissingETAssociationMap* metMap, + const xAOD::IParticleContainer* hardObjs); + virtual StatusCode extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) = 0; + virtual StatusCode extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* tcCont, + const xAOD::Vertex* pv) = 0; + virtual StatusCode extractTopoClusters(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* tcCont) = 0; + static inline bool greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2) { + return part1->pt()>part2->pt(); + } + static inline bool greaterPtPFO(const xAOD::PFO* part1, const xAOD::PFO* part2) { + if (part1->charge()==0 && part2->charge()!=0) return false; + if (part1->charge()!=0 && part2->charge()==0) return true; + if (part1->charge()==0 && part2->charge()==0) return part1->ptEM()>part2->ptEM(); + return part1->pt()>part2->pt(); + } + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + // Default Constructor + METAssociator(); + }; +} + +#endif // METRECONSTRUCTION_METASSOCBUILDERTOOL_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METBuilderTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METBuilderTool.h index 0e18d73da6dbb3ef6948bcceb7ccafc5a876387e..eb44d26dd853ddcceb1d256ce1db63448cf5db4d 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METBuilderTool.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METBuilderTool.h @@ -139,8 +139,6 @@ namespace met { }; - inline bool greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2); - } // I/O operators @@ -150,8 +148,4 @@ namespace met { // Inline methods: /////////////////////////////////////////////////////////////////// -bool met::greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2) { - return part1->pt()>part2->pt(); -} - #endif //> !METRECONSTRUCTION_METBUILDERTOOL_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METCaloRegionsTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METCaloRegionsTool.h index a2eb0332b953d9bddf8ec07c5a6d5ea1435f4381..97297bb755b7d1a64becf9840b73e61e0d1334fb 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METCaloRegionsTool.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METCaloRegionsTool.h @@ -34,11 +34,7 @@ #include "xAODCaloEvent/CaloClusterContainer.h" #include "xAODCaloEvent/CaloClusterFwd.h" -#ifndef XAOD_STANDALONE -#include "CaloEvent/CaloCellContainer.h" -#else class CaloCellContainer; -#endif namespace met{ diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..7f47a6653977f0768385b2c9b998315894b66a00 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h @@ -0,0 +1,75 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METEgammaAssociator.h +// Header file for class METEgammaAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METEGAMMAASSOCIATOR_H +#define METRECONSTRUCTION_METEGAMMAASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METEgammaAssociator + : virtual public METAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METEgammaAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METEgammaAssociator(const std::string& name); + virtual ~METEgammaAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode extractTopoClusters(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* tcCont); + double m_tcMatch_dR; + double m_tcMatch_maxRat; + double m_tcMatch_tolerance; + unsigned short m_tcMatch_method; + + private: + + /// Default constructor: + METEgammaAssociator(); + + // track overlap removal + bool m_eg_doTracks; + + }; + +} + +#endif //> !METRECONSTRUCTION_METEGAMMAASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METElectronAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METElectronAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..783b9bad47337bed16595d21c0d8306b978ba2d8 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METElectronAssociator.h @@ -0,0 +1,77 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METElectronAssociator.h +// Header file for class METElectronAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METELECTRONASSOCIATOR_H +#define METRECONSTRUCTION_METELECTRONASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METEgammaAssociator.h" +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METElectronAssociator final + : virtual public METEgammaAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METElectronAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METElectronAssociator(const std::string& name); + ~METElectronAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) final; + StatusCode extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* tcCont, + const xAOD::Vertex* pv) final; + + private: + + /// Default constructor: + METElectronAssociator(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METELECTRONASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h new file mode 100644 index 0000000000000000000000000000000000000000..33cf47fca4e5a1b5739d0a03f7763a1a9ad5ba62 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METJetAssocTool.h @@ -0,0 +1,81 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METJetAssocTool.h +// Header file for class METJetAssocTool +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METJETASSOCTOOL_H +#define METRECONSTRUCTION_METJETASSOCTOOL_H 1 + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METJetAssocTool final + : virtual public METAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METJetAssocTool, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METJetAssocTool(const std::string& name); + ~METJetAssocTool(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractPFO(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + MissingETBase::Types::constvec_t&, + const xAOD::PFOContainer*, + const xAOD::Vertex*){return StatusCode::FAILURE;} // should not be called + + StatusCode extractTracks(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + const xAOD::CaloClusterContainer*, + const xAOD::Vertex*){return StatusCode::FAILURE;} // should not be called + StatusCode extractTopoClusters(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + const xAOD::CaloClusterContainer*){return StatusCode::FAILURE;} // should not be called + + private: + + /// Default constructor: + METJetAssocTool(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METJETASSOCTOOL_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..9d5f2f855d9658f4c8c517170034bd52c5464c78 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h @@ -0,0 +1,80 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METMuonAssociator.h +// Header file for class METMuonAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METMUONASSOCIATOR_H +#define METRECONSTRUCTION_METMUONASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METMuonAssociator final + : virtual public METAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METMuonAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METMuonAssociator(const std::string& name); + ~METMuonAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractTopoClusters(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* tcCont); + StatusCode extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) final; + StatusCode extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* tcCont, + const xAOD::Vertex* pv) final; + + private: + + /// Default constructor: + METMuonAssociator(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METMUONASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METPhotonAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METPhotonAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..49a479fc24ebc7f291ffe7a732861cac19c3e7f4 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METPhotonAssociator.h @@ -0,0 +1,76 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METPhotonAssociator.h +// Header file for class METPhotonAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METPHOTONASSOCIATOR_H +#define METRECONSTRUCTION_METPHOTONASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METEgammaAssociator.h" + +namespace met{ + class METPhotonAssociator final + : virtual public METEgammaAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METPhotonAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METPhotonAssociator(const std::string& name); + ~METPhotonAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) final; + StatusCode extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* tcCont, + const xAOD::Vertex* pv) final; + + private: + + /// Default constructor: + METPhotonAssociator(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METPHOTONASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METReconstructionDict.h b/Reconstruction/MET/METReconstruction/METReconstruction/METReconstructionDict.h new file mode 100644 index 0000000000000000000000000000000000000000..d57ffdae0d0bb03ab501a6127daa015e574f870e --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METReconstructionDict.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef METRECONSTRUCTIONDICT_H +#define METRECONSTRUCTIONDICT_H + +#if defined(__GCCXML__) and not defined(EIGEN_DONT_VECTORIZE) +#define EIGEN_DONT_VECTORIZE +#endif // __GCCXML__ + +#include "METReconstruction/METBuilderTool.h" +#include "METReconstruction/METElectronTool.h" +#include "METReconstruction/METPhotonTool.h" +#include "METReconstruction/METTauTool.h" +#include "METReconstruction/METJetTool.h" +#include "METReconstruction/METMuonTool.h" +#include "METReconstruction/METSoftTermsTool.h" +#include "METReconstruction/METTruthTool.h" +#include "METReconstruction/METCaloRegionsTool.h" +#include "METReconstruction/METRegionsTool.h" +#include "METReconstruction/METTrackFilterTool.h" +#include "METReconstruction/METRecoTool.h" + +#include "METReconstruction/METAssociator.h" +#include "METReconstruction/METJetAssocTool.h" +#include "METReconstruction/METElectronAssociator.h" +#include "METReconstruction/METPhotonAssociator.h" +#include "METReconstruction/METTauAssociator.h" +#include "METReconstruction/METMuonAssociator.h" +#include "METReconstruction/METSoftAssociator.h" +#include "METReconstruction/METAssociationTool.h" + +#endif //METRECONSTRUCTIONDICT_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..e6bb11cf5d61a262657295df3253bdc3ea9563dc --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METSoftAssociator.h @@ -0,0 +1,81 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METSoftAssociator.h +// Header file for class METSoftAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METSOFTASSOCIATOR_H +#define METRECONSTRUCTION_METSOFTASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METSoftAssociator final + : virtual public METAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METSoftAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METSoftAssociator(const std::string& name); + ~METSoftAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractPFO(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + MissingETBase::Types::constvec_t&, + const xAOD::PFOContainer*, + const xAOD::Vertex*){return StatusCode::FAILURE;} // should not be called + + StatusCode extractTracks(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + const xAOD::CaloClusterContainer*, + const xAOD::Vertex*){return StatusCode::FAILURE;} // should not be called + StatusCode extractTopoClusters(const xAOD::IParticle*, + std::vector<const xAOD::IParticle*>&, + MissingETBase::Types::constvec_t&, + const xAOD::CaloClusterContainer*){return StatusCode::FAILURE;} // should not be called + + private: + + /// Default constructor: + METSoftAssociator(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METSOFTASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h new file mode 100644 index 0000000000000000000000000000000000000000..fe105183981b0888e4fa32d9d66daad7c948256f --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h @@ -0,0 +1,80 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METTauAssociator.h +// Header file for class METTauAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// +#ifndef METRECONSTRUCTION_METTAUASSOCIATOR_H +#define METRECONSTRUCTION_METTAUASSOCIATOR_H 1 + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" + +namespace met{ + class METTauAssociator final + : virtual public METAssociator + { + // This macro defines the constructor with the interface declaration + ASG_TOOL_CLASS(METTauAssociator, IMETAssocToolBase) + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Constructor with name + METTauAssociator(const std::string& name); + ~METTauAssociator(); + + // AsgTool Hooks + StatusCode initialize(); + StatusCode finalize(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + protected: + + StatusCode executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap); + StatusCode extractTopoClusters(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* tcCont); + StatusCode extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) final; + StatusCode extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* tcCont, + const xAOD::Vertex* pv) final; + + private: + + /// Default constructor: + METTauAssociator(); + + }; + +} + +#endif //> !METRECONSTRUCTION_METTAUASSOCIATOR_H diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTrackFilterTool.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTrackFilterTool.h index 79c27eb14f1b615d57c73f1a04b9c217c7ff2ce9..d104e11af0955ca94dfa0965882d8e8ecaafa425 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METTrackFilterTool.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTrackFilterTool.h @@ -28,6 +28,14 @@ #include "xAODTracking/TrackParticleFwd.h" #include "xAODTracking/VertexFwd.h" #include "xAODTracking/VertexContainerFwd.h" +#include "xAODEgamma/ElectronFwd.h" +#include "xAODEgamma/ElectronContainer.h" + +#include "xAODMuon/Muon.h" +#include "xAODMuon/MuonContainer.h" + +#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h" +#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h" namespace met{ @@ -64,22 +72,42 @@ namespace met{ // Private data: /////////////////////////////////////////////////////////////////// protected: - StatusCode executeTool(xAOD::MissingET* metTerm, xAOD::MissingETComponentMap* metMap); + StatusCode executeTool(xAOD::MissingET* metTerm, xAOD::MissingETComponentMap* metMap); // Accept functions - bool isPVTrack (const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) const; - bool isGoodEoverP (const xAOD::TrackParticle* trk, - const std::vector<const xAOD::IParticle*>& trkList, - const xAOD::CaloClusterContainer* clusters) const; + // bool isPVTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) const; + bool isGoodEoverP(const xAOD::TrackParticle* trk, + const std::vector<const xAOD::IParticle*>& trkList, + const xAOD::CaloClusterContainer* clusters) const; private: // Default constructor: METTrackFilterTool(); + StatusCode buildTrackMET(xAOD::MissingETComponentMap* const metMap, + xAOD::MissingET* const metTerm, + const xAOD::Vertex* const pv, + const std::vector<const xAOD::Electron*>& selElectrons, + const std::vector<const xAOD::Muon*>& selMuons, + const std::vector<const xAOD::TrackParticle*>& softTracks) const; + + bool isElTrack(const xAOD::TrackParticle &trk, const std::vector<const xAOD::Electron*>& electrons, size_t &el_index ) const; + bool isMuTrack(const xAOD::TrackParticle &trk, const std::vector<const xAOD::Muon*>& muons) const; + + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; + ToolHandle<CP::ITrackVertexAssociationTool> m_trkToVertexTool; + + void selectElectrons(const xAOD::ElectronContainer &elCont, std::vector<const xAOD::Electron*>& electrons) const; + void selectMuons(const xAOD::MuonContainer &muCont, std::vector<const xAOD::Muon*>& muons) const; + bool m_trk_doPVsel; - double m_trk_d0Max; - double m_trk_z0Max; + // double m_trk_d0Max; + // double m_trk_z0Max; std::string m_pv_inputkey; - const xAOD::VertexContainer* m_pv_cont; + std::string m_el_inputkey; + std::string m_mu_inputkey; + + bool m_doVxSep; + bool m_doLepRecovery; bool m_trk_doEoverPsel; std::string m_cl_inputkey; diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/selection.xml b/Reconstruction/MET/METReconstruction/METReconstruction/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..09c9b5445e37272d07f855afa4a80a31848c3820 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/METReconstruction/selection.xml @@ -0,0 +1,30 @@ +<lcgdict> + <class name="met::METBuilderTool" /> + <class name="met::METElectronTool" /> + <class name="met::METPhotonTool" /> + <class name="met::METTauTool" /> + <class name="met::METJetTool" /> + <class name="met::METMuonTool" /> + <class name="met::METSoftTermsTool" /> + <class name="met::METTruthTool" /> + <class name="met::METCaloRegionsTool" /> + <class name="met::METRegionsTool" /> + <class name="met::METTrackFilterTool" /> + <class name="met::METRecoTool" /> + + <class name="met::METAssociator" /> + <class name="met::METJetAssocTool" /> + <class name="met::METElectronAssociator" /> + <class name="met::METPhotonAssociator" /> + <class name="met::METTauAssociator" /> + <class name="met::METMuonAssociator" /> + <class name="met::METSoftAssociator" /> + <class name="met::METAssociationTool" /> + + <!-- Suppress the unwanted classes found by ROOT 6. --> + <!-- Hopefully we can remove these extra lines at one point... --> + <exclusion> + <class name="SG::IConstAuxStore" /> + <class name="DataLink<SG::IConstAuxStore>" /> + </exclusion> +</lcgdict> diff --git a/Reconstruction/MET/METReconstruction/Root/METAssociationTool.cxx b/Reconstruction/MET/METReconstruction/Root/METAssociationTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..341b5b927ca987cab240e700b790149c87993876 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METAssociationTool.cxx @@ -0,0 +1,177 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssociationTool.cxx +// Implementation file for class METAssociationTool +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METAssociationTool.h" + +// MET EDM +#include "xAODMissingET/MissingET.h" +#include "xAODMissingET/MissingETContainer.h" +#include "xAODMissingET/MissingETComposition.h" +#include "xAODMissingET/MissingETAuxContainer.h" +#include "xAODMissingET/MissingETAuxComponentMap.h" + +#include <iomanip> + +namespace met { + + using xAOD::MissingET; + using xAOD::MissingETContainer; + using xAOD::MissingETComposition; + using xAOD::MissingETAuxContainer; + // + using std::string; + using std::setw; + using std::setprecision; + using std::fixed; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + + // Constructors + //////////////// + METAssociationTool::METAssociationTool(const std::string& name) : + AsgTool(name) + { + declareProperty( "METAssociators", m_metassociators ); + declareProperty( "METSuffix", m_metsuffix = "AntiKt4LCTopo" ); + } + + // Destructor + /////////////// + METAssociationTool::~METAssociationTool() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METAssociationTool::initialize() + { + ATH_MSG_INFO ("Initializing " << name() << "..."); + + if( m_metsuffix.size()==0 ) { + ATH_MSG_ERROR("Output suffix for MET names must be provided."); + return StatusCode::FAILURE; + } else { + m_corename = "MET_Core_"+m_metsuffix; + m_mapname = "METAssoc_"+m_metsuffix; + ATH_MSG_INFO("Tool configured to build MET with names:"); + ATH_MSG_INFO(" Core container ==> " << m_corename); + ATH_MSG_INFO(" Association map ==> " << m_mapname); + } + + // retrieve builders + for(ToolHandleArray<IMETAssocToolBase>::const_iterator iBuilder=m_metassociators.begin(); + iBuilder != m_metassociators.end(); ++iBuilder) { + ToolHandle<IMETAssocToolBase> tool = *iBuilder; + if( tool.retrieve().isFailure() ) { + ATH_MSG_FATAL("Failed to retrieve tool: " << tool->name()); + return StatusCode::FAILURE; + }; + ATH_MSG_INFO("Retrieved tool: " << tool->name() ); + } + + return StatusCode::SUCCESS; + } + + StatusCode METAssociationTool::execute() const + { + ATH_MSG_DEBUG ("In execute: " << name() << "..."); + + if( evtStore()->contains<xAOD::MissingETAssociationMap>(m_mapname) ) { + ATH_MSG_WARNING("Association map \"" << m_mapname << "\" is already present, exiting."); + return StatusCode::SUCCESS; + } + + // Create a MissingETAssociationMap with its aux store + xAOD::MissingETAssociationMap* metMap = new xAOD::MissingETAssociationMap(); + if( evtStore()->record(metMap, m_mapname).isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAssociationMap: " << m_mapname); + return StatusCode::SUCCESS; + } + xAOD::MissingETAuxAssociationMap* metAuxMap = new xAOD::MissingETAuxAssociationMap(); + if( evtStore()->record(metAuxMap, m_mapname+"Aux.").isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAuxAssociationMap: " << m_mapname+"Aux."); + return StatusCode::SUCCESS; + } + metMap->setStore(metAuxMap); + + if( evtStore()->contains<MissingETContainer>(m_corename) ) { + ATH_MSG_WARNING("MET_Core container \"" << m_corename << "\" is already present, exiting."); + return StatusCode::SUCCESS; + } + MissingETContainer* metCont = new MissingETContainer(); + if( evtStore()->record(metCont, m_corename).isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETContainer: " << m_corename); + return StatusCode::SUCCESS; + } + MissingETAuxContainer* metAuxCont = new MissingETAuxContainer(); + if( evtStore()->record(metAuxCont, m_corename+"Aux.").isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAuxContainer: " << m_corename+"Aux."); + return StatusCode::SUCCESS; + } + metCont->setStore(metAuxCont); + + if( buildMET(metCont, metMap).isFailure() ) { + ATH_MSG_WARNING("Failed in MissingET reconstruction"); + return StatusCode::SUCCESS; + } + + return StatusCode::SUCCESS; + } + + StatusCode METAssociationTool::finalize() + { + ATH_MSG_INFO ("Finalizing " << name() << "..."); + + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + StatusCode METAssociationTool::buildMET(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) const + { + // Run the MET reconstruction tools in sequence + for(ToolHandleArray<IMETAssocToolBase>::const_iterator iBuilder=m_metassociators.begin(); + iBuilder != m_metassociators.end(); ++iBuilder) { + ToolHandle<IMETAssocToolBase> tool = *iBuilder; + if (tool->execute(metCont,metMap).isFailure()){ + ATH_MSG_WARNING("Failed to execute tool: " << tool->name()); + return StatusCode::FAILURE; + } + } + bool foundOverlaps = metMap->identifyOverlaps(); + ATH_MSG_DEBUG( (foundOverlaps ? "Overlaps" : "No overlaps") << " identified!"); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c026fc0532f1f9d962fa6201a560d5b0cab22dcc --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METAssociator.cxx @@ -0,0 +1,300 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssociator.cxx +// Implementation for class METAssociator +// +// This is the base class for tools that construct MET terms +// from other object collections. +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METAssociator.h" +#include "xAODMissingET/MissingETComposition.h" +#include "xAODMissingET/MissingETContainer.h" +#include "xAODMissingET/MissingETAssociationMap.h" + +// Tracking EDM +#include "xAODTracking/Vertex.h" +#include "xAODTracking/TrackParticle.h" + +// Track errors +#include "EventPrimitives/EventPrimitivesHelpers.h" + +namespace met { + + using namespace xAOD; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + + // Constructors + //////////////// + METAssociator::METAssociator(const std::string& name) : + AsgTool(name), + m_signalstate(-1) + { + declareProperty( "InputCollection", m_input_data_key ); + declareProperty( "PrimVxColl", m_pvcoll = "PrimaryVertices" ); + declareProperty( "TrkColl", m_trkcoll = "InDetTrackParticles" ); + declareProperty( "ClusColl", m_clcoll = "CaloCalTopoClusters" ); + declareProperty( "PFlow", m_pflow = false ); + declareProperty( "PFOTool", m_pfotool ); + + declareProperty( "TrackSelectorTool", m_trkseltool ); + } + + // Destructor + /////////////// + METAssociator::~METAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METAssociator::initialize() + { + ATH_MSG_INFO ("Initializing " << name() << "..."); + + ATH_CHECK( m_trkseltool.retrieve() ); + + return StatusCode::SUCCESS; + } + + StatusCode METAssociator::execute(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_DEBUG ("In execute: " << name() << "..."); + if(!metCont) { + ATH_MSG_WARNING("Invalid pointer to MissingETContainer supplied! Abort."); + return StatusCode::FAILURE; + } + + if(!metMap) { + ATH_MSG_WARNING("Invalid pointer to MissingETAssociationMap supplied! Abort."); + return StatusCode::FAILURE; + } + + // will set the signal state for the first event with jets + if(m_signalstate<0) { + if(metMap->size()>0) { //allow for misc association + const MissingETAssociation* assoc = metMap->front(); + if(!assoc->isMisc()) { + m_signalstate = assoc->refJet()->getConstituentsSignalState(); + ATH_MSG_INFO("Configured METAssociator with signal state " << m_signalstate); + } + } + } + + return this->executeTool(metCont, metMap); + } + + StatusCode METAssociator::retrieveConstituents(const xAOD::CaloClusterContainer*& tcCont,const xAOD::Vertex*& pv,const xAOD::TrackParticleContainer*& trkCont,const xAOD::PFOContainer*& pfoCont) + { + ATH_MSG_DEBUG ("In execute: " << name() << "..."); + tcCont = 0; + if( evtStore()->retrieve(tcCont, m_clcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve topocluster container " << m_clcoll << " for overlap removal"); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Successfully retrieved topocluster collection"); + + const VertexContainer *vxCont = 0; + pv = 0; + if( evtStore()->retrieve(vxCont, m_pvcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve primary vertex container " << m_pvcoll); + return StatusCode::FAILURE; + } else if(vxCont->empty()) { + ATH_MSG_WARNING("Event has no primary vertices!"); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Successfully retrieved primary vertex container"); + for(const auto& vx : *vxCont) { + if(vx->vertexType()==VxType::PriVtx) + {pv = vx; break;} + } + if(!pv) { + ATH_MSG_WARNING("Failed to find primary vertex!"); + return StatusCode::FAILURE; + } else { + ATH_MSG_VERBOSE("Primary vertex has z = " << pv->z()); + } + + trkCont=0; + ATH_CHECK( evtStore()->retrieve(trkCont, m_trkcoll) ); + + // filterTracks(trkCont,pv); + + if(m_pflow) { + pfoCont = 0; + if( evtStore()->contains<xAOD::PFOContainer>("EtmissParticleFlowObjects") ) { + ATH_CHECK(evtStore()->retrieve(pfoCont,"EtmissParticleFlowObjects")); + } else { + pfoCont = m_pfotool->retrievePFO(CP::EM, CP::all); + ATH_CHECK( evtStore()->record(pfoCont,"EtmissParticleFlowObjects")); + } + if(!pfoCont) { + ATH_MSG_WARNING("Unable to retrieve input pfo container"); + return StatusCode::FAILURE; + } + } + return StatusCode::SUCCESS; + } + + StatusCode METAssociator::finalize() + { + ATH_MSG_INFO ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + StatusCode METAssociator::fillAssocMap(xAOD::MissingETAssociationMap* metMap, + const xAOD::IParticleContainer* hardObjs) + // std::vector<const xAOD::IParticle*>& mutracks) + { + const CaloClusterContainer* tcCont; + const Vertex* pv; + const TrackParticleContainer* trkCont; + const PFOContainer* pfoCont; + + if (retrieveConstituents(tcCont,pv,trkCont,pfoCont).isFailure()) { + ATH_MSG_WARNING("Unable to retrieve constituent containers"); + return StatusCode::FAILURE; + } + + std::vector<const IParticle*> constlist; + constlist.reserve(20); + std::vector<const IParticle*> hardObjs_tmp; + for(const auto& obj : *hardObjs) { + hardObjs_tmp.push_back(obj); + } + std::sort(hardObjs_tmp.begin(),hardObjs_tmp.end(),greaterPt); + + for(const auto& obj : hardObjs_tmp) { + if(obj->pt()<5e3 && obj->type()!=xAOD::Type::Muon) continue; + constlist.clear(); + MissingETBase::Types::constvec_t tcvec,trkvec; + ATH_MSG_VERBOSE( "Object type, pt, eta, phi = " << obj->type() << ", " << obj->pt() << ", " << obj->eta() << "," << obj->phi() ); + if (m_pflow) { + ATH_CHECK( this->extractPFO(obj,constlist,tcvec,trkvec,pfoCont,pv) ); + } else { + ATH_CHECK( this->extractTopoClusters(obj,constlist,tcvec,tcCont) ); + ATH_CHECK( this->extractTracks(obj,constlist,trkvec,tcCont,pv) ); + } + bool inserted(false); + inserted = MissingETComposition::insert(metMap,obj,constlist,tcvec,trkvec); + if(inserted) { + const MissingETAssociation* assoc = MissingETComposition::getAssociation(metMap,obj); + ATH_MSG_VERBOSE( obj->type() << " is associated to jet " << assoc->refJet()->index() << " with pt " << assoc->refJet()->pt() ); + } else { + ATH_MSG_VERBOSE( "Add " << obj->type() << " as miscellaneous object" ); + if(!obj->type()==xAOD::Type::Tau) + inserted = MissingETComposition::insertMisc(metMap,obj,constlist,tcvec,trkvec); + } + } + return StatusCode::SUCCESS; + } + + void METAssociator::filterTracks(const xAOD::TrackParticleContainer* tracks, + const xAOD::Vertex* pv) { + for(const auto& trk : *tracks) { + m_goodtracks.clear(); + if(acceptTrack(trk,pv)) m_goodtracks.push_back(trk); + } + } + + // Accept Track + //////////////// + bool METAssociator::acceptTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* vx) const + { + //if(fabs(trk->pt())<500/*MeV*/ || fabs(trk->eta())>2.5) return false; + // could add some error checking to make sure we successfully read the details + //uint8_t nPixHits(0), nSctHits(0); + //trk->summaryValue(nPixHits,xAOD::numberOfPixelHits); + //if(nPixHits<1) return false; + //trk->summaryValue(nSctHits,xAOD::numberOfSCTHits); + //if(nSctHits<6) return false; + //if(fabs(trk->d0())>1.5) return false; + //if(fabs(trk->z0() + trk->vz() - vx->z()) > 1.5) return false; + //return true; + + const Root::TAccept& accept = m_trkseltool->accept( *trk, vx ); + // uint8_t nBLHits(0), expectBLHit(false); + // if(trk->summaryValue(nBLHits,xAOD::numberOfBLayerHits)) { + // ATH_MSG_VERBOSE("Track has " << (int) nBLHits << " b-layer hits"); + // } + // if(trk->summaryValue(expectBLHit,xAOD::expectBLayerHit)) { + // ATH_MSG_VERBOSE("Track expected b-layer hit: " << (bool) expectBLHit); + // } + // ATH_MSG_VERBOSE("From auxdata: expect hit ? " << (bool) trk->auxdata<uint8_t>("expectBLayerHit") + // << " Nhits = " << (int) trk->auxdata<uint8_t>("numberOfBLayerHits")); + + // if(!accept && fabs(trk->z0() + trk->vz() - vx->z())*sin(trk->theta()) < 1.5) { + // for(size_t icut=0; icut<accept.getNCuts(); ++icut) { + // ATH_MSG_VERBOSE("Cut " << accept.getCutName(icut) << ": result = " << accept.getCutResult(icut)); + // } + // } + return accept; + } + + + bool METAssociator::acceptChargedPFO(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) const + { + if(fabs((trk->z0() - pv->z()+trk->vz())*sin(trk->theta())) > 2) return false; + return true; + } + + + bool METAssociator::isGoodEoverP(const xAOD::TrackParticle* trk,const xAOD::CaloClusterContainer*& tcCont) const + { + + if( (fabs(trk->eta())<1.5 && trk->pt()>200e3) || + (fabs(trk->eta())>=1.5 && trk->pt()>120e3) ) { + + // Get relative error on qoverp + float Rerr = Amg::error(trk->definingParametersCovMatrix(),4)/fabs(trk->qOverP()); + ATH_MSG_VERBOSE( "Track momentum error (%): " << Rerr*100 ); + + // first compute track and calo isolation variables + float ptcone20 = 0; + for(const auto& testtrk : m_goodtracks) { + if(testtrk==trk) continue; + if(testtrk->p4().DeltaR(trk->p4()) < 0.2) { + ptcone20 += testtrk->pt(); + } + } + float isolfrac = ptcone20 / trk->pt(); + ATH_MSG_VERBOSE( "Track isolation fraction: " << isolfrac ); + + float etcone10 = 0.; + for(const auto& clus : *tcCont) { + if(clus->p4().DeltaR(trk->p4()) < 0.1) { + etcone10 += clus->pt(); + } + } + float EoverP = etcone10/trk->pt(); + ATH_MSG_VERBOSE( "Track E/P: " << EoverP ); + + if(isolfrac<0.1) { + // isolated track cuts + if(Rerr>0.4) return false; + else if (EoverP<0.65 && (EoverP>0.1 || Rerr>0.1)) return false; + } else { + // non-isolated track cuts + float trkptsum = ptcone20+trk->pt(); + if(EoverP/trkptsum<0.6 && ptcone20/trkptsum<0.6) return false; + } + } + return true; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METCaloRegionsTool.cxx b/Reconstruction/MET/METReconstruction/Root/METCaloRegionsTool.cxx index 45460ab7cadfa7065d15d849a11fcfea7dbd54c8..65f9c81ba70d8ef54cf0220c65d731fdf69cdc85 100644 --- a/Reconstruction/MET/METReconstruction/Root/METCaloRegionsTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METCaloRegionsTool.cxx @@ -16,7 +16,10 @@ #include "METReconstruction/METCaloRegionsTool.h" // MET EDM -#include "xAODMissingET/MissingETComposition.h" +#if defined(XAOD_STANDALONE) || defined(XAOD_ANALYSIS) +#else +#include "CaloEvent/CaloCellContainer.h" +#endif namespace met { @@ -28,7 +31,6 @@ namespace met { using xAOD::CaloClusterContainer; // using xAOD::MissingET; - using xAOD::MissingETComposition; using xAOD::MissingETContainer; // Initialize CaloRegionNames @@ -96,6 +98,14 @@ namespace met { // Create the container and push back the new MET terms MissingETBase::Types::bitmask_t source = MissingETBase::Source::Calo | MissingETBase::Source::clusterEM(); MissingETContainer* metCont = dynamic_cast<MissingETContainer*>( metTerm_EMB->container() ); + + // Check dynamic_cast for coverity + if(!metCont) { + ATH_MSG_WARNING("Unsuccesful dynamic_cast"); + return StatusCode::SUCCESS; + } + + // Push region terms to the container for( int i=0; i < REGIONS_TOTAL; ++i) { // Create the new terms if( i > 0 ) { @@ -106,27 +116,32 @@ namespace met { metCont->at(i)->setSource( source ); } + StatusCode sc = StatusCode::SUCCESS; + // Either Cells or Clusters if(m_calo_useCells) { // Retrieve the cell container - const CaloCellContainer* caloCellCont = 0; - #ifndef XAOD_STANDALONE - if( evtStore()->retrieve(caloCellCont, m_input_data_key).isFailure() ) { + const CaloCellContainer* caloCellCont = 0; + #if defined(XAOD_STANDALONE) || defined(XAOD_ANALYSIS) + #else + sc = evtStore()->retrieve(caloCellCont, m_input_data_key); + if( sc.isFailure() ) { ATH_MSG_WARNING("Unable to retrieve input cell cluster container"); return StatusCode::SUCCESS; } #endif // Fill MET - return fillCellMet(metCont,caloCellCont); + sc = fillCellMet(metCont,caloCellCont); } else { // Retrieve the calo container const CaloClusterContainer* caloClusCont = 0; - if( evtStore()->retrieve(caloClusCont, m_input_data_key).isFailure() ) { + sc = evtStore()->retrieve(caloClusCont, m_input_data_key); + if( sc.isFailure() ) { ATH_MSG_WARNING("Unable to retrieve input calo cluster container"); return StatusCode::SUCCESS; } // Fill MET - return fillClusterMet(metCont,caloClusCont); + sc=fillClusterMet(metCont,caloClusCont); } // end if use clusters if/else // Debug information @@ -142,6 +157,10 @@ namespace met { ); } // end debug information + if(sc.isFailure()) { + ATH_MSG_WARNING("Unable to fill cell/cluster MET"); + } + return StatusCode::SUCCESS; } @@ -194,7 +213,9 @@ namespace met { // Fill Cell MET StatusCode METCaloRegionsTool::fillCellMet(xAOD::MissingETContainer* metContainer, const CaloCellContainer* caloCellContainer) { - #ifndef XAOD_STANDALONE + #if defined (XAOD_STANDALONE) || defined(XAOD_ANALYSIS) + ATH_MSG_WARNING("Cell information is only available in athena framework"); + #else // Loop over all cells for( CaloCellContainer::const_iterator iCell=caloCellContainer->begin(); iCell!=caloCellContainer->end(); ++iCell ) { @@ -222,8 +243,6 @@ namespace met { et_cell); } // end if energy>0 if } // end of loop overall cells - #else - ATH_MSG_WARNING("Cell information is only available in athena framework"); #endif return StatusCode::SUCCESS; } // end of fillCellMet diff --git a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e9273270233755deb101e3c5756e6a9a0e4bd8ae --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx @@ -0,0 +1,147 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METEgammaAssociator.cxx +// Implementation file for class METEgammaAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METEgammaAssociator.h" + +// Egamma EDM +#include "xAODEgamma/EgammaFwd.h" +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/PhotonContainer.h" +#include "xAODCaloEvent/CaloClusterContainer.h" + +// Calo helpers +#include "xAODCaloEvent/CaloClusterChangeSignalState.h" + +// Tracking EDM +#include "xAODTracking/Vertex.h" + +namespace met { + + using xAOD::IParticle; + // + using xAOD::Egamma; + // + using xAOD::CaloCluster; + // + using xAOD::VertexContainer; + + // Constructors + //////////////// + METEgammaAssociator::METEgammaAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name) + { + declareProperty( "TCMatchDeltaR", m_tcMatch_dR = 0.1 ); + declareProperty( "TCMatchMaxRat", m_tcMatch_maxRat = 1.5 ); + declareProperty( "TCMatchTolerance", m_tcMatch_tolerance = 0.2 ); + declareProperty( "TCMatchMethod", m_tcMatch_method = 0 ); + } + + // Destructor + /////////////// + METEgammaAssociator::~METEgammaAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METEgammaAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METEgammaAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + //********************************************************************** + // Get Egamma constituents + StatusCode METEgammaAssociator::extractTopoClusters(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* tcCont) + { + const Egamma *eg = static_cast<const xAOD::Egamma*>(obj); + // safe to assume a single SW cluster? + // will do so for now... + const CaloCluster* swclus = eg->caloCluster(); + double eg_cl_e = swclus->e(); + + // the matching strategy depends on how the cluster container is sorted + // easier if it's sorted in descending pt order + // we'll worry about optimisation later + std::vector<const xAOD::CaloCluster*> nearbyTC; + CaloClusterChangeSignalStateList stateHelperList; + nearbyTC.reserve(10); + for(const auto& cl : *tcCont) { + // this can probably be done more elegantly + double dR = swclus->p4().DeltaR(cl->p4()); + if(dR<m_tcMatch_dR && cl->e()>0) { + // could consider also requirements on the EM fraction or depth + nearbyTC.push_back(cl); + stateHelperList.add(cl, CaloCluster::State(m_signalstate)); + } // match TC in a cone around SW cluster + } + ATH_MSG_VERBOSE("Found " << nearbyTC.size() << " nearby topoclusters"); + + bool doSum = true; + double sumE_tc = 0.; + const CaloCluster* bestbadmatch = 0; + std::sort(nearbyTC.begin(),nearbyTC.end(),greaterPt); + for(const auto& cl : nearbyTC) { + double tcl_e = cl->e(); + // skip cluster if it's above our bad match threshold + // FIXME: What to do with these poor matches? + if(tcl_e>m_tcMatch_maxRat*eg_cl_e) { + ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e)); + if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = cl; + continue; + } + + ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e); + if( (doSum = (fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e))) ) { + ATH_MSG_VERBOSE("Accept topocluster with pt " << cl->pt() << ", e " << cl->e() << " in sum."); + ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e); + ATH_MSG_VERBOSE("Energy ratio of TC to eg: " << tcl_e / eg_cl_e); + tclist.push_back(cl); + sumE_tc += tcl_e; + tcvec += MissingETBase::Types::constvec_t(*cl); + } // if we will retain the topocluster + } // loop over nearby clusters + if(sumE_tc<1e-9 && bestbadmatch) { + ATH_MSG_VERBOSE("No better matches found -- add bad match topocluster with pt " + << bestbadmatch->pt() << ", e " << bestbadmatch->e() << "."); + tclist.push_back(bestbadmatch); + tcvec += MissingETBase::Types::constvec_t(*bestbadmatch); + } + + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METEgammaTool.cxx b/Reconstruction/MET/METReconstruction/Root/METEgammaTool.cxx index b8d20d7ae2cf12e45554a49f30e6dc124354f960..03e85fa201b806661575a7ab39c5fbc27882ba07 100644 --- a/Reconstruction/MET/METReconstruction/Root/METEgammaTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METEgammaTool.cxx @@ -51,6 +51,10 @@ namespace met { // Public methods: /////////////////////////////////////////////////////////////////// + static bool greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2) { + return part1->pt()>part2->pt(); + } + // Constructors //////////////// METEgammaTool::METEgammaTool(const std::string& name) : @@ -68,7 +72,7 @@ namespace met { declareProperty( "ClusOQ", m_eg_clusOQ = 0x0 ); declareProperty( "TestClusOQ", m_eg_testClusOQ = false ); // could e.g. veto BADCLUSELECTRON - declareProperty( "TopoClusKey", m_tcCont_key = "CaloCalTopoCluster" ); + declareProperty( "TopoClusKey", m_tcCont_key = "CaloCalTopoClusters" ); declareProperty( "TCMatchDeltaR", m_tcMatch_dR = 0.1 ); declareProperty( "TCMatchMaxRat", m_tcMatch_maxRat = 1.5 ); declareProperty( "TCMatchTolerance", m_tcMatch_tolerance = 0.2 ); @@ -178,20 +182,23 @@ namespace met { bool goodmatch = false; bool doSum = true; double sumE_tc = 0.; + const CaloCluster* bestbadmatch = 0; std::sort(nearbyTC.begin(),nearbyTC.end(),greaterPt); for(vector<const xAOD::CaloCluster*>::const_iterator iClus=nearbyTC.begin(); - iClus!=nearbyTC.end() && doSum; ++iClus) { + iClus!=nearbyTC.end(); ++iClus) { double tcl_e = (*iClus)->e(); // skip cluster if it's above our bad match threshold if(tcl_e>m_tcMatch_maxRat*eg_cl_e) { ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e)); + if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = *iClus; continue; } switch(m_tcMatch_method) { case 0: // sum clusters until the next cluster to be added will make the energy match worse - doSum = ( fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e)); + doSum = ( fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e) ); + ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e); break; case 1: // sum clusters until we either find one very good cluster match @@ -204,11 +211,15 @@ namespace met { tclist.push_back(*iClus); sumE_tc += tcl_e; if(tclist.size()==1) goodmatch = fabs(tcl_e/eg_cl_e-1)<m_tcMatch_tolerance; - ATH_MSG_VERBOSE("Accept topocluster in sum."); - ATH_MSG_VERBOSE("Energy ratio of TC to eg: " << tcl_e / swclus->e()); + ATH_MSG_VERBOSE("Accept topocluster with pt " << (*iClus)->pt() << ", e " << (*iClus)->e() << " in sum."); + ATH_MSG_VERBOSE("Energy ratio of TC to eg: " << tcl_e / eg_cl_e); ATH_MSG_VERBOSE("Do we have a good match? " << (goodmatch ? "YES" : "NO")); } // if we will retain the topocluster } // loop over nearby clusters + if(sumE_tc<1e-9 && bestbadmatch) { + tclist.push_back(bestbadmatch); + sumE_tc += bestbadmatch->e(); + } ATH_MSG_VERBOSE("Egamma links " << eg->nCaloClusters() << " clusters"); ATH_MSG_VERBOSE("Identified " << tclist.size() << " matched topoclusters"); ATH_MSG_VERBOSE("Egamma energy: " << eg->e()); diff --git a/Reconstruction/MET/METReconstruction/Root/METElectronAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METElectronAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d713c7b8eafdeedaee91558bbbfb29e695765858 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METElectronAssociator.cxx @@ -0,0 +1,169 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METElectronAssociator.cxx +// Implementation file for class METElectronAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METElectronAssociator.h" + +// Egamma EDM +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/EgammaxAODHelpers.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METElectronAssociator::METElectronAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name), + METEgammaAssociator(name) + {} + + // Destructor + /////////////// + METElectronAssociator::~METElectronAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METElectronAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METElectronAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + // executeTool + //////////////// + StatusCode METElectronAssociator::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + + const ElectronContainer* elCont(0); + if( evtStore()->retrieve(elCont, m_input_data_key).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input electron container " << m_input_data_key); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("Successfully retrieved electron collection"); + if (fillAssocMap(metMap,elCont).isFailure()) { + ATH_MSG_WARNING("Unable to fill map with electron container " << m_input_data_key); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; + } + + + StatusCode METElectronAssociator::extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* /*tcCont*/, + const xAOD::Vertex* pv) + { + const Electron *el = static_cast<const Electron*>(obj); + for(size_t iTrk=0; iTrk<el->nTrackParticles(); ++iTrk) { + const TrackParticle* eltrk = EgammaHelpers::getOriginalTrackParticleFromGSF(el->trackParticle(iTrk)); + // if(acceptTrack(eltrk,pv) && isGoodEoverP(eltrk,tcCont) && el->p4().DeltaR(eltrk->p4())<0.1) { + if(acceptTrack(eltrk,pv) && el->p4().DeltaR(eltrk->p4())<0.1) { + ATH_MSG_VERBOSE("Accept electron track " << eltrk << " px, py = " << eltrk->p4().Px() << ", " << eltrk->p4().Py()); + constlist.push_back(eltrk); + trkvec += *eltrk; + } + } + return StatusCode::SUCCESS; + } + + //********************************************************************** + // Get Egamma constituents + StatusCode METElectronAssociator::extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) + { + const Electron *el = static_cast<const Electron*>(obj); + // safe to assume a single SW cluster? + // will do so for now... + const CaloCluster* swclus = el->caloCluster(); + double eg_cl_e = swclus->e(); + + // the matching strategy depends on how the cluster container is sorted + // easier if it's sorted in descending pt order + // we'll worry about optimisation later + std::vector<const PFO*> nearbyPFO; + nearbyPFO.reserve(10); + for(const auto& pfo : *pfoCont) { + std::vector<const IParticle*> cls; + bool match = false; + if (pfo->charge()==0) { + if (swclus->p4().DeltaR(pfo->p4EM())<m_tcMatch_dR && pfo->eEM()>0) match = true; + //pfo->associatedParticles(PFODetails::CaloCluster,cls); + //for(const auto& cl : cls) { + // if (!cl) continue; + // double dR = swclus->p4().DeltaR(cl->p4()); + // if(dR<0.1 && cl->e()>0) match = true; + //} + } + for(size_t iTrk=0; iTrk<el->nTrackParticles(); ++iTrk) { + const TrackParticle* eltrk = EgammaHelpers::getOriginalTrackParticleFromGSF(el->trackParticle(iTrk)); + if(pfo->charge()!=0 && acceptChargedPFO(eltrk,pv) && pfo->track(0) == eltrk) match = true; + } + if (match) nearbyPFO.push_back(pfo); + } + ATH_MSG_VERBOSE("Found " << nearbyPFO.size() << " nearby pfos"); + + bool doSum = true; + double sumE_pfo = 0.; + std::sort(nearbyPFO.begin(),nearbyPFO.end(),greaterPtPFO); + for(const auto& pfo : nearbyPFO) { + double pfo_e = (pfo->charge()==0 ? pfo->eEM() : pfo->e()); + // skip cluster if it's above our bad match threshold + if(pfo->eEM()>m_tcMatch_maxRat*eg_cl_e) { + ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (pfo->eEM()/eg_cl_e)); + continue; + } + + if( (doSum = fabs(sumE_pfo+pfo->e()-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) { + pfolist.push_back(pfo); + sumE_pfo += pfo_e; + pfovec += (pfo->charge()==0 ? MissingETBase::Types::constvec_t(pfo->ptEM()*cos(pfo->phiEM()),pfo->ptEM()*sin(pfo->phiEM()),pfo->ptEM()*cosh(pfo->etaEM()),pfo->eEM(),pfo->eEM()) : MissingETBase::Types::constvec_t(*pfo)); + trkvec += MissingETBase::Types::constvec_t(*pfo); + } // if we will retain the topocluster + else {break;} + } // loop over nearby clusters + + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx b/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c41e88c9e5ffd5cbdaf9e27f45183868f058f05d --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METJetAssocTool.cxx @@ -0,0 +1,135 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METJetAssocTool.cxx +// Implementation file for class METJetAssocTool +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METJetAssocTool.h" + +// MET EDM +#include "xAODMissingET/MissingETComposition.h" + +// Jet EDM +#include "xAODJet/JetContainer.h" +#include "xAODJet/JetAttributes.h" + +// Tracking EDM +#include "xAODTracking/Vertex.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METJetAssocTool::METJetAssocTool(const std::string& name) : + AsgTool(name), + METAssociator(name) + {} + + // Destructor + /////////////// + METJetAssocTool::~METJetAssocTool() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METJetAssocTool::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METJetAssocTool::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + // executeTool + //////////////// + StatusCode METJetAssocTool::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + + // Retrieve the jet container + const JetContainer* jetCont = 0; + if( evtStore()->retrieve(jetCont, m_input_data_key).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input jet container " << m_input_data_key); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Successfully retrieved jet collection"); + + // Retrieve the vertices + const VertexContainer* vxCont = 0; + if( evtStore()->retrieve(vxCont,"PrimaryVertices").isFailure() ) { // configurable + ATH_MSG_WARNING("Unable to retrieve vertex container"); + return StatusCode::FAILURE; + } + const Vertex* pv = 0; + ATH_MSG_DEBUG("Successfully retrieved vertex collection"); + for(const auto& vx : *vxCont) { + if(vx->vertexType()==VxType::PriVtx) + {pv = vx; break;} + } + if(!pv) { + ATH_MSG_WARNING("Failed to find primary vertex!"); + return StatusCode::FAILURE; + } + + // Create jet associations + MissingETBase::Types::constvec_t trkvec; + for(const auto& jet : *jetCont) { + std::vector<const IParticle*> selectedTracks; + if (m_pflow) { + for (size_t consti = 0; consti < jet->numConstituents(); consti++) { + const xAOD::PFO *pfo = dynamic_cast<const xAOD::PFO*>(jet->rawConstituent(consti)); + if (pfo->charge()!=0) trkvec += *pfo; + } + } else { + std::vector<const IParticle*> jettracks; + jet->getAssociatedObjects<IParticle>(JetAttribute::GhostTrack,jettracks); + + selectedTracks.reserve(jettracks.size()); + for(const auto& trk : jettracks) { + const TrackParticle* pTrk = dynamic_cast<const TrackParticle*>(trk); + if( acceptTrack(pTrk,pv) ) { + selectedTracks.push_back(trk); + ATH_MSG_VERBOSE("Accept track " << trk << " px, py = " << trk->p4().Px() << ", " << trk->p4().Py()); + } + } + } + MissingETComposition::add(metMap,jet,selectedTracks); + if (m_pflow) metMap->back()->setJetTrkVec(trkvec); + ATH_MSG_VERBOSE("Added association " << metMap->findIndex(jet) << " pointing to jet " << jet); + ATH_MSG_VERBOSE("Jet pt, eta, phi = " << jet->pt() << ", " << jet->eta() << "," << jet->phi() ); + + } + MissingETComposition::addMiscAssociation(metMap); + ATH_MSG_DEBUG("Added miscellaneous association"); + + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx b/Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx index 30d1f02036c8c142c86904de8d8283bb6187da0d..f57889138c29b674326e2e31963a15579c859c17 100644 --- a/Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx @@ -96,6 +96,10 @@ namespace met { fabs(jet->eta()) < m_jet_maxEtaJVF ) { vector<float> jvf; jet->getAttribute<vector<float> >(JetAttribute::JVF,jvf); + if(!jet->getAttribute<vector<float> >(JetAttribute::JVF,jvf)) { + ATH_MSG_WARNING("Jet JVF unavailable!"); + return false; + } ATH_MSG_VERBOSE("Jet JVF = " << jvf[0]); if( fabs(jvf[0]) < m_jet_minAbsJVF ) return false; } diff --git a/Reconstruction/MET/METReconstruction/Root/METJetTool.cxx b/Reconstruction/MET/METReconstruction/Root/METJetTool.cxx index 80fac487247d6aff3792cfa8362a9c8bca4d12b0..163e319020802cd36bf29f5e1e156c6b619f608f 100644 --- a/Reconstruction/MET/METReconstruction/Root/METJetTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METJetTool.cxx @@ -129,6 +129,7 @@ namespace met { { const Jet* jet = dynamic_cast<const Jet*>(object); + m_signalstate = jet->getConstituentsSignalState(); ATH_MSG_VERBOSE("Retrieving jet constituents."); // first get the topoclusters @@ -141,16 +142,14 @@ namespace met { vector<const IParticle*> constit_vec; constit_vec.reserve(jet->numConstituents()); CaloClusterChangeSignalStateList stateHelperList; - //stateHelperList.reserve(jet->numConstituents()); for(JetConstituentVector::const_iterator iClus = constit.begin(); iClus!=constit.end(); ++iClus) { sumE_allclus += (*iClus)->e(); const CaloCluster* pClus = dynamic_cast<const CaloCluster*>( (*iClus)->rawConstituent() ); - // create a helper to change the signal state and retain it until the end of the method - // signal state will be reset when it goes out of scope - //CaloClusterChangeSignalState stateHelper(pClus, CaloCluster::State(m_signalstate)); stateHelperList.add(pClus, CaloCluster::State(m_signalstate)); + ATH_MSG_VERBOSE("Constit E = " << pClus->e()); + constit_vec.push_back(pClus); } // loop over jet constituents ATH_MSG_VERBOSE( "Jet E = " << jet->e() << ", cluster energy sum = " << sumE_allclus ); @@ -165,6 +164,7 @@ namespace met { iClus!=constit_vec.end(); ++iClus) { sumE_unique += (*iClus)->e(); acceptedSignals.push_back(*iClus); + ATH_MSG_VERBOSE("Unique constit E = " << (*iClus)->e()); } // loop over jet unique constituents double scalef = sumE_unique / sumE_allclus; // weight as an entire object with the unused E fraction @@ -236,20 +236,23 @@ namespace met { this->addToMET(*iJet,signalList,metTerm,metMap,objWeight); } else { if( m_jet_doMinWetPtCut ) { - if( objWeight.wet() > m_jet_minWet ) { - ATH_MSG_VERBOSE("Jet weighted energy is above threshold -- add to MET"); - this->addToMET(*iJet,signalList,metTerm,metMap,objWeight); - ATH_MSG_VERBOSE("Jet px = " << (*iJet)->px() - << ", weighted px = " << (*iJet)->px()*objWeight.wpx() - << ", MET px = " << metTerm->mpx() ); - } - } else { if( (*iJet)->pt()*objWeight.wet() > m_jet_minPt ) { ATH_MSG_VERBOSE("Jet unique energy is above threshold -- add to MET."); this->addToMET(*iJet,signalList,metTerm,metMap,objWeight); ATH_MSG_VERBOSE("Jet px = " << (*iJet)->px() << ", weighted px = " << (*iJet)->px()*objWeight.wpx() << ", MET px = " << metTerm->mpx() ); + ATH_MSG_VERBOSE("Jet pt = " << (*iJet)->pt() + << ", weighted pt = " << (*iJet)->pt()*objWeight.wet() + << ", MET pt = " << metTerm->met() ); + } + } else { + if( objWeight.wet() > m_jet_minWet ) { + ATH_MSG_VERBOSE("Jet weighted energy is above threshold -- add to MET"); + this->addToMET(*iJet,signalList,metTerm,metMap,objWeight); + ATH_MSG_VERBOSE("Jet px = " << (*iJet)->px() + << ", weighted px = " << (*iJet)->px()*objWeight.wpx() + << ", MET px = " << metTerm->mpx() ); } } // end if minWet } diff --git a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f0eb2a78fd34684d8a88e65ad3ab7d46b9a3aad8 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx @@ -0,0 +1,139 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METMuonAssociator.cxx +// Implementation file for class METMuonAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METMuonAssociator.h" + +// Muon EDM +#include "xAODMuon/MuonContainer.h" + +// Tracking EDM +#include "xAODTracking/Vertex.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METMuonAssociator::METMuonAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name) + {} + + // Destructor + /////////////// + METMuonAssociator::~METMuonAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METMuonAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METMuonAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + // executeTool + //////////////// + StatusCode METMuonAssociator::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + + const MuonContainer* muonCont(0); + if( evtStore()->retrieve(muonCont, m_input_data_key).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input muon container " << m_input_data_key); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Successfully retrieved muon collection"); + if (fillAssocMap(metMap,muonCont).isFailure()) { + ATH_MSG_WARNING("Unable to fill map with muon container " << m_input_data_key); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Get constituents + StatusCode METMuonAssociator::extractTopoClusters(const xAOD::IParticle* /*obj*/, + std::vector<const xAOD::IParticle*>& /*tclist*/, + MissingETBase::Types::constvec_t& /*tcvec*/, + const xAOD::CaloClusterContainer* /*tcCont*/) + { + return StatusCode::SUCCESS; + } + + StatusCode METMuonAssociator::extractTracks(const xAOD::IParticle *obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* /*tcCont*/, + const xAOD::Vertex* pv) + { + const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj); + const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle); + //if(idtrack && acceptTrack(idtrack,pv) && isGoodEoverP(idtrack,tcCont)) { + if(idtrack && acceptTrack(idtrack,pv)) { + ATH_MSG_VERBOSE("Accept muon track " << idtrack << " px, py = " << idtrack->p4().Px() << ", " << idtrack->p4().Py()); + ATH_MSG_VERBOSE("Muon ID track ptr: " << idtrack); + constlist.push_back(idtrack); + trkvec += *idtrack; + // if(mu->pt()>10e3 && (mu->muonType()==xAOD::Muon::Combined || mu->muonType()==xAOD::Muon::SegmentTagged)) { + // mutracks.push_back(idtrack); + // } + } + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Get constituents + StatusCode METMuonAssociator::extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) + { + const xAOD::Muon *mu = static_cast<const xAOD::Muon*>(obj); + const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle); + if(idtrack && acceptChargedPFO(idtrack,pv)) { + for(const auto& pfo : *pfoCont) { + if (pfo->charge()!=0 && pfo->track(0) == idtrack) { + pfolist.push_back(pfo); + trkvec += *idtrack; + pfovec += *idtrack; + } + } + } + return StatusCode::SUCCESS; + } + + + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METMuonTool.cxx b/Reconstruction/MET/METReconstruction/Root/METMuonTool.cxx index 70151d142f77731e4a9bd1c360ee9f7e38184b30..b7118afb7a69771fd98bc2f7088c4bb134787940 100644 --- a/Reconstruction/MET/METReconstruction/Root/METMuonTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METMuonTool.cxx @@ -121,9 +121,9 @@ namespace met { if(nPrecision<m_mu_nPrecisionHits) return false; } // only if we use SA muons } // selection for StandAlone muons - else { + else if(mu->muonType()==Muon::Combined || mu->muonType()==Muon::SegmentTagged) { if(fabs(mu->eta())>m_mu_maxEta) return false; - + // could add some error checking to make sure we successfully read the details uint8_t nPixHits(0), nSctHits(0); if(!mu->primaryTrackParticleLink().isValid()) return false; @@ -133,7 +133,8 @@ namespace met { if(nPixHits<m_mu_nPixHits) return false; if(nPixHits+nSctHits<m_mu_nSiHits) return false; } // selection for SegmentTagged and Combined muons - + else {return false;} // don't accept forward muons or calo tagged + return true; } diff --git a/Reconstruction/MET/METReconstruction/Root/METPhotonAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METPhotonAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7c10b71a07d26a24f62c076a56b2b0cf0ac7380e --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METPhotonAssociator.cxx @@ -0,0 +1,195 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METPhotonAssociator.cxx +// Implementation file for class METPhotonAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METPhotonAssociator.h" + +// Egamma EDM +#include "xAODEgamma/PhotonContainer.h" +#include "xAODEgamma/EgammaxAODHelpers.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METPhotonAssociator::METPhotonAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name), + METEgammaAssociator(name) + {} + + // Destructor + /////////////// + METPhotonAssociator::~METPhotonAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METPhotonAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METPhotonAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + // executeTool + //////////////// + StatusCode METPhotonAssociator::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + + const xAOD::PhotonContainer* phCont(0); + if( evtStore()->retrieve(phCont, m_input_data_key).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input photon container " << m_input_data_key); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("Successfully retrieved photon collection"); + + if (fillAssocMap(metMap,phCont).isFailure()) { + ATH_MSG_WARNING("Unable to fill map with photon container " << m_input_data_key); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + + StatusCode METPhotonAssociator::extractTracks(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* /*tcCont*/, + const xAOD::Vertex* pv) + { + const xAOD::Photon *ph = static_cast<const xAOD::Photon*>(obj); + std::vector<const xAOD::TrackParticle*> phtrks; + for(size_t iVtx=0; iVtx<ph->nVertices(); ++iVtx) { + const xAOD::Vertex* phvx = ph->vertex(iVtx); + for(size_t iTrk=0; iTrk<phvx->nTrackParticles(); ++iTrk) { + // if(!phvx->trackParticle(iTrk)) { + // ATH_MSG_VERBOSE("Invalid photon trackparticle pointer"); + // } + const xAOD::TrackParticle* phtrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(phvx->trackParticle(iTrk)); + // if(acceptTrack(phtrk,pv) && isGoodEoverP(phtrk,tcCont)) { + if(acceptTrack(phtrk,pv)) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (phtrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + bool duplicate = false; + for(const auto& gamtrk : phtrks) { + if( (duplicate = (phtrk == gamtrk)) ) { + ATH_MSG_VERBOSE("Veto duplicate track"); + break; + } + } + // if(!matchedmu && !duplicate) { + if(!duplicate) { + ATH_MSG_VERBOSE("Accept photon track " << phtrk << " px, py = " << phtrk->p4().Px() << ", " << phtrk->p4().Py()); + ATH_MSG_VERBOSE(" track eta, phi = " << phtrk->p4().Eta() << ", " << phtrk->p4().Phi()); + constlist.push_back(phtrk); + trkvec += *phtrk; + phtrks.push_back(phtrk); + } + } + } + } + return StatusCode::SUCCESS; + } + //********************************************************************** + // Get Egamma constituents + StatusCode METPhotonAssociator::extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) + { + const xAOD::Photon *ph = static_cast<const xAOD::Photon*>(obj); + // safe to assume a single SW cluster? + // will do so for now... + const xAOD::CaloCluster* swclus = ph->caloCluster(); + double eg_cl_e = swclus->e(); + + // the matching strategy depends on how the cluster container is sorted + // easier if it's sorted in descending pt order + // we'll worry about optimisation later + std::vector<const xAOD::PFO*> nearbyPFO; + nearbyPFO.reserve(10); + for(const auto& pfo : *pfoCont) { + std::vector<const IParticle*> cls; + bool match = false; + if (pfo->charge()==0) { + if (swclus->p4().DeltaR(pfo->p4EM())<0.1 && pfo->eEM()>0) match = true; + //pfo->associatedParticles(PFODetails::CaloCluster,cls); + //for(const auto& cl : cls) { + // if (!cl) continue; + // double dR = swclus->p4().DeltaR(cl->p4()); + // if(dR<0.1 && cl->e()>0) match = true; + //} + } + for(size_t iVtx=0; iVtx<ph->nVertices(); ++iVtx) { + const xAOD::Vertex* phvx = ph->vertex(iVtx); + for(size_t iTrk=0; iTrk<phvx->nTrackParticles(); ++iTrk) { + const xAOD::TrackParticle* phtrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(phvx->trackParticle(iTrk)); + if(pfo->charge()!=0 && acceptChargedPFO(phtrk,pv) && pfo->track(0) == phtrk) match = true; + } + } + if (match) nearbyPFO.push_back(pfo); + } + ATH_MSG_VERBOSE("Found " << nearbyPFO.size() << " nearby pfos"); + + bool doSum = true; + double sumE_pfo = 0.; + std::sort(nearbyPFO.begin(),nearbyPFO.end(),greaterPtPFO); + for(const auto& pfo : nearbyPFO) { + double pfo_e = (pfo->charge()==0 ? pfo->eEM() : pfo->e()); + // skip cluster if it's above our bad match threshold + if(pfo->eEM()>m_tcMatch_maxRat*eg_cl_e) { + ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (pfo->eEM()/eg_cl_e)); + continue; + } + + if( (doSum = fabs(sumE_pfo+pfo->e()-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) { + pfolist.push_back(pfo); + sumE_pfo += pfo_e; + pfovec += (pfo->charge()==0 ? MissingETBase::Types::constvec_t(pfo->ptEM()*cos(pfo->phiEM()),pfo->ptEM()*sin(pfo->phiEM()),pfo->ptEM()*cosh(pfo->etaEM()),pfo->eEM(),pfo->eEM()) : MissingETBase::Types::constvec_t(*pfo)); + trkvec += MissingETBase::Types::constvec_t(*pfo); + } // if we will retain the topocluster + else {break;} + } // loop over nearby clusters + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..091bbe408f4b52888b557f73a260b5235c57210d --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METSoftAssociator.cxx @@ -0,0 +1,114 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METSoftAssociator.cxx +// Implementation file for class METSoftAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METSoftAssociator.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METSoftAssociator::METSoftAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name) + { + } + + // Destructor + /////////////// + METSoftAssociator::~METSoftAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METSoftAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + + return StatusCode::SUCCESS; + } + + StatusCode METSoftAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + // executeTool + //////////////// + StatusCode METSoftAssociator::executeTool(xAOD::MissingETContainer* metCont, xAOD::MissingETAssociationMap* metMap) + { + + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + const xAOD::CaloClusterContainer* tcCont; + const xAOD::Vertex* pv; + const xAOD::TrackParticleContainer* trkCont; + const xAOD::PFOContainer* pfoCont; + if (retrieveConstituents(tcCont,pv,trkCont,pfoCont).isFailure()) { + ATH_MSG_WARNING("Unable to retrieve constituent containers"); + return StatusCode::FAILURE; + } + + // Create a MissingETContainer with its aux store + MissingET* metCoreCl = new MissingET(0.,0.,0.,"SoftClusCore",MissingETBase::Source::softEvent() | MissingETBase::Source::cluster()); + metCont->push_back(metCoreCl); + MissingET* metCoreTrk = new MissingET(0.,0.,0.,"PVSoftTrkCore",MissingETBase::Source::softEvent() | MissingETBase::Source::track()); + metCont->push_back(metCoreTrk); + if (m_pflow) { + const IParticleContainer* uniquePFOs = metMap->getUniqueSignals(pfoCont,MissingETBase::UsageHandler::Policy::ParticleFlow); + for(const auto& sig : *uniquePFOs) { + const PFO *pfo = dynamic_cast<const PFO*>(sig); + if (pfo->charge()!=0) { + if (acceptChargedPFO(pfo->track(0),pv)) { + *metCoreTrk += sig; + *metCoreCl += sig; + } + } else { + TLorentzVector corrected = pfo->GetVertexCorrectedEMFourVec(*pv); + if (pfo->eEM()>0) metCoreCl->add(corrected.Px(),corrected.Py(),corrected.Pt()); + } + } + } else { + const IParticleContainer* uniqueClusters = metMap->getUniqueSignals(tcCont); + for(const auto& cl : *uniqueClusters) { + if (cl->e()>0) *metCoreCl += cl; + } + const IParticleContainer* uniqueTracks = metMap->getUniqueSignals(trkCont); + for(const auto& trk : *uniqueTracks) { + // if(acceptTrack(dynamic_cast<const TrackParticle*>(trk),pv) && isGoodEoverP(dynamic_cast<const TrackParticle*>(trk),tcCont)) { + ATH_MSG_VERBOSE("Test core track with pt " << trk->pt()); + if(acceptTrack(dynamic_cast<const TrackParticle*>(trk),pv)) { + ATH_MSG_VERBOSE("Add core track with pt " << trk->pt()); + *metCoreTrk += trk; + } + } + } + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx b/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx index b58995166cf52e0df605622145c7bef5cfb178f6..fa52907e1edee71889024d8b64a63bb301eb8243 100644 --- a/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METSoftTermsTool.cxx @@ -150,23 +150,25 @@ namespace met { bool METSoftTermsTool::accept(const xAOD::CaloCluster* clus) const { + if(!clus) return false; if(m_cl_vetoNegE && clus->e()<0) return false; if(m_cl_onlyNegE && clus->e()>0) return false; return true; } - bool METSoftTermsTool::accept(const xAOD::TrackParticle* trk) const + bool METSoftTermsTool::accept(const xAOD::TrackParticle* /*trk*/) const { + // if(!trk) return false; - if(fabs(trk->pt())<500/*MeV*/ || fabs(trk->eta())>2.5) return false; - - // could add some error checking to make sure we successfully read the details - uint8_t nPixHits(0), nSctHits(0); - trk->summaryValue(nPixHits,xAOD::numberOfPixelHits); - if(nPixHits<1) return false; - trk->summaryValue(nSctHits,xAOD::numberOfSCTHits); - if(nSctHits<6) return false; +// if(fabs(trk->pt())<500/*MeV*/ || fabs(trk->eta())>2.5) return false; +// +// // could add some error checking to make sure we successfully read the details +// uint8_t nPixHits(0), nSctHits(0); +// trk->summaryValue(nPixHits,xAOD::numberOfPixelHits); +// if(nPixHits<1) return false; +// trk->summaryValue(nSctHits,xAOD::numberOfSCTHits); +// if(nSctHits<6) return false; return true; } diff --git a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7d86d32bc62d8246daf3222786dbd2df2f0ab16b --- /dev/null +++ b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx @@ -0,0 +1,200 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METTauAssociator.cxx +// Implementation file for class METTauAssociator +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// +// Author: P Loch, S Resconi, TJ Khoo, AS Mete +/////////////////////////////////////////////////////////////////// + +// METReconstruction includes +#include "METReconstruction/METTauAssociator.h" + +// MET EDM +#include "xAODMissingET/MissingETComposition.h" + +// Tau EDM +#include "xAODTau/TauJetContainer.h" + +// Calo helpers +#include "xAODCaloEvent/CaloClusterChangeSignalState.h" + +// Tracking EDM +#include "xAODTracking/Vertex.h" + +namespace met { + + using namespace xAOD; + + // Constructors + //////////////// + METTauAssociator::METTauAssociator(const std::string& name) : + AsgTool(name), + METAssociator(name) + {} + + // Destructor + /////////////// + METTauAssociator::~METTauAssociator() + {} + + // Athena algtool's Hooks + //////////////////////////// + StatusCode METTauAssociator::initialize() + { + ATH_MSG_VERBOSE ("Initializing " << name() << "..."); + return StatusCode::SUCCESS; + } + + StatusCode METTauAssociator::finalize() + { + ATH_MSG_VERBOSE ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected methods: + /////////////////////////////////////////////////////////////////// + + // executeTool + //////////////// + StatusCode METTauAssociator::executeTool(xAOD::MissingETContainer* /*metCont*/, xAOD::MissingETAssociationMap* metMap) + { + ATH_MSG_VERBOSE ("In execute: " << name() << "..."); + + const TauJetContainer* tauCont(0); + if( evtStore()->retrieve(tauCont, m_input_data_key).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input electron container " << m_input_data_key); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("Successfully retrieved electron collection"); + if (fillAssocMap(metMap,tauCont).isFailure()) { + ATH_MSG_WARNING("Unable to fill map with tau container " << m_input_data_key); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; + } + + + //********************************************************************************************************* + // Get tau constituents + StatusCode METTauAssociator::extractTopoClusters(const xAOD::IParticle *obj, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec, + const xAOD::CaloClusterContainer* /*tcCont*/) + { + const TauJet* tau = static_cast<const TauJet*>(obj); + const Jet* seedjet = *tau->jetLink(); + JetConstituentVector constit = seedjet->getConstituents(); + CaloClusterChangeSignalStateList stateHelperList; + ATH_MSG_VERBOSE("Current tau has " << constit.size() << " constituents."); + // test for used topoclusters, and retrieve unused ones (ok until/unless we use PFlow taus) + // only use clusters for computing the overlap removal relative to other objects + for(const auto& cl : constit) { + // TEMP: use jet seed axis + // taus will provide an accessor + double dR = seedjet->p4().DeltaR(cl->rawConstituent()->p4()); + if(dR>0.2) continue; + // skip cluster if dR>0.2 + const CaloCluster* pClus = dynamic_cast<const CaloCluster*>( cl->rawConstituent() ); + stateHelperList.add(pClus, CaloCluster::State(m_signalstate)); + tclist.push_back(pClus); + tcvec += MissingETBase::Types::constvec_t(*pClus); + } // loop over jet constituents + return StatusCode::SUCCESS; + } + + + StatusCode METTauAssociator::extractTracks(const xAOD::IParticle *obj, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::CaloClusterContainer* /*tcCont*/, + const xAOD::Vertex* pv) + { + const TauJet* tau = static_cast<const TauJet*>(obj); + const Jet* jet = *tau->jetLink(); + for(size_t iTrk=0; iTrk<tau->nTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->track(iTrk); + // if(acceptTrack(tautrk,pv) && isGoodEoverP(tautrk,tcCont)) { + if(acceptTrack(tautrk,pv)) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (tautrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + // if(!matchedmu) { + ATH_MSG_VERBOSE("Accept tau track " << tautrk << " px, py = " << tautrk->p4().Px() << ", " << tautrk->p4().Py()); + constlist.push_back(tautrk); + trkvec += *tautrk; + // } + } + } + for(size_t iTrk=0; iTrk<tau->nOtherTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->otherTrack(iTrk); + double dR = jet->p4().DeltaR(tautrk->p4()); + //if(dR<0.2 && acceptTrack(tautrk,pv) && isGoodEoverP(tautrk,tcCont)) { + if(dR<0.2 && acceptTrack(tautrk,pv)) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (tautrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + // if(!matchedmu) { + ATH_MSG_VERBOSE("Accept track " << tautrk << " px, py = " << tautrk->p4().Px() << ", " << tautrk->p4().Py()); + constlist.push_back(tautrk); + trkvec += *tautrk; + // } + } + } + return StatusCode::SUCCESS; + } + //********************************************************************************************************* + // Get tau constituents + StatusCode METTauAssociator::extractPFO(const xAOD::IParticle* obj, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::PFOContainer* pfoCont, + const xAOD::Vertex* pv) + { + const TauJet* tau = static_cast<const TauJet*>(obj); + const Jet* seedjet = *tau->jetLink(); + for(const auto& pfo : *pfoCont) { + bool match = false; + if (pfo->charge()==0 && seedjet->p4().DeltaR(pfo->p4EM())<0.2) match = true; + for(size_t iTrk=0; iTrk<tau->nTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->track(iTrk); + if(acceptChargedPFO(tautrk,pv) && pfo->charge()!=0 && tautrk==pfo->track(0)) match = true; + } + for(size_t iTrk=0; iTrk<tau->nOtherTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->otherTrack(iTrk); + double dR = seedjet->p4().DeltaR(tautrk->p4()); + if(dR<0.2 && acceptChargedPFO(tautrk,pv) && pfo->charge()!=0 && tautrk==pfo->track(0)) match = true; + } + if (!match) continue; + pfolist.push_back(pfo); + if (pfo->charge()) trkvec += MissingETBase::Types::constvec_t(*pfo); + pfovec += (pfo->charge()==0 ? MissingETBase::Types::constvec_t(pfo->ptEM()*cos(pfo->phiEM()),pfo->ptEM()*sin(pfo->phiEM()),pfo->ptEM()*cosh(pfo->etaEM()),pfo->eEM(),pfo->eEM()) : MissingETBase::Types::constvec_t(*pfo)); + } + return StatusCode::SUCCESS; + } + +} diff --git a/Reconstruction/MET/METReconstruction/Root/METTauTool.cxx b/Reconstruction/MET/METReconstruction/Root/METTauTool.cxx index 7e27ad63c6609dd896f4dcd3590cd3df64862c4e..ded1d869bf88f6b6c61e53fdfba6d4d6d14e0ab2 100644 --- a/Reconstruction/MET/METReconstruction/Root/METTauTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METTauTool.cxx @@ -247,25 +247,25 @@ namespace met { if ( this->resolveOverlap(*iTau,metMap,signalList,objWeight) ) { // add if not overlapping anything this->addToMET(*iTau,signalList,metTerm,metMap,objWeight); - } else { + } else { // no overlaps if( m_tau_doMinWetPtCut ) { - if ( objWeight.wet() > m_tau_minWet ) { + if( (*iTau)->pt()*objWeight.wet() > m_tau_minPt ) { ATH_MSG_VERBOSE("Tau weighted energy is above threshold -- add to MET"); this->addToMET(*iTau,signalList,metTerm,metMap,objWeight); //ATH_MSG_VERBOSE("Tau px = " << (*iTau)->px() // << " , weighted px = " << (*iTau)->px()*objWeight.wpx() // << " ,MET px = " << metTerm->mpx() ); - } + } // if passes weighted pt cut } else { - if( (*iTau)->pt()*objWeight.wet() > m_tau_minPt ) { + if ( objWeight.wet() > m_tau_minWet ) { ATH_MSG_VERBOSE("Tau weighted energy is above threshold -- add to MET"); this->addToMET(*iTau,signalList,metTerm,metMap,objWeight); //ATH_MSG_VERBOSE("Tau px = " << (*iTau)->px() // << " , weighted px = " << (*iTau)->px()*objWeight.wpx() // << " ,MET px = " << metTerm->mpx() ); - } - } // end if minWet - } + } // if passes weight cut + } // end if do weighted pt cut + } // overlapping } // if passing selection } // loop on tau container return StatusCode::SUCCESS; diff --git a/Reconstruction/MET/METReconstruction/Root/METTrackFilterTool.cxx b/Reconstruction/MET/METReconstruction/Root/METTrackFilterTool.cxx index cff589ca54e983ab79f169e573aecd93164778a9..64bd36db46c1258c139f0bc7f28a2c489c1470a3 100644 --- a/Reconstruction/MET/METReconstruction/Root/METTrackFilterTool.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METTrackFilterTool.cxx @@ -27,26 +27,21 @@ // Calo EDM #include "xAODCaloEvent/CaloClusterContainer.h" +// Egamma EDM +#include "xAODEgamma/EgammaxAODHelpers.h" +#include "xAODEgamma/Electron.h" + // Track errors #include "EventPrimitives/EventPrimitivesHelpers.h" +// ConstDV +#include "AthContainers/ConstDataVector.h" + namespace met { using std::vector; // - using xAOD::IParticle; - // - using xAOD::TrackParticle; - using xAOD::TrackParticleContainer; - using xAOD::VertexContainer; - // - using xAOD::CaloCluster; - using xAOD::CaloClusterContainer; - // - using xAOD::MissingET; - using xAOD::MissingETComposition; - using xAOD::MissingETComponent; - using xAOD::MissingETComponentMap; + using namespace xAOD; /////////////////////////////////////////////////////////////////// // Public methods: @@ -58,12 +53,19 @@ namespace met { AsgTool(name), METRefinerTool(name) { - declareProperty( "DoPVSel", m_trk_doPVsel = true ); - declareProperty( "TrackD0Max", m_trk_d0Max = 1.5 ); - declareProperty( "TrackZ0Max", m_trk_z0Max = 1.5 ); - declareProperty( "InputPVKey", m_pv_inputkey = "PrimaryVertices" ); - declareProperty( "DoEoverPSel", m_trk_doEoverPsel = true ); - declareProperty( "InputClusterKey", m_cl_inputkey = "CaloCalTopoCluster" ); + declareProperty( "DoPVSel", m_trk_doPVsel = true ); + // declareProperty( "TrackD0Max", m_trk_d0Max = 1.5 ); + // declareProperty( "TrackZ0Max", m_trk_z0Max = 1.5 ); + declareProperty( "InputPVKey", m_pv_inputkey = "PrimaryVertices" ); + declareProperty( "DoEoverPSel", m_trk_doEoverPsel = false ); + declareProperty( "InputClusterKey", m_cl_inputkey = "CaloCalTopoClusters" ); + declareProperty( "InputElectronKey", m_el_inputkey = "Electrons" ); + declareProperty( "InputMuonKey", m_mu_inputkey = "Muons" ); + + declareProperty( "DoVxSep", m_doVxSep = false ); + declareProperty( "TrackSelectorTool", m_trkseltool ); + declareProperty( "TrackVxAssocTool", m_trkToVertexTool ); + declareProperty( "DoLepRecovery", m_doLepRecovery=false ); } // Destructor @@ -76,6 +78,10 @@ namespace met { StatusCode METTrackFilterTool::initialize() { ATH_MSG_INFO ("Initializing " << name() << "..."); + ATH_CHECK(m_trkseltool.retrieve()); + ATH_CHECK(m_trkToVertexTool.retrieve()); + + if(m_doVxSep) ATH_MSG_INFO("Building TrackMET for each vertex"); return StatusCode::SUCCESS; } @@ -100,15 +106,14 @@ namespace met { /////////////////////////////////////////////////////////////////// // Implement for now, but should move to common tools when possible - bool METTrackFilterTool::isPVTrack(const xAOD::TrackParticle* trk, - const xAOD::Vertex* pv) const - { - - if(trk->d0()>m_trk_d0Max) return false; - if(fabs(trk->z0()+trk->vz() - pv->z()) > m_trk_z0Max) return false; - - return true; - } + // bool METTrackFilterTool::isPVTrack(const xAOD::TrackParticle* /*trk*/, + // const xAOD::Vertex* /*pv*/) const + // { + // if(!trk || !pv) return false; + // if(fabs(trk->d0())>m_trk_d0Max) return false; + // if(fabs(trk->z0()+trk->vz() - pv->z()) > m_trk_z0Max) return false; + // return true; + // } bool METTrackFilterTool::isGoodEoverP(const xAOD::TrackParticle* trk, const std::vector<const xAOD::IParticle*>& trkList, @@ -163,32 +168,32 @@ namespace met { ATH_MSG_DEBUG ("In execute: " << name() << "..."); - if(m_trk_doPVsel) { - m_pv_cont = 0; - if( evtStore()->retrieve( m_pv_cont, m_pv_inputkey).isFailure() ) { - ATH_MSG_WARNING("Unable to retrieve input primary vertex container"); - return StatusCode::SUCCESS; - } - if(m_pv_cont->size()>0) { - ATH_MSG_DEBUG("Main primary vertex has z = " << (*m_pv_cont)[0]->z()); - } else{ - ATH_MSG_WARNING("Event has no primary vertices"); - return StatusCode::SUCCESS; - } - } + std::vector<const xAOD::Electron*> selElectrons; + std::vector<const xAOD::Muon*> selMuons; - const CaloClusterContainer* cl_cont = 0; - if(m_trk_doEoverPsel) { - if( evtStore()->retrieve( cl_cont, m_cl_inputkey).isFailure() ) { - ATH_MSG_WARNING("Unable to retrieve input calocluster container"); - return StatusCode::SUCCESS; - } - } + if(m_doLepRecovery) + { + const ElectronContainer* elCont; + const MuonContainer* muCont; + ATH_CHECK(evtStore()->retrieve(elCont,m_el_inputkey)); + ATH_CHECK(evtStore()->retrieve(muCont,m_mu_inputkey)); + + selectElectrons(*elCont, selElectrons); + selectMuons(*muCont, selMuons); + } + + // const CaloClusterContainer* cl_cont = 0; + // if(m_trk_doEoverPsel) { + // if( evtStore()->retrieve( cl_cont, m_cl_inputkey).isFailure() ) { + // ATH_MSG_WARNING("Unable to retrieve input calocluster container"); + // return StatusCode::FAILURE; + // } + // } MissingETComponentMap::iterator iter = MissingETComposition::find(metMap,metTerm); if(iter==metMap->end()) { ATH_MSG_WARNING("Could not find current METComponent in MET Map!"); - return StatusCode::SUCCESS; + return StatusCode::FAILURE; } MissingETComponent* newComp = *iter; newComp->setStatusWord(MissingETBase::Status::Tags::correctedTerm(MissingETBase::Status::Nominal, @@ -197,38 +202,192 @@ namespace met { // Extract the component corresponding to the Track SoftTerms MissingETBase::Types::bitmask_t src_ST_idTrk = MissingETBase::Source::SoftEvent | MissingETBase::Source::idTrack(); MissingETBase::Types::bitmask_t src_ST_refTrk = MissingETBase::Source::softEvent() | MissingETBase::Source::track(); + metTerm->setSource(src_ST_refTrk); + MissingETComponentMap::const_iterator citer = MissingETComposition::find(metMap,src_ST_idTrk); if(citer==metMap->end()) { ATH_MSG_WARNING("Could not find Soft ID Track component in MET Map!"); - return StatusCode::SUCCESS; + return StatusCode::FAILURE; + } + vector<const TrackParticle*> softTracks; + softTracks.reserve((*citer)->size()); + for(const auto& obj : (*citer)->objects()) { + const TrackParticle* trk = dynamic_cast<const TrackParticle*>(obj); + if(trk) {softTracks.push_back(trk);} + else {ATH_MSG_WARNING("Track filter given an object of type " << obj->type());} } - vector<const IParticle*> softTrackList = (*citer)->objects(); - metTerm->setSource(src_ST_refTrk); + const Vertex* pv=0; + const VertexContainer* vxCont = 0; + vector<const Vertex*> vertices; + if(m_trk_doPVsel) { + if( evtStore()->retrieve( vxCont, m_pv_inputkey).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input primary vertex container"); + return StatusCode::FAILURE; + } + if(vxCont->size()>0) { + vertices.reserve(vxCont->size()); + for(const auto& vx : *vxCont) { + if(vx->vertexType()==VxType::PriVtx) {pv = vx;} + vertices.push_back(vx); + } + ATH_MSG_DEBUG("Main primary vertex has z = " << pv->z()); + } else{ + ATH_MSG_WARNING("Event has no primary vertices"); + return StatusCode::FAILURE; + } + if(!pv) { + ATH_MSG_WARNING("Did not find a primary vertex in the container."); + return StatusCode::FAILURE; + } + } + + if(m_doVxSep) { + xAOD::TrackVertexAssociationMap trktovxmap=m_trkToVertexTool->getUniqueMatchMap(softTracks, vertices); + + // initialize metContainer and metTerm + MissingETContainer* metCont = static_cast<MissingETContainer*>( metTerm->container() ); + + bool firstVx(true); + std::string basename = metTerm->name()+"_vx"; + for(const auto& vx : *vxCont){ + if(vx->vertexType()==VxType::PriVtx || vx->vertexType()==VxType::PileUp) { + MissingET *met_vx = metTerm; + if(!firstVx) { + met_vx = new MissingET(0. ,0. ,0. ); + metCont->push_back(met_vx); + met_vx->setSource(metTerm->source()); + MissingETComposition::add(metMap, met_vx); + } + met_vx->setName(basename+std::to_string(vx->index())); + ATH_MSG_VERBOSE("Building " << met_vx->name()); + + ATH_MSG_VERBOSE("Number of tracks associated to vertex " << vx->index() << ": "<< (trktovxmap[vx]).size()); + + ATH_CHECK( buildTrackMET(metMap,metTerm,vx,selElectrons,selMuons,trktovxmap[vx]) ); + firstVx = false; + } + } + } else { + ATH_CHECK( buildTrackMET(metMap,metTerm,pv,selElectrons,selMuons,softTracks) ); + } + + return StatusCode::SUCCESS; + } + + StatusCode METTrackFilterTool::buildTrackMET(xAOD::MissingETComponentMap* const metMap, + xAOD::MissingET* const metTerm, + const xAOD::Vertex* const pv, + const std::vector<const xAOD::Electron*>& selElectrons, + const std::vector<const xAOD::Muon*>& selMuons, + const std::vector<const xAOD::TrackParticle*>& softTracks) const { vector<const IParticle*> dummyList; + const MissingETComponent* metComp = MissingETComposition::getComponent(metMap,metTerm); + if(!metComp) { + ATH_MSG_WARNING("Failed to find MissingETComponent for MET term " << metTerm->name()); + return StatusCode::FAILURE; + } // Loop over the tracks and select only good ones - for( vector<const IParticle*>::const_iterator iPar=softTrackList.begin(); - iPar!=softTrackList.end(); ++iPar ) { - MissingETBase::Types::weight_t trackWeight = (*citer)->weight(*iPar); - const TrackParticle* trk = dynamic_cast<const TrackParticle*>(*iPar); - ATH_MSG_VERBOSE("Filter track with pt " << trk->pt()); + for( const auto& trk : softTracks ) { + MissingETBase::Types::weight_t trackWeight = metComp->weight(trk); // Could/should use common implementation of addToMET here -- derive builder and refiner from a common base tool? bool passFilters = true; - if(m_trk_doPVsel && !isPVTrack(trk,(*m_pv_cont)[0])) passFilters = false; - if(m_trk_doEoverPsel && !isGoodEoverP(trk,softTrackList,cl_cont)) passFilters = false; - if(passFilters) { - ATH_MSG_VERBOSE("Add to MET."); - metTerm->add(trk->pt()*cos(trk->phi())*trackWeight.wpx(), - trk->pt()*sin(trk->phi())*trackWeight.wpy(), - trk->pt()*trackWeight.wet()); - MissingETComposition::insert(metMap,metTerm,*iPar,dummyList,trackWeight); + // if(m_trk_doPVsel && !isPVTrack(trk,(*vxCont)[0])) passFilters = false; + // if(m_trk_doEoverPsel && !isGoodEoverP(trk,softTracks,cl_cont)) passFilters = false; + if(m_trk_doPVsel) { + if(!(m_trkseltool->accept( *trk, pv ))) passFilters=false; + } else { + if(!(m_trkseltool->accept( trk ))) passFilters=false; + } + + bool isMuon=false; + bool isElectron=false; + size_t el_index=-1; + + if(m_doLepRecovery) { + isMuon=isMuTrack(*trk,selMuons); + isElectron=isElTrack(*trk,selElectrons, el_index); + } + + bool isLepton=(isMuon||isElectron); + + if(passFilters || (m_doLepRecovery && isLepton)) { + if(!passFilters && isElectron && m_doLepRecovery) { + //electron track fails, replace with electron pt + const Electron* el = selElectrons[el_index]; + + metTerm->add(el->pt()*cos(trk->phi())*trackWeight.wpx(), + el->pt()*sin(trk->phi())*trackWeight.wpy(), + el->pt()*trackWeight.wet()); + MissingETComposition::insert(metMap,metTerm,el,dummyList,trackWeight); + } else { + ATH_MSG_VERBOSE("Add track with pt " << trk->pt() <<" to MET."); + metTerm->add(trk->pt()*cos(trk->phi())*trackWeight.wpx(), + trk->pt()*sin(trk->phi())*trackWeight.wpy(), + trk->pt()*trackWeight.wet()); + MissingETComposition::insert(metMap,metTerm,trk,dummyList,trackWeight); + } } } return StatusCode::SUCCESS; } + bool METTrackFilterTool::isElTrack(const xAOD::TrackParticle &trk, const std::vector<const xAOD::Electron*>& electrons, size_t &el_index) const + { + for(unsigned int eli=0; eli<electrons.size(); ++eli) { + const xAOD::Electron *el=electrons.at(eli); + if(&trk==xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(el->trackParticle())) { + el_index=eli; + return true; + } + } + return false; + } + + bool METTrackFilterTool::isMuTrack(const xAOD::TrackParticle &trk, const std::vector<const xAOD::Muon*>& muons) const + { + for(unsigned mui=0;mui<muons.size();mui++) { + // if(((muon_list.at(mui))->trackParticle(xAOD::Muon::InnerDetectorTrackParticle))->pt()==trk->pt()) + if(((muons.at(mui))->trackParticle(xAOD::Muon::InnerDetectorTrackParticle))==&trk) { + return true; + } + } + return false; + } + + void METTrackFilterTool::selectElectrons(const xAOD::ElectronContainer &elCont, std::vector<const xAOD::Electron*>& electrons) const + { + for(unsigned int eli=0; eli< elCont.size(); eli++) { + const xAOD::Electron *el=elCont.at(eli); + if( (el)->author()&0x1 //electron author + && (el)->pt()>10000 // electron pt + && fabs(el->eta())<2.47 // electron eta + ) { + if(!((fabs((el)->eta())>1.37) && (fabs((el)->eta())<1.52) )) { + // crack region + electrons.push_back(el); + } + } + } + } + + + void METTrackFilterTool::selectMuons(const xAOD::MuonContainer &muCont, std::vector<const xAOD::Muon*>& muons) const + { + for(unsigned int mui=0; mui<muCont.size();mui++) { + const xAOD::Muon *mu=muCont.at(mui); + if( (mu->muonType()==xAOD::Muon::Combined) + && (mu->pt()>6000.) + && fabs(mu->eta())<2.5 + ) { + muons.push_back(mu); + } + } + } + + /////////////////////////////////////////////////////////////////// // Const methods: /////////////////////////////////////////////////////////////////// diff --git a/Reconstruction/MET/METReconstruction/cmt/requirements b/Reconstruction/MET/METReconstruction/cmt/requirements index 3c47bb5b35747748a63a482838d33785fdd90e15..16c344cb2a36b64daeefa63cdaf3ebd0a5cbed3c 100644 --- a/Reconstruction/MET/METReconstruction/cmt/requirements +++ b/Reconstruction/MET/METReconstruction/cmt/requirements @@ -17,14 +17,17 @@ use METRecoInterface METRecoInterface-* Reconstruction/MET ## Public EDM usage use xAODMissingET xAODMissingET-* Event/xAOD -use xAODEgamma xAODEgamma-* Event/xAOD use xAODCaloEvent xAODCaloEvent-* Event/xAOD use xAODTracking xAODTracking-* Event/xAOD use xAODTruth xAODTruth-* Event/xAOD use xAODJet xAODJet-* Event/xAOD +use xAODEgamma xAODEgamma-* Event/xAOD +use xAODMuon xAODMuon-* Event/xAOD use xAODPFlow xAODPFlow-* Event/xAOD use PFlowUtils PFlowUtils-* Reconstruction/PFlow -use CaloEvent CaloEvent-* Calorimeter + +use InDetTrackSelectionTool InDetTrackSelectionTool-* InnerDetector/InDetRecTools +use TrackVertexAssociationTool TrackVertexAssociationTool-* InnerDetector/InDetRecTools ## ROOT for timing use AtlasROOT AtlasROOT-* External @@ -34,9 +37,10 @@ private use AthenaBaseComps AthenaBaseComps-* Control ## EDM -use xAODMuon xAODMuon-* Event/xAOD +use AthContainers AthContainers-* Control use xAODTau xAODTau-* Event/xAOD -#use xAODEventInfo xAODEventInfo-* Event/xAOD +use xAODEventInfo xAODEventInfo-* Event/xAOD +use CaloEvent CaloEvent-* Calorimeter ## @@ -45,8 +49,13 @@ use EventPrimitives EventPrimitives-* Event end_private +include_dirs $(METReconstruction_root)/src + branches METReconstruction src src/components doc python share Root +# Apply the cmake-specific command to access the private headers +apply_pattern cmake_add_command command="include_directories(src)" + ## default is to make component library library METReconstruction *.cxx ../Root/*.cxx -s=components *.cxx @@ -57,3 +66,6 @@ apply_pattern declare_python_modules files="../python/*.py" private macro DOXYGEN_INPUT "" Doxygen "../src ../Root ../$(package) ../doc ../share ../python ../cmt/fragments" end_private + +use AtlasReflex AtlasReflex-* External -no-auto-imports +apply_pattern lcgdict dict=METReconstruction selectionfile=selection.xml headerfiles="../METReconstruction/METReconstructionDict.h" diff --git a/Reconstruction/MET/METReconstruction/python/METAssocConfig.py b/Reconstruction/MET/METReconstruction/python/METAssocConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..0b2fdd5c442e8682d86c60d11637c3da10fbf04d --- /dev/null +++ b/Reconstruction/MET/METReconstruction/python/METAssocConfig.py @@ -0,0 +1,165 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from AthenaCommon import CfgMgr + +################################################################################# +# Define some default values + +clusterSigStates = { + 'EMScale':0, + 'LocHad':1 +} + +defaultInputKey = { + 'Ele' :'Electrons', + 'Gamma' :'Photons', + 'Tau' :'TauJets', + 'LCJet' :'AntiKt4LCTopoJets', + 'EMJet' :'AntiKt4EMTopoJets', + 'PFlowJet' :'AntiKt4EMPFlowJets', + 'Muon' :'Muons', + 'Soft' :'', + 'ClusColl' :'CaloCalTopoClusters', + 'TrkColl' :'InDetTrackParticles', + 'PrimVxColl':'PrimaryVertices', + 'Truth' :'TruthParticles', + } + +# # old naming scheme +# defaultInputKey = { +# 'Ele' :'ElectronCollection', +# 'Gamma' :'PhotonCollection', +# 'Tau' :'TauRecContainer', +# 'LCJet' :'AntiKt4LCTopoJets', +# 'EMJet' :'AntiKt4EMTopoJets', +# 'PFlowJet' :'AntiKt4EMPFlowJets', +# 'Muon' :'Muons', +# 'Soft' :'', +# 'ClusColl' :'CaloCalTopoCluster', +# 'TrkColl' :'InDetTrackParticles', +# 'PrimVxColl':'PrimaryVertices', +# 'Truth' :'TruthParticle', +# } + +prefix = 'METAssocConfig: ' + +################################################################################# +# Configuration of builders + +class AssocConfig: + def __init__(self,objType='',inputKey=''): + self.objType = objType + self.inputKey = inputKey + +def getAssociator(config,suffix,doPFlow): + tool = None + + from AthenaCommon.AppMgr import ToolSvc + # Construct tool and set defaults for case-specific configuration + if config.objType == 'Ele': + tool = CfgMgr.met__METElectronAssociator('MET_ElectronAssociator_'+suffix) + if config.objType == 'Gamma': + tool = CfgMgr.met__METPhotonAssociator('MET_PhotonAssociator_'+suffix) + if config.objType == 'Tau': + tool = CfgMgr.met__METTauAssociator('MET_TauAssociator_'+suffix) + if config.objType == 'LCJet': + tool = CfgMgr.met__METJetAssocTool('MET_LCJetAssocTool_'+suffix) + if config.objType == 'EMJet': + tool = CfgMgr.met__METJetAssocTool('MET_EMJetAssocTool_'+suffix) + if config.objType == 'PFlowJet': + tool = CfgMgr.met__METJetAssocTool('MET_PFlowJetAssocTool_'+suffix) + if config.objType == 'Muon': + tool = CfgMgr.met__METMuonAssociator('MET_MuonAssociator_'+suffix) + if config.objType == 'Soft': + tool = CfgMgr.met__METSoftAssociator('MET_SoftAssociator_'+suffix) + if doPFlow: + pfotool = CfgMgr.CP__RetrievePFOTool('MET_PFOTool_'+suffix) + ToolSvc += pfotool + tool.PFOTool = pfotool + tool.PFlow=True + # set input/output key names + if config.inputKey == '': + tool.InputCollection = defaultInputKey[config.objType] + config.inputKey = tool.InputCollection + tool.ClusColl = defaultInputKey['ClusColl'] + tool.TrkColl = defaultInputKey['TrkColl'] + else: + tool.InputCollection = config.inputKey + + trkseltool=CfgMgr.InDet__InDetTrackSelectionTool("IDTrkSel_METAssoc", + CutLevel="TightPrimary", + maxZ0SinTheta=1.5, + maxD0overSigmaD0=3) + ToolSvc += trkseltool + tool.TrackSelectorTool = trkseltool + ToolSvc += tool + return tool + +################################################################################# +# Top level MET configuration + +class METAssocConfig: + def outputCollections(self): + return 'MET_Core_'+self.suffix,'MET_Reference_'+self.suffix + # + def outputMap(self): + return 'METAssoc_'+self.suffix + # + def setupAssociators(self,buildconfigs): + print prefix, 'Setting up associators for MET config '+self.suffix + for config in buildconfigs: + if config.objType in self.associators: + print prefix, 'Config '+self.suffix+' already contains a associator of type '+config.objType + raise LookupError + else: + associator = getAssociator(config,self.suffix,self.doPFlow) + self.associators[config.objType] = associator + self.assoclist.append(associator) + print prefix, ' Added '+config.objType+' tool named '+associator.name() + # + def __init__(self,suffix,buildconfigs=[], + doPFlow=False): + print prefix, 'Creating MET config \''+suffix+'\'' + self.suffix = suffix + self.doPFlow = doPFlow + self.associators = {} + self.assoclist = [] # need an ordered list + # + self.setupAssociators(buildconfigs) + +# Set up a top-level tool with mostly defaults +def getMETAssocTool(topconfig): + assocTool = CfgMgr.met__METAssociationTool('MET_AssociationTool_'+topconfig.suffix, + METAssociators = topconfig.assoclist, + METSuffix = topconfig.suffix) + return assocTool + +# Allow user to configure reco tools directly or get more default configurations +def getMETAssocAlg(algName='METAssociation',configs={},tools=[]): + + assocTools = [] + assocTools += tools + + from METReconstruction.METRecoFlags import metFlags + if configs=={} and tools==[]: + print prefix, 'Taking configurations from METRecoFlags' + configs = metFlags.METAssocConfigs() + print configs + for key,conf in configs.iteritems(): + print prefix, 'Generate METAssocTool for MET_'+key + assoctool = getMETAssocTool(conf) + assocTools.append(assoctool) + metFlags.METAssocTools()[key] = assoctool + + from AthenaCommon.AppMgr import ToolSvc + for tool in assocTools: + ToolSvc += tool + print prefix, 'Added METAssocTool \''+tool.name()+'\' to alg '+algName + + assocAlg = CfgMgr.met__METRecoAlg(name=algName, + RecoTools=assocTools) +# assocAlg.OutputLevel=DEBUG + return assocAlg + +# Allow user to configure reco tools directly or get more default configurations +#def getMETMakerAlg(algName='METMaker'): diff --git a/Reconstruction/MET/METReconstruction/python/METConfig_Associator.py b/Reconstruction/MET/METReconstruction/python/METConfig_Associator.py new file mode 100644 index 0000000000000000000000000000000000000000..005b55cb67118a5c7a12c143b3260764b1e3a4c1 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/python/METConfig_Associator.py @@ -0,0 +1,62 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from METReconstruction.METRecoFlags import metFlags +from METReconstruction.METAssocConfig import AssocConfig, METAssocConfig + +from RecExConfig.RecFlags import rec +doInDet = rec.doInDet() + +############################################################################ +# AntiKt4LCTopo +JetType = 'LCJet' + +associators = [AssocConfig(JetType), + AssocConfig('Muon'), + AssocConfig('Ele'), + AssocConfig('Gamma'), + AssocConfig('Tau'), + AssocConfig('Soft')] +cfg_akt4lc = METAssocConfig('AntiKt4LCTopo', + associators, + doPFlow=False + ) + +metFlags.METAssocConfigs()[cfg_akt4lc.suffix] = cfg_akt4lc +metFlags.METAssocOutputList().append(cfg_akt4lc.suffix) + +############################################################################ +# AntiKt4EMTopo +JetType = 'EMJet' + +associators = [AssocConfig(JetType), + AssocConfig('Muon'), + AssocConfig('Ele'), + AssocConfig('Gamma'), + AssocConfig('Tau'), + AssocConfig('Soft')] +cfg_akt4em = METAssocConfig('AntiKt4EMTopo', + associators, + doPFlow=False + ) + +metFlags.METAssocConfigs()[cfg_akt4em.suffix] = cfg_akt4em +metFlags.METAssocOutputList().append(cfg_akt4em.suffix) + +############################################################################ +# PFlow +if doInDet and metFlags.DoPFlow(): + JetType = 'PFlowJet' + + associators = [AssocConfig(JetType), + AssocConfig('Muon'), + AssocConfig('Ele'), + AssocConfig('Gamma'), + AssocConfig('Tau'), + AssocConfig('Soft')] + cfg_akt4pf = METAssocConfig('AntiKt4EMPFlow', + associators, + doPFlow=True + ) + + metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf + metFlags.METAssocOutputList().append(cfg_akt4pf.suffix) diff --git a/Reconstruction/MET/METReconstruction/python/METConfig_Calo.py b/Reconstruction/MET/METReconstruction/python/METConfig_Calo.py new file mode 100644 index 0000000000000000000000000000000000000000..360d2b147cea7f94f33a74349b5810d745ad3c2c --- /dev/null +++ b/Reconstruction/MET/METReconstruction/python/METConfig_Calo.py @@ -0,0 +1,41 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from METReconstruction.METRecoFlags import metFlags +from METReconstruction.METRecoConfig import BuildConfig, RefConfig, METConfig,clusterSigStates +#from METReconstruction.METRecoConfig_Associator import BuildConfig, RefConfig, METConfig,clusterSigStates + +############################################################################ +# EMTopo + +cfg_emt = METConfig('EMTopo',[BuildConfig('SoftClus','EMTopo')], + doRegions=True + ) +cfg_emt.builders['SoftClus'].SignalState = clusterSigStates['EMScale'] + +metFlags.METConfigs()[cfg_emt.suffix] = cfg_emt +metFlags.METOutputList().append(cfg_emt.suffix) +metFlags.METOutputList().append(cfg_emt.suffix+"Regions") + +############################################################################ +# LocHadTopo + +cfg_lht = METConfig('LocHadTopo',[BuildConfig('SoftClus','LocHadTopo')], + doRegions=True + ) +cfg_lht.builders['SoftClus'].SignalState = clusterSigStates['LocHad'] + +metFlags.METConfigs()[cfg_lht.suffix] = cfg_lht +metFlags.METOutputList().append(cfg_lht.suffix) +metFlags.METOutputList().append(cfg_lht.suffix+"Regions") + + +############################################################################ +# Calo regions + +cfg_calo = METConfig('Calo', + [BuildConfig('CaloReg')], + doCells=True + ) + +metFlags.METConfigs()[cfg_calo.suffix] = cfg_calo +metFlags.METOutputList().append(cfg_calo.suffix) diff --git a/Reconstruction/MET/METReconstruction/python/METConfig_RefFinal.py b/Reconstruction/MET/METReconstruction/python/METConfig_RefFinal.py index 7760d5c569a9a2fd1d3d4564bf6dc50666c059fe..2b698f2ee8b5ec2e58312040f12a22f24df6a953 100644 --- a/Reconstruction/MET/METReconstruction/python/METConfig_RefFinal.py +++ b/Reconstruction/MET/METReconstruction/python/METConfig_RefFinal.py @@ -5,6 +5,8 @@ from METReconstruction.METRecoConfig import BuildConfig, RefConfig, METConfig,cl from RecExConfig.RecFlags import rec doInDet = rec.doInDet() +from JetRec.JetRecFlags import jetFlags +jetsUseTracks = jetFlags.useTracks() ############################################################################ # MET_RefFinal @@ -16,13 +18,12 @@ rf_builders = [BuildConfig('Ele'), BuildConfig('Muon'), BuildConfig('SoftClus'), BuildConfig('SoftTrk')] -rf_refiners = [RefConfig('JetFilter','RefJet_JVFCut'), - RefConfig('TrackFilter','PVSoftTrk')] +rf_refiners = [RefConfig('TrackFilter','PVSoftTrk')] cfg_mrf = METConfig('RefFinal', rf_builders, rf_refiners, doSum=True, - doTracks=doInDet, + doTracks=(doInDet and jetsUseTracks), doRegions=True ) @@ -62,38 +63,7 @@ cfg_mrf.builders['Muon'].MinNprecision = 3 # cfg_mrf.builders['SoftClus'].VetoNegEClus = True cfg_mrf.builders['SoftClus'].SignalState = clusterSigStates['LocHad'] -# -cfg_mrf.refiners['JetFilter'].DoJVFCut = True -cfg_mrf.refiners['JetFilter'].MinAbsJVF = 0.25 -cfg_mrf.refiners['JetFilter'].MaxPtJVF = 50e3 # only apply for pt<50 -cfg_mrf.refiners['JetFilter'].MaxEtaJVF = 2.4 # only apply to central jets -# -cfg_mrf.refiners['TrackFilter'].DoPVSel = True -cfg_mrf.refiners['TrackFilter'].TrackD0Max = 1.5 -cfg_mrf.refiners['TrackFilter'].TrackZ0Max = 1.5 metFlags.METConfigs()[cfg_mrf.suffix] = cfg_mrf metFlags.METOutputList().append(cfg_mrf.suffix) metFlags.METOutputList().append(cfg_mrf.suffix+"Regions") - -############################################################################ -# LocHadTopo - -cfg_lht = METConfig('LocHadTopo',[BuildConfig('SoftClus','LocHadTopo')], - doRegions=True - ) -cfg_lht.builders['SoftClus'].SignalState = clusterSigStates['LocHad'] - -metFlags.METConfigs()[cfg_lht.suffix] = cfg_lht -metFlags.METOutputList().append(cfg_lht.suffix) -metFlags.METOutputList().append(cfg_lht.suffix+"Regions") - -############################################################################ -# Nominal TrackMET - -cfg_trk = METConfig('Track',[BuildConfig('SoftTrk','Track')],[RefConfig('TrackFilter','PVTrack')], - doTracks=doInDet) - -metFlags.METConfigs()[cfg_trk.suffix] = cfg_trk -metFlags.METOutputList().append(cfg_trk.suffix) -metFlags.METOutputList().append(cfg_trk.suffix+"Regions") diff --git a/Reconstruction/MET/METReconstruction/python/METConfig_Track.py b/Reconstruction/MET/METReconstruction/python/METConfig_Track.py new file mode 100644 index 0000000000000000000000000000000000000000..51a6d04c6681ffa2c54af7f9db7f7cee19295fe8 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/python/METConfig_Track.py @@ -0,0 +1,19 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +from METReconstruction.METRecoFlags import metFlags +from METReconstruction.METRecoConfig import BuildConfig, RefConfig, METConfig,clusterSigStates + +from RecExConfig.RecFlags import rec +doInDet = rec.doInDet() + +cfg_trk = METConfig('Track',[BuildConfig('SoftTrk','Track')], + [RefConfig('TrackFilter','PVTrack')], + doTracks=doInDet) + +cfg_trk.refiners['TrackFilter'].DoLepRecovery=True +cfg_trk.refiners['TrackFilter'].DoVxSep=True +# Old input names +#cfg_trk.refiners['TrackFilter'].InputClusterKey="CaloCalTopoCluster" +#cfg_trk.refiners['TrackFilter'].InputElectronKey="ElectronCollection" +metFlags.METConfigs()[cfg_trk.suffix] = cfg_trk +metFlags.METOutputList().append(cfg_trk.suffix) diff --git a/Reconstruction/MET/METReconstruction/python/METRecoConfig.py b/Reconstruction/MET/METReconstruction/python/METRecoConfig.py index 30fadf61dd44bf94d0946e83f87a3caf28976007..54ada5057f5e71ee7c99933977a16276368ea848 100644 --- a/Reconstruction/MET/METReconstruction/python/METRecoConfig.py +++ b/Reconstruction/MET/METReconstruction/python/METRecoConfig.py @@ -21,18 +21,33 @@ defaultAuthor = { } defaultInputKey = { - 'Ele' :'ElectronCollection', - 'Gamma' :'PhotonCollection', - 'Tau' :'TauRecContainer', - 'Jet' :'AntiKt4LCTopoJets', - 'Muon' :'Muons', - 'SoftTrk' :'InDetTrackParticles', - 'SoftClus' :'CaloCalTopoCluster', - 'SoftPFlow':'neutralJetETMissPFO_eflowRec', - 'PrimaryVx':'PrimaryVertices', - 'Truth' :'TruthParticle', - 'Calo' :'AllCalo' - } + 'Ele' :'Electrons', + 'Gamma' :'Photons', + 'Tau' :'TauJets', + 'Jet' :'AntiKt4LCTopoJets', + 'Muon' :'Muons', + 'SoftTrk' :'InDetTrackParticles', + 'SoftClus' :'CaloCalTopoClusters', + 'SoftPFlow':'JetETMissNeutralParticleFlowObjects', + 'PrimaryVx':'PrimaryVertices', + 'Truth' :'TruthParticles', + 'Calo' :'AllCalo' + } + +# # old naming scheme +# defaultInputKey = { +# 'Ele' :'ElectronCollection', +# 'Gamma' :'PhotonCollection', +# 'Tau' :'TauRecContainer', +# 'Jet' :'AntiKt4LCTopoJets', +# 'Muon' :'Muons', +# 'SoftTrk' :'InDetTrackParticles', +# 'SoftClus' :'CaloCalTopoCluster', +# 'SoftPFlow':'neutralJetETMissPFO_eflowRec', +# 'PrimaryVx':'PrimaryVertices', +# 'Truth' :'TruthParticle', +# 'Calo' :'AllCalo' +# } defaultOutputKey = { 'Ele' :'RefEle', @@ -108,6 +123,7 @@ def getBuilder(config,suffix,doTracks,doCells): tool.UseCells = False config.inputKey = defaultInputKey['SoftClus'] config.outputKey = config.objType + # set input/output key names if config.inputKey == '': tool.InputCollection = defaultInputKey[config.objType] @@ -134,15 +150,27 @@ class RefConfig: def getRefiner(config,suffix): tool = None + + from AthenaCommon.AppMgr import ToolSvc if config.type == 'TrackFilter': tool = CfgMgr.met__METTrackFilterTool('MET_TrackFilterTool_'+suffix) tool.InputPVKey = defaultInputKey['PrimaryVx'] + trkseltool=CfgMgr.InDet__InDetTrackSelectionTool("IDTrkSel_MET", + CutLevel="TightPrimary", + maxZ0SinTheta=1.5, + maxD0overSigmaD0=3) + ToolSvc += trkseltool + # + trkvxtool=CfgMgr.CP__TightTrackVertexAssociationTool("TightTrackVertexAssociationTool", dzSinTheta_cut=1.5, doPV=False) + ToolSvc += trkvxtool + # + tool.TrackSelectorTool=trkseltool + tool.TrackVxAssocTool=trkvxtool if config.type == 'JetFilter': tool = CfgMgr.met__METJetFilterTool('MET_JetFilterTool_'+suffix) if config.type == 'MuonEloss': tool = CfgMgr.met__METMuonElossTool('MET_MuonElossTool_'+suffix) tool.MissingETKey = config.outputKey - from AthenaCommon.AppMgr import ToolSvc ToolSvc += tool return tool diff --git a/Reconstruction/MET/METReconstruction/python/METRecoFlags.py b/Reconstruction/MET/METReconstruction/python/METRecoFlags.py index 80ffb220f2018fa7a25bc03c6007861dbd2381df..f79b59f0d6b1d1b0d21ee53cad00d2b32a3a5590 100644 --- a/Reconstruction/MET/METReconstruction/python/METRecoFlags.py +++ b/Reconstruction/MET/METReconstruction/python/METRecoFlags.py @@ -11,6 +11,11 @@ class DoRegions(JobProperty): allowedTypes = ['bool'] StoredValue = False +class DoPFlow(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = True + class METConfigs(JobProperty): statusOn = True allowedTypes = ['dict'] @@ -26,11 +31,30 @@ class METOutputList(JobProperty): allowedTypes = ['list'] StoredValue = [] +class METAssocConfigs(JobProperty): + statusOn = True + allowedTypes = ['dict'] + StoredValue = {} + +class METAssocTools(JobProperty): + statusOn = True + allowedTypes = ['dict'] + StoredValue = {} + +class METAssocOutputList(JobProperty): + statusOn = True + allowedTypes = ['list'] + StoredValue = [] + jobproperties.add_Container(METRecoFlags) jobproperties.METRecoFlags.add_JobProperty(DoRegions) +jobproperties.METRecoFlags.add_JobProperty(DoPFlow) jobproperties.METRecoFlags.add_JobProperty(METConfigs) jobproperties.METRecoFlags.add_JobProperty(METOutputList) jobproperties.METRecoFlags.add_JobProperty(METRecoTools) +jobproperties.METRecoFlags.add_JobProperty(METAssocConfigs) +jobproperties.METRecoFlags.add_JobProperty(METAssocOutputList) +jobproperties.METRecoFlags.add_JobProperty(METAssocTools) metFlags = jobproperties.METRecoFlags diff --git a/Reconstruction/MET/METReconstruction/share/BuildAssociation.py b/Reconstruction/MET/METReconstruction/share/BuildAssociation.py new file mode 100644 index 0000000000000000000000000000000000000000..35f8d1e30a8774365499eecdd2b39c6c9b6453ed --- /dev/null +++ b/Reconstruction/MET/METReconstruction/share/BuildAssociation.py @@ -0,0 +1,155 @@ +import AthenaPoolCnvSvc.ReadAthenaPool +from AthenaCommon.AthenaCommonFlags import athenaCommonFlags +from AthenaCommon.AppMgr import ServiceMgr +from AthenaCommon import CfgMgr + +from glob import glob +#filelist = ['../../athxaod/files/mc14_8TeV.147806.PowhegPythia8_AU2CT10_Zee.merge.AOD.e1169_s1896_s1912_r5591_r5625_tid01512387_00/AOD.01512387._001662.pool.root.1'] +filelist = ["/afs/cern.ch/user/b/boliu/workdir/dataset/mc14_8TeV.117050.PowhegPythia_P2011C_ttbar.merge.AOD.e1727_s1933_s1911_r5591_r5625_tid01507243_00/AOD.01507243._011158.pool.root.1"] + +#filelist = ['../../athxaod/newfiler.root'] +#filelist = ['xAOD.sklim.pool.root'] +#filelist = ['/afs/cern.ch/user/s/schaffer/public/public1/work-19.x.EventSizes/build/run/devval_0_0809_100evts/myAOD.pool.root'] +#filelist = ['/afs/cern.ch/user/c/christos/public/AOD_forRob.pool.root'] +ServiceMgr.EventSelector.InputCollections = filelist + +verbose = False + +###################################################################### +# Rerun MET reco to fix track-vertex associations +from METReconstruction.METRecoFlags import metFlags +from METReconstruction.METRecoConfig import BuildConfig, RefConfig, METConfig, getMETRecoAlg + +rf_builders = [BuildConfig('Ele'), + BuildConfig('Gamma'), + BuildConfig('Tau'), + BuildConfig('Jet'), + BuildConfig('Muon'), + BuildConfig('SoftClus'), + BuildConfig('SoftTrk')] +rf_refiners = [RefConfig('TrackFilter','PVSoftTrk'), + RefConfig('JetFilter','RefJet_JVFCut')] +cfg_mrf = METConfig('RefFinalFix', + rf_builders, + rf_refiners, + doSum=True, + doTracks=True + ) +cfg_mrf.builders['Tau'].MinWet=1. +metconfigs = { + 'RefFinalFix':cfg_mrf + } +metAlg = getMETRecoAlg('METReconstruction',metconfigs) + +# The tools are accessible via the configurations in metFlags +from AthenaCommon.AppMgr import ToolSvc +metMaker = CfgMgr.met__METMaker('METMaker', + JetPtCut=0e3, + DoJetJvfCut=False, + ); +ToolSvc += metMaker + +makerAlg = CfgMgr.met__METMakerAlg('METMakerAlg', + METCoreName='MET_Core', + METName='MET_RefAssoc', + Maker=metMaker) + +## Set up default configurations +from METUtilities.METUtilConfig import getMETUtilAlg,METUtilConfig,getMETRebuilder +csttool = getMETRebuilder(METUtilConfig('RefFinalFix',{'Soft':'SoftClus'}, {},'RefCST')) +tsttool = getMETRebuilder(METUtilConfig('RefFinalFix',{'Soft':'PVSoftTrk'},{},'RefTST')) +utilAlg = getMETUtilAlg('METUtilAlg') +csttool.CalibJetPtCut=0e3 +tsttool.CalibJetPtCut=0e3 +csttool.DoJetJVFCut=False +tsttool.DoJetJVFCut=False +ToolSvc += csttool +ToolSvc += tsttool +utilAlg.Rebuilders = [csttool,tsttool] + + +pfotool = CfgMgr.CP__RetrievePFOTool('MET_PFOTool') +from AthenaCommon.AppMgr import ToolSvc +ToolSvc += pfotool + +trkseltool=CfgMgr.InDet__InDetTrackSelectionTool(CutLevel="TightPrimary") +ToolSvc += trkseltool + + + +assocAlg = CfgMgr.met__METAssocAlg('METAssocAlg',PFOTool=pfotool, TrackSelectorTool=trkseltool) + +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() +from GaudiSequencer.PyComps import PyEvtFilter +filterseq = CfgMgr.AthSequencer('AthFilterSeq') +#the following lines are examples, pick one... +#filterseq += PyEvtFilter(evt_list=[1980130,287866,1706011,2226793,146377,146604,1904442,1297008,1298451,1072953]) #will execute main sequence only for these eventnumbers +#filterseq += PyEvtFilter(evt_list=[1108077]) +filterseq += metAlg +filterseq += assocAlg +filterseq += utilAlg +filterseq += makerAlg + +if verbose: + metAlg.OutputLevel=VERBOSE + assocAlg.OutputLevel=VERBOSE + makerAlg.OutputLevel=VERBOSE + metMaker.OutputLevel=VERBOSE + cfg_mrf.builders['Ele'].OutputLevel=VERBOSE + cfg_mrf.builders['Gamma'].OutputLevel=VERBOSE + cfg_mrf.builders['Tau'].OutputLevel=VERBOSE + cfg_mrf.builders['Muon'].OutputLevel=VERBOSE + cfg_mrf.builders['Jet'].OutputLevel=VERBOSE + cfg_mrf.builders['SoftTrk'].OutputLevel=VERBOSE + cfg_mrf.refiners['TrackFilter'].OutputLevel=VERBOSE + +#from Valkyrie.JobOptCfg import ValgrindSvc +#svcMgr += ValgrindSvc( OutputLevel = DEBUG, +# ProfiledAlgs = ['METAssocAlg','METAssocAlg'], +# ProfiledIntervals = ['METAssocAlg.execute']) + +from PerfMonComps.PerfMonFlags import jobproperties as pmon_properties +pmon_properties.PerfMonFlags.doSemiDetailedMonitoring=True + +from OutputStreamAthenaPool.MultipleStreamManager import MSMgr +xaodStream = MSMgr.NewPoolRootStream( 'StreamAOD', 'xAOD.METAssoc.testassoc.pool.root' ) +xaodStream.AddItem('xAOD::MissingETAssociationMap_v1#METAssoc_Akt4LC') +xaodStream.AddItem('xAOD::MissingETAuxAssociationMap_v1#METAssoc_Akt4LCAux.') +xaodStream.AddItem('xAOD::EventInfo_v1#EventInfo') +xaodStream.AddItem('xAOD::EventAuxInfo_v1#EventInfoAux.') +#xaodStream.AddItem('xAOD::ElectronContainer#ElectronCollection') +#xaodStream.AddItem('xAOD::ElectronAuxContainer#ElectronCollectionAux.') +#xaodStream.AddItem('xAOD::PhotonContainer#PhotonCollection') +#xaodStream.AddItem('xAOD::PhotonAuxContainer#PhotonCollectionAux.') +#xaodStream.AddItem('xAOD::TauJetContainer_v1#TauRecContainer') +#xaodStream.AddItem('xAOD::TauJetAuxContainer_v1#TauRecContainerAux.') +#xaodStream.AddItem('xAOD::JetContainer_v1#AntiKt4LCTopoJets') +#xaodStream.AddItem('xAOD::JetAuxContainer_v1#AntiKt4LCTopoJetsAux.') +#xaodStream.AddItem('xAOD::MuonContainer_v1#Muons') +#xaodStream.AddItem('xAOD::MuonAuxContainer_v1#MuonsAux.') +#xaodStream.AddItem('xAOD::MissingETComponentMap_v1#METMap_RefFinalFix') +#xaodStream.AddItem('xAOD::MissingETAuxComponentMap_v1#METMap_RefFinalFixAux.') +#xaodStream.AddItem('xAOD::CaloClusterContainer_v1#egClusterCollection'); +#xaodStream.AddItem('xAOD::CaloClusterAuxContainer_v1#egClusterCollectionAux.'); +#xaodStream.AddItem('xAOD::CaloClusterContainer_v1#CaloCalTopoCluster'); +#xaodStream.AddItem('xAOD::CaloClusterAuxContainer_v1#CaloCalTopoClusterAux.'); +#xaodStream.AddItem('xAOD::TrackParticleContainer_v1#*') +#xaodStream.AddItem('xAOD::TrackParticleAuxContainer_v1#*') +#xaodStream.AddItem('xAOD::VertexContainer_v1#*') +#xaodStream.AddItem('xAOD::VertexAuxContainer_v1#*') +xaodStream.AddItem('xAOD::MissingETContainer_v1#MET_Core') +xaodStream.AddItem('xAOD::MissingETAuxContainer_v1#MET_CoreAux.') +xaodStream.AddItem('xAOD::MissingETContainer_v1#MET_RefAssoc') +xaodStream.AddItem('xAOD::MissingETAuxContainer_v1#MET_RefAssocAux.') +xaodStream.AddItem('xAOD::MissingETContainer_v1#MET_RefFinalFix') +xaodStream.AddItem('xAOD::MissingETAuxContainer_v1#MET_RefFinalFixAux.') +xaodStream.AddItem('xAOD::MissingETContainer_v1#MET_RefCST') +xaodStream.AddItem('xAOD::MissingETAuxContainer_v1#MET_RefCSTAux.') +xaodStream.AddItem('xAOD::MissingETContainer_v1#MET_RefTST') +xaodStream.AddItem('xAOD::MissingETAuxContainer_v1#MET_RefTSTAux.') +xaodStream.AcceptAlgs(['PyEvtFilter']) + +theApp.EvtMax = 100 +ServiceMgr.EventSelector.SkipEvents = 0 +#ServiceMgr.MessageSvc.defaultLimit = 9999 diff --git a/Reconstruction/MET/METReconstruction/share/METReconstructionOutputAODList_jobOptions.py b/Reconstruction/MET/METReconstruction/share/METReconstructionOutputAODList_jobOptions.py index 8e21bd9d447db23287f1390ef09c1e787a759270..da94662e50062a1d954039be396df2930c23c931 100644 --- a/Reconstruction/MET/METReconstruction/share/METReconstructionOutputAODList_jobOptions.py +++ b/Reconstruction/MET/METReconstruction/share/METReconstructionOutputAODList_jobOptions.py @@ -3,14 +3,26 @@ MissingETAODList = [] outputlist = [] from METReconstruction.METRecoFlags import metFlags if len(metFlags.METOutputList())==0: - outputlist = ['Truth','Track','LocHadTopo','RefFinal','Calo', - 'TruthRegions','TrackRegions','LocHadTopoRegions','RefFinalRegions'] + outputlist = ['Truth','EMTopo','LocHadTopo','Calo','Track', + 'TruthRegions','EMTopoRegions','LocHadTopoRegions'] else: outputlist = metFlags.METOutputList() for config in outputlist: - MissingETAODList.append( 'xAOD::MissingETContainer_v1#MET_'+config ) - MissingETAODList.append( 'xAOD::MissingETAuxContainer_v1#MET_'+config+'Aux.' ) - if not config == 'Calo': - MissingETAODList.append( 'xAOD::MissingETComponentMap_v1#METMap_'+config ) - MissingETAODList.append( 'xAOD::MissingETAuxComponentMap_v1#METMap_'+config+'Aux.' ) + MissingETAODList.append( 'xAOD::MissingETContainer#MET_'+config ) + MissingETAODList.append( 'xAOD::MissingETAuxContainer#MET_'+config+'Aux.' ) + if config == 'Truth': + MissingETAODList.append( 'xAOD::MissingETComponentMap#METMap_'+config ) + MissingETAODList.append( 'xAOD::MissingETAuxComponentMap#METMap_'+config+'Aux.' ) + +if len(metFlags.METAssocOutputList())==0: + assocoutput = ['AntiKt4LCTopo','AntiKt4EMTopo','AntiKt4EMPFlow'] +else: + assocoutput = metFlags.METAssocOutputList() +for config in assocoutput: + MissingETAODList.append( 'xAOD::MissingETAssociationMap#METAssoc_'+config ) + MissingETAODList.append( 'xAOD::MissingETAuxAssociationMap#METAssoc_'+config+'Aux.' ) + MissingETAODList.append( 'xAOD::MissingETContainer#MET_Core_'+config ) + MissingETAODList.append( 'xAOD::MissingETAuxContainer#MET_Core_'+config+'Aux.' ) + MissingETAODList.append( 'xAOD::MissingETContainer#MET_Reference_'+config ) + MissingETAODList.append( 'xAOD::MissingETAuxContainer#MET_Reference_'+config+'Aux.' ) diff --git a/Reconstruction/MET/METReconstruction/share/METReconstructionOutputESDList_jobOptions.py b/Reconstruction/MET/METReconstruction/share/METReconstructionOutputESDList_jobOptions.py index 588b400cb53e431d808d332c3805fbcca0aa9dd4..705a5034fc03eca71e6ff7ff5800c072e1beb2c0 100644 --- a/Reconstruction/MET/METReconstruction/share/METReconstructionOutputESDList_jobOptions.py +++ b/Reconstruction/MET/METReconstruction/share/METReconstructionOutputESDList_jobOptions.py @@ -3,14 +3,26 @@ MissingETESDList = [] outputlist = [] from METReconstruction.METRecoFlags import metFlags if len(metFlags.METOutputList())==0: - outputlist = ['Truth','Track','LocHadTopo','RefFinal','Calo', - 'TruthRegions','TrackRegions','LocHadTopoRegions','RefFinalRegions'] + outputlist = ['Truth','EMTopo','LocHadTopo','Calo','Track' + 'TruthRegions','EMTopoRegions','LocHadTopoRegions'] else: outputlist = metFlags.METOutputList() for config in outputlist: - MissingETESDList.append( 'xAOD::MissingETContainer_v1#MET_'+config ) - MissingETESDList.append( 'xAOD::MissingETAuxContainer_v1#MET_'+config+'Aux.' ) - if not config == 'Calo': - MissingETESDList.append( 'xAOD::MissingETComponentMap_v1#METMap_'+config ) - MissingETESDList.append( 'xAOD::MissingETAuxComponentMap_v1#METMap_'+config+'Aux.' ) + MissingETESDList.append( 'xAOD::MissingETContainer#MET_'+config ) + MissingETESDList.append( 'xAOD::MissingETAuxContainer#MET_'+config+'Aux.' ) + if config == 'Truth': + MissingETESDList.append( 'xAOD::MissingETComponentMap#METMap_'+config ) + MissingETESDList.append( 'xAOD::MissingETAuxComponentMap#METMap_'+config+'Aux.' ) + +if len(metFlags.METAssocOutputList())==0: + assocoutput = ['AntiKt4LCTopo','AntiKt4EMTopo','AntiKt4EMPFlow'] +else: + assocoutput = metFlags.METAssocOutputList() +for config in assocoutput: + MissingETESDList.append( 'xAOD::MissingETAssociationMap#METAssoc_'+config ) + MissingETESDList.append( 'xAOD::MissingETAuxAssociationMap#METAssoc_'+config+'Aux.' ) + MissingETESDList.append( 'xAOD::MissingETContainer#MET_Core_'+config ) + MissingETESDList.append( 'xAOD::MissingETAuxContainer#MET_Core_'+config+'Aux.' ) + MissingETESDList.append( 'xAOD::MissingETContainer#MET_Reference_'+config ) + MissingETESDList.append( 'xAOD::MissingETAuxContainer#MET_Reference_'+config+'Aux.' ) diff --git a/Reconstruction/MET/METReconstruction/share/METReconstruction_jobOptions.py b/Reconstruction/MET/METReconstruction/share/METReconstruction_jobOptions.py index f3c04ad4956e421b3254f8ecde0e6d3b1490ce8c..d81230e1c3f0e503b6985d2f8ada01d74c0819b4 100644 --- a/Reconstruction/MET/METReconstruction/share/METReconstruction_jobOptions.py +++ b/Reconstruction/MET/METReconstruction/share/METReconstruction_jobOptions.py @@ -1,16 +1,29 @@ from AthenaCommon.AlgSequence import AlgSequence topSequence = AlgSequence() -import METReconstruction.METConfig_RefFinal -import METReconstruction.METConfig_CaloReg -#import METReconstruction.METConfig_PFlow -from RecExConfig.RecFlags import rec -if rec.doTruth: +import METReconstruction.METConfig_Calo +import METReconstruction.METConfig_Track +if rec.doTruth(): import METReconstruction.METConfig_Truth from METReconstruction.METRecoFlags import metFlags from METReconstruction.METRecoConfig import getMETRecoAlg metAlg = getMETRecoAlg('METReconstruction') - topSequence += metAlg + +# Set up default configurations +import METReconstruction.METConfig_Associator +from METReconstruction.METAssocConfig import getMETAssocAlg + +# Get the configuration directly from METRecoFlags +# Can also provide a dict of configurations or list of RecoTools or both +assocAlg = getMETAssocAlg('METAssociation') +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() +topSequence += assocAlg + +from METUtilities.METMakerConfig import getMETMakerAlg +for key,conf in metFlags.METAssocConfigs().iteritems(): + makerAlg = getMETMakerAlg(conf.suffix) + topSequence += makerAlg diff --git a/Reconstruction/MET/METReconstruction/share/RunMETReco.py b/Reconstruction/MET/METReconstruction/share/RunMETReco.py index cd9592d09ad076861a0e5bcf1bdbe33b12fa495e..38c86951fb7cf4bbe62050a2ce91eb1b8d61f0ce 100644 --- a/Reconstruction/MET/METReconstruction/share/RunMETReco.py +++ b/Reconstruction/MET/METReconstruction/share/RunMETReco.py @@ -3,61 +3,54 @@ from AthenaCommon.AthenaCommonFlags import athenaCommonFlags from AthenaCommon.AppMgr import ServiceMgr from AthenaCommon import CfgMgr -filelist = ["AOD.nomet.pool.root"] +filelist = ["myAOD.pool.root"] +from glob import glob +#filelist = glob('/r03/atlas/khoo/Data_2014/DC14xAOD/mc14_8TeV.117050.PowhegPythia_P2011C_ttbar.merge.AOD.e1727_s1933_s1911_r5591_r5625/*') +#filelist = glob('/r03/atlas/khoo/Data_2014/DC14xAOD/mc14_13TeV.110401.PowhegPythia_P2012_ttbar_nonallhad.merge.AOD.e2928_s1982_s2008_r5787_r5853/*') ServiceMgr.EventSelector.InputCollections = filelist -# Set up default configurations -import METReconstruction.METConfig_RefFinal -import METReconstruction.METConfig_Truth -import METReconstruction.METConfig_CaloReg -#import METReconstruction.METConfig_PFlow +#import METReconstruction.METConfig_RefFinal -#from METReconstruction.METRecoFlags import metFlags -from METReconstruction.METRecoConfig import getMETRecoAlg +from METReconstruction.METRecoFlags import metFlags -# Get the configuration directly from METRecoFlags -# Can also provide a dict of configurations or list of RecoTools or both -metAlg = getMETRecoAlg('METReconstruction') +############################################################################## +from AthenaCommon.AppMgr import ToolSvc from AthenaCommon.AlgSequence import AlgSequence topSequence = AlgSequence() -topSequence += metAlg -topSequence += CfgMgr.met__METReaderAlg("METReader") -# The tools are accessible via the configurations in metFlags -topSequence.METReconstruction.OutputLevel = DEBUG -from AthenaCommon.AppMgr import ToolSvc -ToolSvc.MET_RecoTool_RefFinal.OutputLevel = VERBOSE -ToolSvc.MET_RecoTool_LocHadTopo.OutputLevel = VERBOSE -ToolSvc.MET_RecoTool_Calo.OutputLevel = VERBOSE -ToolSvc.MET_RecoTool_Truth.OutputLevel = VERBOSE +############################################################################## -from Valkyrie.JobOptCfg import ValgrindSvc -svcMgr += ValgrindSvc( OutputLevel = DEBUG, - ProfiledAlgs = ["METReconstruction"], - ProfiledIntervals = ["METReconstruction.execute"]) +metFlags.DoPFlow.set_Value_and_Lock(False) -from PerfMonComps.PerfMonFlags import jobproperties as pmon_properties -pmon_properties.PerfMonFlags.doSemiDetailedMonitoring=True +from AthenaCommon.Resilience import protectedInclude +protectedInclude("METReconstruction/METReconstruction_jobOptions.py") write_xAOD = True if write_xAOD: # The list of output containers/maps is autogenerated and stored in metFlags # This jO extracts them with the appropriate formatting - from AthenaCommon.Resilience import protectedInclude protectedInclude("METReconstruction/METReconstructionOutputAODList_jobOptions.py") from OutputStreamAthenaPool.MultipleStreamManager import MSMgr - xaodStream = MSMgr.NewPoolStream( "StreamAOD", "xAOD.pool.root" ) + xaodStream = MSMgr.NewPoolRootStream( "StreamAOD", "xAOD.8TeV.pool.root" ) for item in MissingETAODList: xaodStream.AddItem(item) - ServiceMgr.AthenaPoolCnvSvc.PoolAttributes += [ - "DEFAULT_SPLITLEVEL='99'" ] - - # Force POOL to just simply use the StoreGate keys as branch names: - ServiceMgr.AthenaPoolCnvSvc.SubLevelBranchName = "<key>" +from PerfMonComps.PerfMonFlags import jobproperties as pmon_properties +pmon_properties.PerfMonFlags.doSemiDetailedMonitoring=True -theApp.EvtMax = -1 +# assocRefAlg.OutputLevel=VERBOSE +# topSequence.METAssociation.OutputLevel=VERBOSE +# ToolSvc.MET_AssociationTool_AntiKt4LCTopo.OutputLevel=VERBOSE +# ToolSvc.MET_LCJetAssocTool_AntiKt4LCTopo.OutputLevel=VERBOSE +# ToolSvc.MET_PhotonAssociator_AntiKt4LCTopo.OutputLevel=VERBOSE +# ToolSvc.MET_SoftAssociator_AntiKt4LCTopo.OutputLevel=VERBOSE +# ToolSvc.MET_JetTool_RefFinal2.OutputLevel=VERBOSE +# ToolSvc.METMaker_AntiKt4LCTopo.OutputLevel=VERBOSE +# ToolSvc.METMaker_Test.OutputLevel=VERBOSE + +theApp.EvtMax = 40 ServiceMgr.EventSelector.SkipEvents = 0 +ServiceMgr.MessageSvc.defaultLimit = 99999 diff --git a/Reconstruction/MET/METReconstruction/share/RunMETReco_Associator.py b/Reconstruction/MET/METReconstruction/share/RunMETReco_Associator.py new file mode 100644 index 0000000000000000000000000000000000000000..27669599894a8dfc5df2d977db3fbefc09224715 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/share/RunMETReco_Associator.py @@ -0,0 +1,53 @@ +import AthenaPoolCnvSvc.ReadAthenaPool +from AthenaCommon.AthenaCommonFlags import athenaCommonFlags +from AthenaCommon.AppMgr import ServiceMgr +from AthenaCommon import CfgMgr + +import METReconstruction.METConfig_Calo + +from RecExConfig.RecFlags import rec +if rec.doTruth: + import METReconstruction.METConfig_Truth + +filelist = ["/afs/cern.ch/user/b/boliu/workdir/dataset/mc14_8TeV.117050.PowhegPythia_P2011C_ttbar.merge.AOD.e1727_s1933_s1911_r5591_r5625_tid01507243_00/AOD.01507243._011158.pool.root.1"] +ServiceMgr.EventSelector.InputCollections = filelist + +# Set up default configurations +import METReconstruction.METConfig_Associator + +#from METReconstruction.METRecoFlags import metFlags +from METReconstruction.METRecoConfig_Associator import getMETRecoAlg + +# Get the configuration directly from METRecoFlags +# Can also provide a dict of configurations or list of RecoTools or both +metAlg = getMETRecoAlg('METReconstruction') +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() +topSequence += metAlg + +# The tools are accessible via the configurations in metFlags +from AthenaCommon.AppMgr import ToolSvc + +from Valkyrie.JobOptCfg import ValgrindSvc +svcMgr += ValgrindSvc( OutputLevel = DEBUG, + ProfiledAlgs = ["METReconstruction"], + ProfiledIntervals = ["METReconstruction.execute"]) + +from PerfMonComps.PerfMonFlags import jobproperties as pmon_properties +pmon_properties.PerfMonFlags.doSemiDetailedMonitoring=True + +write_xAOD = True +if write_xAOD: + + # The list of output containers/maps is autogenerated and stored in metFlags + # This jO extracts them with the appropriate formatting + from AthenaCommon.Resilience import protectedInclude + protectedInclude("METReconstruction/METReconstructionOutputAODList_jobOptions.py") + + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + xaodStream = MSMgr.NewPoolRootStream( "StreamAOD", "xAOD.pool.root" ) + for item in MissingETAODList: + xaodStream.AddItem(item) + +theApp.EvtMax = -1 +ServiceMgr.EventSelector.SkipEvents = 0 diff --git a/Reconstruction/MET/METReconstruction/src/METAssocAlg.cxx b/Reconstruction/MET/METReconstruction/src/METAssocAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3ad59913f51ba3ebd8699879c0300c44fb94523c --- /dev/null +++ b/Reconstruction/MET/METReconstruction/src/METAssocAlg.cxx @@ -0,0 +1,864 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssocAlg.cxx + +#include "METAssocAlg.h" + +#include "xAODMissingET/MissingETContainer.h" +#include "xAODMissingET/MissingETAuxContainer.h" +#include "xAODMissingET/MissingETComposition.h" +#include "xAODMissingET/MissingETAssociationMap.h" +#include "xAODMissingET/MissingETAuxAssociationMap.h" + +#include "xAODEgamma/EgammaxAODHelpers.h" +#include "AthContainers/ConstDataVector.h" + +// Track errors +#include "EventPrimitives/EventPrimitivesHelpers.h" + +#include "xAODEventInfo/EventInfo.h" + +using std::string; +using std::vector; +using namespace xAOD; + +using std::string; + +namespace met { + + static inline bool greaterPt(const xAOD::IParticle* part1, const xAOD::IParticle* part2) { + return part1->pt()>part2->pt(); + } + static inline bool greaterPtPFO(const xAOD::PFO* part1, const xAOD::PFO* part2) { + if (part1->charge()==0 && part2->charge()!=0) return false; + if (part1->charge()!=0 && part2->charge()==0) return true; + if (part1->charge()==0 && part2->charge()==0) return part1->ptEM()>part2->ptEM(); + return part1->pt()>part2->pt(); + } + + //********************************************************************** + + METAssocAlg::METAssocAlg(const std::string& name, + ISvcLocator* pSvcLocator ) + : ::AthAlgorithm( name, pSvcLocator ) { + declareProperty( "METContainer", m_contname = "MET_Core" ); + declareProperty( "METAssociationMap", m_mapname = "METAssoc" ); + + declareProperty( "JetColl", m_jetcoll = "AntiKt4LCTopoJets" ); + declareProperty( "EleColl", m_elecoll = "ElectronCollection" ); + declareProperty( "GammaColl", m_gammacoll = "PhotonCollection" ); + declareProperty( "TauColl", m_taucoll = "TauRecContainer" ); + declareProperty( "MuonColl", m_muoncoll = "Muons" ); + declareProperty( "PrimVxColl", m_pvcoll = "PrimaryVertices" ); + declareProperty( "TrkColl", m_trkcoll = "InDetTrackParticles" ); + declareProperty( "ClusColl", m_clcoll = "CaloCalTopoCluster" ); + declareProperty( "PFlow", m_pflow = false ); + declareProperty( "PFOTool", m_pfotool ); + declareProperty( "TrackSelectorTool", m_trkseltool ); + } + + //********************************************************************** + + METAssocAlg::~METAssocAlg() { } + + //********************************************************************** + + StatusCode METAssocAlg::initialize() { + ATH_MSG_INFO("Initializing " << name() << "..."); + + return StatusCode::SUCCESS; + } + + //********************************************************************** + + StatusCode METAssocAlg::finalize() { + ATH_MSG_INFO ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + //********************************************************************** + + StatusCode METAssocAlg::execute() { + ATH_MSG_VERBOSE("Executing " << name() << "..."); + // Loop over tools. + + // Create a MissingETAssociationMap with its aux store + MissingETAssociationMap* metMap = new MissingETAssociationMap(); + if( evtStore()->record(metMap, m_mapname).isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAssociationMap: " << m_mapname); + return StatusCode::SUCCESS; + } + MissingETAuxAssociationMap* metAuxMap = new MissingETAuxAssociationMap(); + if( evtStore()->record(metAuxMap, m_mapname+"Aux.").isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAuxAssociationMap: " << m_mapname+"Aux."); + return StatusCode::SUCCESS; + } + metMap->setStore(metAuxMap); + + // Apply track selection filters + const CaloClusterContainer* tcCont(0); + if( evtStore()->retrieve(tcCont, m_clcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve topocluster container " << m_clcoll << " for overlap removal"); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved topocluster collection"); + + const VertexContainer* vxCont(0); + if( evtStore()->retrieve(vxCont, m_pvcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve primary vertex container " << m_pvcoll); + return StatusCode::SUCCESS; + } else if(vxCont->empty()) { + ATH_MSG_WARNING("Event has no primary vertices!"); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved primary vertex container"); + + const TrackParticleContainer* tracks=0; + ATH_CHECK( evtStore()->retrieve(tracks, m_trkcoll) ); + + filterTracks(tracks,(*vxCont)[0]); + + const PFOContainer* pfoCont = m_pfotool->retrievePFO(CP::EM, CP::all); + if(!pfoCont) { + ATH_MSG_WARNING("Unable to retrieve input pfo container"); + return StatusCode::SUCCESS; + } + + ATH_CHECK(m_trkseltool.retrieve()); + + // Generate association objects from the jets in the event ****************** + const JetContainer* jetCont(0); + if( evtStore()->retrieve(jetCont, m_jetcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input jet container " << m_jetcoll); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved jet collection"); + + CHECK( setupJetAssoc(metMap, jetCont, (*vxCont)[0]) ); + + /// Muons + /// Do muons before electrons and photons to remove track overlaps + + const MuonContainer* muonCont(0); + if( evtStore()->retrieve(muonCont, m_muoncoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input muon container " << m_muoncoll); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved muon collection"); + + // vector<const IParticle*> mutracks; + CHECK( setupMuons(metMap, muonCont, (*vxCont)[0], pfoCont)); + + /// Electrons + + const ElectronContainer* elCont(0); + if( evtStore()->retrieve(elCont, m_elecoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input electron container " << m_elecoll); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved electron collection"); + CHECK( setupElectrons(metMap, elCont, tcCont, (*vxCont)[0], pfoCont)); + + /// Photons + + const PhotonContainer* phCont(0); + if( evtStore()->retrieve(phCont, m_gammacoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input photon container " << m_gammacoll); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved photon collection"); + CHECK( setupPhotons(metMap, phCont, tcCont, (*vxCont)[0], pfoCont)); + + /// Taus + + const TauJetContainer* tauCont(0); + if( evtStore()->retrieve(tauCont, m_taucoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve input tau container " << m_taucoll); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully retrieved tau collection"); + + CHECK( setupTaus(metMap, tauCont, (*vxCont)[0], pfoCont)); + + // Do internal overlap-finding ********************************************** + + bool foundOverlaps = metMap->identifyOverlaps(); + if(foundOverlaps) ATH_MSG_DEBUG("Overlaps identified!"); + + // Create a MissingETContainer with its aux store + MissingETContainer* newMet = new MissingETContainer(); + if( evtStore()->record(newMet, m_contname).isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETContainer: " << m_contname); + return StatusCode::SUCCESS; + } + MissingETAuxContainer* metAuxCont = new MissingETAuxContainer(); + if( evtStore()->record(metAuxCont, m_contname+"Aux.").isFailure() ) { + ATH_MSG_WARNING("Unable to record MissingETAuxContainer: " << m_contname+"Aux."); + return StatusCode::SUCCESS; + } + newMet->setStore(metAuxCont); + + MissingET* metCoreCl = new MissingET(0.,0.,0.,"SoftClusCore",MissingETBase::Source::softEvent() | MissingETBase::Source::cluster()); + newMet->push_back(metCoreCl); + MissingET* metCoreTrk = new MissingET(0.,0.,0.,"PVSoftTrkCore",MissingETBase::Source::softEvent() | MissingETBase::Source::track()); + newMet->push_back(metCoreTrk); + const IParticleContainer* uniqueClusters; + if (m_pflow) uniqueClusters = metMap->getUniqueSignals(pfoCont,MissingETBase::UsageHandler::Policy::ParticleFlow); + else uniqueClusters = metMap->getUniqueSignals(tcCont); + for(IParticleContainer::const_iterator iSig=uniqueClusters->begin();iSig!=uniqueClusters->end();iSig++) { + if (m_pflow) { + const xAOD::PFO *pfo = dynamic_cast<const xAOD::PFO*>(*iSig); + if (pfo->charge()==0) { + TLorentzVector corrected = pfo->GetVertexCorrectedEMFourVec(*((*vxCont)[0])); + if (pfo->eEM()>0) metCoreCl->add(corrected.Px(),corrected.Py(),corrected.Pt()); + continue; + } else if (!acceptChargedPFO(pfo->track(0),(*vxCont)[0])) continue; + *metCoreTrk += *iSig; + } + if ((*iSig)->e()>0) *metCoreCl += *iSig; + } + if (m_pflow) return StatusCode::SUCCESS; + + const IParticleContainer* uniqueTracks = metMap->getUniqueSignals(tracks); + for(const auto& trk : *uniqueTracks) { +// if(acceptTrack(dynamic_cast<const TrackParticle*>(trk),(*vxCont)[0]) && isGoodEoverP(dynamic_cast<const TrackParticle*>(trk))) { + if(acceptTrack(dynamic_cast<const TrackParticle*>(trk),(*vxCont)[0]) ) { + ATH_MSG_VERBOSE("Add core track with pt " << trk->pt()); + *metCoreTrk += trk; + } + } + + delete uniqueClusters; + delete uniqueTracks; + + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Create jet associations + StatusCode METAssocAlg::setupJetAssoc(xAOD::MissingETAssociationMap* metMap, + const xAOD::JetContainer* jets, + const xAOD::Vertex* pv) + { + for(const auto& jet : *jets) { + ATH_MSG_VERBOSE("Jet pt, eta, phi = " << jet->pt() << ", " << jet->eta() << "," << jet->phi() ); + std::vector<const IParticle*> selectedTracks; + if (m_pflow) { + for (size_t consti = 0; consti < jet->numConstituents(); consti++) { + const PFO *pfo = dynamic_cast<const PFO*>(jet->rawConstituent(consti)); + if (pfo->charge()!=0) selectedTracks.push_back(pfo->track(0)); + } + } else { + std::vector<const IParticle*> jettracks; + jet->getAssociatedObjects<IParticle>(JetAttribute::GhostTrack,jettracks); + selectedTracks = selectTracks(jettracks,pv); + } + MissingETComposition::add(metMap,jet,selectedTracks); + ATH_MSG_VERBOSE("Added association " << metMap->findIndex(jet) << " pointing to jet " << jet); + } + MissingETComposition::addMiscAssociation(metMap); + ATH_MSG_VERBOSE("Added miscellaneous association"); + + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Do muon track finding + StatusCode METAssocAlg::setupMuons(xAOD::MissingETAssociationMap* metMap, + const xAOD::MuonContainer* muons, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont) + // std::vector<const xAOD::IParticle*>& mutracks) + { + vector<const IParticle*> constlist; + constlist.reserve(2); + for(const auto& mu : *muons) { + // if(mu->pt()<5e3) continue; + ATH_MSG_VERBOSE( "Muon px, py, pt = " << mu->p4().Px() << ", " << mu->p4().Py() << ", " << mu->pt() ); + constlist.clear(); + MissingETBase::Types::constvec_t tcvec; + MissingETBase::Types::constvec_t trkvec; + // ATH_MSG_VERBOSE( "Muon pt, eta, phi = " << mu->pt() << ", " << mu->eta() << "," << mu->phi() ); + const TrackParticle* idtrack = mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle); + if(idtrack) { + // if(acceptTrack(idtrack,pv) && isGoodEoverP(idtrack)) { + if(acceptTrack(idtrack,pv) ) { + ATH_MSG_VERBOSE("Accept muon track " << idtrack << " px, py = " << idtrack->p4().Px() << ", " << idtrack->p4().Py()); + ATH_MSG_VERBOSE("Muon ID track ptr: " << idtrack); + if (m_pflow) { + for(const auto& pfo : *pfoCont) { + if (pfo->charge()!=0 && pfo->track(0) == idtrack) { + constlist.push_back(pfo); + trkvec += *idtrack; + } + if (pfo->charge()==0 && mu->cluster() && mu->cluster()->p4().DeltaR(pfo->p4EM())<0.1 && pfo->eEM()>0) constlist.push_back(pfo); + } + } else { + constlist.push_back(idtrack); + trkvec += *idtrack; + } + // if(mu->pt()>10e3 && (mu->muonType()==xAOD::Muon::Combined || mu->muonType()==xAOD::Muon::SegmentTagged)) { + // mutracks.push_back(idtrack); + // } + } + } + ATH_MSG_VERBOSE( "Muon track px, py, pt = " << trkvec.cpx() << ", " << trkvec.cpy() << ", " << trkvec.cpt() ); + + bool inserted(false); + inserted = MissingETComposition::insert(metMap,mu,constlist,tcvec,trkvec); + if(inserted) { + const MissingETAssociation* assoc = MissingETComposition::getAssociation(metMap,mu); + ATH_MSG_VERBOSE( "Muon is associated to jet " << assoc->refJet()->index() << " with pt " << assoc->refJet()->pt() ); + ATH_MSG_VERBOSE( "Muon-jet deltaR = " << mu->p4().DeltaR(assoc->refJet()->p4()) ); + } else { + ATH_MSG_VERBOSE( "Add muon as miscellaneous object" ); + inserted = MissingETComposition::insertMisc(metMap,mu,constlist,tcvec,trkvec); + } + ATH_MSG_VERBOSE( (inserted ? "Successfully" : "Unsuccessfully" ) << " inserted muon into association map"); + } + ATH_MSG_VERBOSE("Done with muon setup"); + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Do electron topocluster finding + StatusCode METAssocAlg::setupElectrons(xAOD::MissingETAssociationMap* metMap, + const xAOD::ElectronContainer* electrons, + const xAOD::CaloClusterContainer* clusters, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont) + // std::vector<const xAOD::IParticle*>& mutracks) + { + vector<const xAOD::IParticle*> constlist; + constlist.reserve(10); + ConstDataVector<ElectronContainer> electrons_tmp(SG::VIEW_ELEMENTS); + for(const auto& ph : *electrons) { + electrons_tmp.push_back(ph); + } + std::sort(electrons_tmp.begin(),electrons_tmp.end(),greaterPt); + + for(const auto& el : electrons_tmp) { + // if(el->pt()<5e3) continue; + ATH_MSG_VERBOSE( "Electron px, py, pt = " << el->p4().Px() << ", " << el->p4().Py() << ", " << el->pt() ); + constlist.clear(); + MissingETBase::Types::constvec_t tcvec,trkvec; + // ATH_MSG_VERBOSE( "Electron pt, eta, phi = " << el->pt() << ", " << el->eta() << "," << el->phi() ); + if (m_pflow) this->extractPFO(el,pfoCont,constlist,tcvec,trkvec,pv); + else { + this->extractTopoClusters(el,clusters,constlist,tcvec); + this->extractTracks(el,pv,constlist,trkvec); + } + ATH_MSG_VERBOSE( "Electron has " << constlist.size() << " topoclusters." ); + + ATH_MSG_VERBOSE( "Electron tc px, py, pt, sumpt = " << tcvec.cpx() << ", " << tcvec.cpy() << ", " << tcvec.cpt() << ", " << tcvec.sumpt() ); + ATH_MSG_VERBOSE( "Electron track px, py, pt, sumpt = " << trkvec.cpx() << ", " << trkvec.cpy() << ", " << trkvec.cpt() << ", " << trkvec.sumpt() ); + + bool inserted(false); + inserted = MissingETComposition::insert(metMap,el,constlist,tcvec,trkvec); + if(inserted) { + const MissingETAssociation* assoc = MissingETComposition::getAssociation(metMap,el); + ATH_MSG_VERBOSE( "Electron is associated to jet " << assoc->refJet()->index() << " with pt " << assoc->refJet()->pt() ); + ATH_MSG_VERBOSE( "Electron-jet deltaR = " << el->p4().DeltaR(assoc->refJet()->p4()) ); + } else { + ATH_MSG_VERBOSE( "Add electron as miscellaneous object" ); + inserted = MissingETComposition::insertMisc(metMap,el,constlist,tcvec,trkvec); + } + ATH_MSG_VERBOSE( (inserted ? "Successfully" : "Unsuccessfully" ) << " inserted electron into association map"); + } + ATH_MSG_VERBOSE("Done with electron setup"); + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Do photon topocluster finding + StatusCode METAssocAlg::setupPhotons(xAOD::MissingETAssociationMap* metMap, + const xAOD::PhotonContainer* photons, + const xAOD::CaloClusterContainer* clusters, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont) + // std::vector<const xAOD::IParticle*>& mutracks) + { + vector<const xAOD::IParticle*> constlist; + constlist.reserve(10); + ConstDataVector<PhotonContainer> photons_tmp(SG::VIEW_ELEMENTS); + for(const auto& ph : *photons) { + photons_tmp.push_back(ph); + } + std::sort(photons_tmp.begin(),photons_tmp.end(),greaterPt); + + for(const auto& ph : photons_tmp) { + // if(ph->pt()<5e3) continue; + ATH_MSG_VERBOSE( "Photon px, py, pt = " << ph->p4().Px() << ", " << ph->p4().Py() << ", " << ph->pt() ); + constlist.clear(); + MissingETBase::Types::constvec_t tcvec,trkvec; + if (m_pflow) this->extractPFO(ph,pfoCont,constlist,tcvec,trkvec,pv); + else { + this->extractTopoClusters(ph,clusters,constlist,tcvec); + ATH_MSG_VERBOSE( "Photon has " << constlist.size() << " topoclusters." ); + this->extractTracks(ph,pv,constlist,trkvec); + } + + ATH_MSG_VERBOSE( "Photon tc px, py, pt, sumpt = " << tcvec.cpx() << ", " << tcvec.cpy() << ", " << tcvec.cpt() << ", " << tcvec.sumpt() ); + ATH_MSG_VERBOSE( "Photon track px, py, pt, sumpt = " << trkvec.cpx() << ", " << trkvec.cpy() << ", " << trkvec.cpt() << ", " << trkvec.sumpt() ); + + bool inserted(false); + inserted = MissingETComposition::insert(metMap,ph,constlist,tcvec,trkvec); + if(inserted) { + const MissingETAssociation* assoc = MissingETComposition::getAssociation(metMap,ph); + ATH_MSG_VERBOSE( "Photon is associated to jet " << assoc->refJet()->index() << " with pt " << assoc->refJet()->pt() ); + ATH_MSG_VERBOSE( "Photon-jet deltaR = " << ph->p4().DeltaR(assoc->refJet()->p4()) ); + } else { + ATH_MSG_VERBOSE( "Add photon as miscellaneous object" ); + inserted = MissingETComposition::insertMisc(metMap,ph,constlist,tcvec,trkvec); + } + ATH_MSG_VERBOSE( (inserted ? "Successfully" : "Unsuccessfully" ) << " inserted photon into association map"); + } + ATH_MSG_VERBOSE("Done with photons setup"); + return StatusCode::SUCCESS; + } + + //********************************************************************************************************* + // Do tau topocluster finding + StatusCode METAssocAlg::setupTaus(xAOD::MissingETAssociationMap* metMap, + const xAOD::TauJetContainer* taus, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont) + // std::vector<const xAOD::IParticle*>& mutracks) + { + vector<const xAOD::IParticle*> constlist; + constlist.reserve(20); + ConstDataVector<TauJetContainer> taus_tmp(SG::VIEW_ELEMENTS); + for(const auto& ph : *taus) { + taus_tmp.push_back(ph); + } + std::sort(taus_tmp.begin(),taus_tmp.end(),greaterPt); + + for(const auto& tau : taus_tmp) { + // if(tau->pt()<5e3) continue; + ATH_MSG_VERBOSE( "Tau px, py, pt = " << tau->p4().Px() << ", " << tau->p4().Py() << ", " << tau->pt() ); + constlist.clear(); + MissingETBase::Types::constvec_t tcvec,trkvec; + if (m_pflow) this->extractPFO(tau,pfoCont,constlist,tcvec,trkvec,pv); + else { + this->extractTopoClusters(tau,constlist,tcvec); + this->extractTracks(tau,pv,constlist,trkvec); + } + + ATH_MSG_VERBOSE( "Tau tc px, py, pt, sumpt = " << tcvec.cpx() << ", " << tcvec.cpy() << ", " << tcvec.cpt() << ", " << tcvec.sumpt() ); + ATH_MSG_VERBOSE( "Tau track px, py, pt, sumpt = " << trkvec.cpx() << ", " << trkvec.cpy() << ", " << trkvec.cpt() << ", " << trkvec.sumpt() ); + + bool inserted(false); + inserted = MissingETComposition::insert(metMap,tau,constlist,tcvec,trkvec); + ATH_MSG_VERBOSE( (inserted ? "Successfully" : "Unsuccessfully" ) << " inserted tau into association map"); + const MissingETAssociation* assoc = MissingETComposition::getAssociation(metMap,tau); + if(assoc) { + ATH_MSG_VERBOSE( "Tau is associated to jet " << assoc->refJet()->index() << " with pt " << assoc->refJet()->pt() ); + ATH_MSG_VERBOSE( "Tau-jet deltaR = " << tau->p4().DeltaR(assoc->refJet()->p4()) ); + const Jet* seedjet = *tau->jetLink(); + ATH_MSG_VERBOSE( "Tau has seed jet " << seedjet->index() << " with pt " << seedjet->pt() ); + } + } + + ATH_MSG_VERBOSE("Done with tau setup"); + return StatusCode::SUCCESS; + } + //********************************************************************** + // Get Egamma constituents + void METAssocAlg::extractPFO(const xAOD::Egamma* eg, + const xAOD::PFOContainer* pfoCont, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::Vertex* pv) + { + // safe to assume a single SW cluster? + // will do so for now... + const CaloCluster* swclus = eg->caloCluster(); + double eg_cl_e = swclus->e(); + const xAOD::Electron* elec = (eg->type()==xAOD::Type::ObjectType::Electron) ? dynamic_cast<const xAOD::Electron*>(eg) : NULL; + const xAOD::Photon* ph = (eg->type()==xAOD::Type::ObjectType::Photon) ? dynamic_cast<const xAOD::Photon*>(eg) : NULL; + + // the matching strategy depends on how the cluster container is sorted + // easier if it's sorted in descending pt order + // we'll worry about optimisation later + vector<const xAOD::PFO*> nearbyPFO; + nearbyPFO.reserve(10); + for(const auto& pfo : *pfoCont) { + std::vector<const IParticle*> cls; + bool match = false; + if (pfo->charge()==0) { + if (swclus->p4().DeltaR(pfo->p4EM())<0.1 && pfo->eEM()>0) match = true; + //pfo->associatedParticles(PFODetails::CaloCluster,cls); + //for(const auto& cl : cls) { + // if (!cl) continue; + // double dR = swclus->p4().DeltaR(cl->p4()); + // if(dR<0.1 && cl->e()>0) match = true; + //} + } + if (elec) { + for(size_t iTrk=0; iTrk<elec->nTrackParticles(); ++iTrk) { + const TrackParticle* eltrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(elec->trackParticle(iTrk)); + if(pfo->charge()!=0 && acceptChargedPFO(eltrk,pv) && pfo->track(0) == eltrk) match = true; + } + } + if (ph) { + for(size_t iVtx=0; iVtx<ph->nVertices(); ++iVtx) { + const Vertex* phvx = ph->vertex(iVtx); + for(size_t iTrk=0; iTrk<phvx->nTrackParticles(); ++iTrk) { + const TrackParticle* phtrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(phvx->trackParticle(iTrk)); + if(pfo->charge()!=0 && acceptChargedPFO(phtrk,pv) && pfo->track(0) == phtrk) match = true; + } + } + } + if (match) nearbyPFO.push_back(pfo); + } + ATH_MSG_VERBOSE("Found " << nearbyPFO.size() << " nearby pfos"); + + bool doSum = true; + double sumE_pfo = 0.; + std::sort(nearbyPFO.begin(),nearbyPFO.end(),greaterPtPFO); + for(const auto& pfo : nearbyPFO) { + double pfo_e = (pfo->charge()==0 ? pfo->eEM() : pfo->e()); + // skip cluster if it's above our bad match threshold + if(pfo->eEM()>2*eg_cl_e) { + ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (pfo->eEM()/eg_cl_e)); + continue; + } + + if( (doSum = fabs(sumE_pfo+pfo->e()-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) { + pfolist.push_back(pfo); + sumE_pfo += pfo_e; + pfovec += (pfo->charge()==0 ? MissingETBase::Types::constvec_t(pfo->ptEM()*cos(pfo->phiEM()),pfo->ptEM()*sin(pfo->phiEM()),pfo->ptEM()*cosh(pfo->etaEM()),pfo->eEM(),pfo->eEM()) : MissingETBase::Types::constvec_t(*pfo)); + trkvec += MissingETBase::Types::constvec_t(*pfo); + } // if we will retain the topocluster + else {break;} + } // loop over nearby clusters + } + + void METAssocAlg::extractTracks(const xAOD::TauJet* tau, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec) + { + const Jet* jet = *tau->jetLink(); + for(size_t iTrk=0; iTrk<tau->nTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->track(iTrk); + // if(acceptTrack(tautrk,pv) && isGoodEoverP(tautrk)) { + if(acceptTrack(tautrk,pv) ) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (tautrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + // if(!matchedmu) { + ATH_MSG_VERBOSE("Accept tau track " << tautrk << " px, py = " << tautrk->p4().Px() << ", " << tautrk->p4().Py()); + constlist.push_back(tautrk); + trkvec += *tautrk; + // } + } + } + for(size_t iTrk=0; iTrk<tau->nOtherTracks(); ++iTrk) { + const xAOD::TrackParticle* tautrk = tau->otherTrack(iTrk); + double dR = jet->p4().DeltaR(tautrk->p4()); + // if(dR<0.2 && acceptTrack(tautrk,pv) && isGoodEoverP(tautrk)) { + if(dR<0.2 && acceptTrack(tautrk,pv) ) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (tautrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + // if(!matchedmu) { + ATH_MSG_VERBOSE("Accept track " << tautrk << " px, py = " << tautrk->p4().Px() << ", " << tautrk->p4().Py()); + constlist.push_back(tautrk); + trkvec += *tautrk; + // } + } + } + } + void METAssocAlg::extractTracks(const xAOD::Photon* ph, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec) + { + vector<const xAOD::TrackParticle*> phtrks; + for(size_t iVtx=0; iVtx<ph->nVertices(); ++iVtx) { + const Vertex* phvx = ph->vertex(iVtx); + for(size_t iTrk=0; iTrk<phvx->nTrackParticles(); ++iTrk) { + // if(!phvx->trackParticle(iTrk)) { + // ATH_MSG_INFO("Invalid photon trackparticle pointer"); + // } + const TrackParticle* phtrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(phvx->trackParticle(iTrk)); + // if(acceptTrack(phtrk,pv) && isGoodEoverP(phtrk) && ph->p4().DeltaR(phtrk->p4())<0.1) { + if(acceptTrack(phtrk,pv) && ph->p4().DeltaR(phtrk->p4())<0.2) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu = (phtrk == mutrk)) ) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + bool duplicate = false; + for(const auto& gamtrk : phtrks) { + if( (duplicate = (phtrk == gamtrk)) ) { + ATH_MSG_VERBOSE("Veto duplicate track"); + break; + } + } + // if(!matchedmu && !duplicate) { + if(!duplicate) { + ATH_MSG_VERBOSE("Accept photon track " << phtrk << " px, py = " << phtrk->p4().Px() << ", " << phtrk->p4().Py()); + ATH_MSG_VERBOSE(" track eta, phi = " << phtrk->p4().Eta() << ", " << phtrk->p4().Phi()); + ATH_MSG_VERBOSE("Delta R = " << ph->p4().DeltaR(phtrk->p4())); + constlist.push_back(phtrk); + trkvec += *phtrk; + phtrks.push_back(phtrk); + } + } + } + } + } + void METAssocAlg::extractTracks(const xAOD::Electron* el, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec) + { + for(size_t iTrk=0; iTrk<el->nTrackParticles(); ++iTrk) { + const TrackParticle* eltrk = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(el->trackParticle(iTrk)); + // if(acceptTrack(eltrk,pv) && isGoodEoverP(eltrk) && el->p4().DeltaR(eltrk->p4())<0.1) { + if(acceptTrack(eltrk,pv) && el->p4().DeltaR(eltrk->p4())<0.1) { + // bool matchedmu = false; + // for(const auto& mutrk : mutracks) { + // if( (matchedmu=(eltrk == mutrk))) { + // ATH_MSG_VERBOSE("Veto track matched to muon"); + // break; + // } + // } + // if(!matchedmu) { + ATH_MSG_VERBOSE("Accept electron track " << eltrk << " px, py = " << eltrk->p4().Px() << ", " << eltrk->p4().Py()); + constlist.push_back(eltrk); + trkvec += *eltrk; + } + } + } + //********************************************************************** + // Get Egamma constituents + void METAssocAlg::extractTopoClusters(const xAOD::Egamma* eg, + const xAOD::CaloClusterContainer* tcCont, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec) + { + // safe to assume a single SW cluster? + // will do so for now... + const CaloCluster* swclus = eg->caloCluster(); + double eg_cl_e = swclus->e(); + + // the matching strategy depends on how the cluster container is sorted + // easier if it's sorted in descending pt order + // we'll worry about optimisation later + vector<const xAOD::CaloCluster*> nearbyTC; + nearbyTC.reserve(10); + for(const auto& cl : *tcCont) { + // this can probably be done more elegantly + double dR = swclus->p4().DeltaR(cl->p4()); + if(dR<0.1 && cl->e()>0) { + // could consider also requirements on the EM fraction or depth + nearbyTC.push_back(cl); + } // match TC in a cone around SW cluster + } + ATH_MSG_VERBOSE("Found " << nearbyTC.size() << " nearby topoclusters"); + + bool doSum = true; + double sumE_tc = 0.; + const CaloCluster* bestbadmatch = 0; + std::sort(nearbyTC.begin(),nearbyTC.end(),greaterPt); + for(const auto& cl : nearbyTC) { + double tcl_e = cl->e(); + // skip cluster if it's above our bad match threshold + // FIXME: What to do with these poor matches? + if(tcl_e>1.5*eg_cl_e) { + ATH_MSG_VERBOSE("Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e)); + if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->e()/eg_cl_e-1.)) ) bestbadmatch = cl; + continue; + } + + ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e); + if( (doSum = (fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e))) ) { + ATH_MSG_VERBOSE("Accept topocluster with pt " << cl->pt() << ", e " << cl->e() << " in sum."); + ATH_MSG_VERBOSE("E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e); + ATH_MSG_VERBOSE("Energy ratio of TC to eg: " << tcl_e / eg_cl_e); + tclist.push_back(cl); + sumE_tc += tcl_e; + tcvec += MissingETBase::Types::constvec_t(*cl); + } // if we will retain the topocluster + } // loop over nearby clusters + if(sumE_tc<1e-9 && bestbadmatch) { + ATH_MSG_VERBOSE("No better matches found -- add bad match topocluster with pt " + << bestbadmatch->pt() << ", e " << bestbadmatch->e() << "."); + tclist.push_back(bestbadmatch); + tcvec += MissingETBase::Types::constvec_t(*bestbadmatch); + } + } + + //********************************************************************************************************* + // Get tau constituents + void METAssocAlg::extractPFO(const xAOD::TauJet* tau, + const xAOD::PFOContainer* pfoCont, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::Vertex* pv) + { + const Jet* seedjet = *tau->jetLink(); + JetConstituentVector constit = seedjet->getConstituents(); + ATH_MSG_VERBOSE("Current tau has " << constit.size() << " constituents."); + for(const auto& pfo : *pfoCont) { + bool match = false; + if (pfo->charge()==0 && seedjet->p4().DeltaR(pfo->p4EM())<0.2) match = true;; + for(size_t iTrk=0; iTrk<tau->nTracks(); ++iTrk) { + const TrackParticle* tautrk = tau->track(iTrk); + if(acceptChargedPFO(tautrk,pv) && pfo->charge()!=0 && tautrk==pfo->track(0)) match = true; + } + for(size_t iTrk=0; iTrk<tau->nOtherTracks(); ++iTrk) { + const xAOD::TrackParticle* tautrk = tau->otherTrack(iTrk); + double dR = seedjet->p4().DeltaR(tautrk->p4()); + if(dR<0.2 && acceptChargedPFO(tautrk,pv) && pfo->charge()!=0 && tautrk==pfo->track(0)) match = true; + } + if (!match) continue; + pfolist.push_back(pfo); + if (pfo->charge()) trkvec += MissingETBase::Types::constvec_t(*pfo); + pfovec += (pfo->charge()==0 ? MissingETBase::Types::constvec_t(pfo->ptEM()*cos(pfo->phiEM()),pfo->ptEM()*sin(pfo->phiEM()),pfo->ptEM()*cosh(pfo->etaEM()),pfo->eEM(),pfo->eEM()) : MissingETBase::Types::constvec_t(*pfo)); + } + } + + //********************************************************************************************************* + // Get tau constituents + void METAssocAlg::extractTopoClusters(const xAOD::TauJet* tau, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec) + { + const Jet* seedjet = *tau->jetLink(); + JetConstituentVector constit = seedjet->getConstituents(); + ATH_MSG_VERBOSE("Current tau has " << constit.size() << " constituents."); + // test for used topoclusters, and retrieve unused ones (ok until/unless we use PFlow taus) + // only use clusters for computing the overlap removal relative to other objects + for(const auto& cl : constit) { + // TEMP: use jet seed axis + // taus will provide an accessor + double dR = seedjet->p4().DeltaR(cl->rawConstituent()->p4()); + if(dR>0.2) continue; + // skip cluster if dR>0.2 + const CaloCluster* pClus = dynamic_cast<const CaloCluster*>( cl->rawConstituent() ); + tclist.push_back(pClus); + tcvec += MissingETBase::Types::constvec_t(*pClus); + } // loop over jet constituents + } + + bool METAssocAlg::acceptChargedPFO(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) { + if(fabs((trk->z0() - pv->z()+trk->vz())*sin(trk->theta())) > 2) return false; + return true; + } + + + bool METAssocAlg::acceptTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv) + { + // if(!trk || !pv) return false; + + // if(fabs(trk->pt())<500/*MeV*/ || fabs(trk->eta())>2.5) return false; + + // // could add some error checking to make sure we successfully read the details + // uint8_t nPixHits(0), nSctHits(0); + // trk->summaryValue(nPixHits,xAOD::numberOfPixelHits); + // if(nPixHits<1) return false; + // trk->summaryValue(nSctHits,xAOD::numberOfSCTHits); + // if(nSctHits<6) return false; + + // if(fabs(trk->d0())>1.5) return false; + // if(fabs(trk->z0() + trk->vz() - pv->z()) > 1.5) return false; + + if(!(m_trkseltool->accept( *trk, pv ))) return false; + else return true; + + } + + bool METAssocAlg::isGoodEoverP(const xAOD::TrackParticle* trk) { + + if( (fabs(trk->eta())<1.5 && trk->pt()>200e3) || + (fabs(trk->eta())>=1.5 && trk->pt()>120e3) ) { + + const CaloClusterContainer *clusters = 0; + if( evtStore()->retrieve(clusters, m_clcoll).isFailure() ) { + ATH_MSG_WARNING("Unable to retrieve topocluster container " << m_clcoll << " for overlap removal"); + return StatusCode::SUCCESS; + } + + // Get relative error on qoverp + float Rerr = Amg::error(trk->definingParametersCovMatrix(),4)/fabs(trk->qOverP()); + ATH_MSG_VERBOSE( "Track momentum error (%): " << Rerr*100 ); + + // first compute track and calo isolation variables + float ptcone20 = 0; + for(const auto& testtrk : m_goodtracks) { + if(testtrk==trk) continue; + if(testtrk->p4().DeltaR(trk->p4()) < 0.2) { + ptcone20 += testtrk->pt(); + } + } + float isolfrac = ptcone20 / trk->pt(); + ATH_MSG_VERBOSE( "Track isolation fraction: " << isolfrac ); + + float etcone10 = 0.; + for(const auto& clus : *clusters) { + if(clus->p4().DeltaR(trk->p4()) < 0.1) { + etcone10 += clus->pt(); + } + } + float EoverP = etcone10/trk->pt(); + ATH_MSG_VERBOSE( "Track E/P: " << EoverP ); + + if(isolfrac<0.1) { + // isolated track cuts + if(Rerr>0.4) return false; + else if (EoverP<0.65 && (EoverP>0.1 || Rerr>0.1)) return false; + } else { + // non-isolated track cuts + float trkptsum = ptcone20+trk->pt(); + if(EoverP/trkptsum<0.6 && ptcone20/trkptsum<0.6) return false; + } + } + return true; + } + + void METAssocAlg::filterTracks(const xAOD::TrackParticleContainer* tracks, + const xAOD::Vertex* pv) { + for(const auto& trk : *tracks) { + m_goodtracks.clear(); + if(acceptTrack(trk,pv)) m_goodtracks.push_back(trk); + } + } + + std::vector<const xAOD::IParticle*> METAssocAlg::selectTracks(const std::vector<const xAOD::IParticle*>& tracksin, + const xAOD::Vertex* pv) + { + std::vector<const xAOD::IParticle*> tracksout; + tracksout.reserve(tracksin.size()); + for(const auto& trk : tracksin) { + const TrackParticle* pTrk = dynamic_cast<const TrackParticle*>(trk); +// if( acceptTrack(pTrk,pv) && isGoodEoverP(pTrk) ) { + if( acceptTrack(pTrk,pv) ) { + tracksout.push_back(trk); + ATH_MSG_VERBOSE("Accept track " << trk << " px, py = " << trk->p4().Px() << ", " << trk->p4().Py()); + } + } + return tracksout; + } + + //********************************************************************** + +} + diff --git a/Reconstruction/MET/METReconstruction/src/METAssocAlg.h b/Reconstruction/MET/METReconstruction/src/METAssocAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..f4919aea6568f5ebf8aeb50b65f7fd4729043288 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/src/METAssocAlg.h @@ -0,0 +1,145 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// METAssocAlg.h + +#ifndef METAssocAlg_H +#define METAssocAlg_H + +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ToolHandle.h" + +#include "xAODMissingET/MissingETAssociationMap.h" + +#include "xAODEgamma/EgammaFwd.h" +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/PhotonContainer.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODJet/JetContainer.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/Vertex.h" +#include "xAODPFlow/PFOContainer.h" +#include "xAODPFlow/PFO.h" +#include "PFlowUtils/IRetrievePFOTool.h" +#include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h" + +class IMETRecoTool; + +namespace met { + class METAssocAlg : public AthAlgorithm { + + public: + + /// Constructor with parameters: + METAssocAlg(const std::string& name, ISvcLocator* pSvcLocator); + + /// Destructor: + ~METAssocAlg(); + + /// Athena algorithm's Hooks + StatusCode initialize(); + StatusCode execute(); + StatusCode finalize(); + + private: + + /// Default constructor: + METAssocAlg(); + + StatusCode setupJetAssoc(xAOD::MissingETAssociationMap* metMap, + const xAOD::JetContainer* jets, + const xAOD::Vertex* pv); + StatusCode setupMuons(xAOD::MissingETAssociationMap* metMap, + const xAOD::MuonContainer* muons, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont); + // std::vector<const xAOD::IParticle*>& mutracks); + StatusCode setupElectrons(xAOD::MissingETAssociationMap* metMap, + const xAOD::ElectronContainer* electrons, + const xAOD::CaloClusterContainer* clusters, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont); + // std::vector<const xAOD::IParticle*>& mutracks); + StatusCode setupPhotons(xAOD::MissingETAssociationMap* metMap, + const xAOD::PhotonContainer* photons, + const xAOD::CaloClusterContainer* clusters, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont); + // std::vector<const xAOD::IParticle*>& mutracks); + StatusCode setupTaus(xAOD::MissingETAssociationMap* metMap, + const xAOD::TauJetContainer* taus, + const xAOD::Vertex* pv, + const xAOD::PFOContainer* pfoCont); + // std::vector<const xAOD::IParticle*>& mutracks); + + void extractTopoClusters(const xAOD::Egamma* eg, + const xAOD::CaloClusterContainer* tcCont, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec); + void extractTopoClusters(const xAOD::TauJet* tau, + std::vector<const xAOD::IParticle*>& tclist, + MissingETBase::Types::constvec_t& tcvec); + void extractTracks(const xAOD::TauJet* tau, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec); + void extractTracks(const xAOD::Electron* el, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec); + void extractTracks(const xAOD::Photon* ph, + const xAOD::Vertex* pv, + std::vector<const xAOD::IParticle*>& constlist, + MissingETBase::Types::constvec_t& trkvec); + void extractPFO(const xAOD::TauJet* tau, + const xAOD::PFOContainer* pfoCont, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::Vertex* pv); + void extractPFO(const xAOD::Egamma* eg, + const xAOD::PFOContainer* pfoCont, + std::vector<const xAOD::IParticle*>& pfolist, + MissingETBase::Types::constvec_t& pfovec, + MissingETBase::Types::constvec_t& trkvec, + const xAOD::Vertex* pv); + + bool acceptTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv); + bool acceptChargedPFO(const xAOD::TrackParticle* trk, const xAOD::Vertex* pv); + bool isGoodEoverP(const xAOD::TrackParticle* trk); + void filterTracks(const xAOD::TrackParticleContainer* tracks, + const xAOD::Vertex* pv); + std::vector<const xAOD::IParticle*> selectTracks(const std::vector<const xAOD::IParticle*>& tracksin, + const xAOD::Vertex* pv); + + // store list of accepted tracks for track isolation checks + std::vector<const xAOD::TrackParticle*> m_goodtracks; + + // configurable data members + std::string m_contname; + std::string m_mapname; + + std::string m_jetcoll; + std::string m_elecoll; + std::string m_gammacoll; + std::string m_taucoll; + std::string m_muoncoll; + std::string m_pvcoll; + std::string m_trkcoll; + std::string m_clcoll; + + bool m_pflow; + + ToolHandle<CP::IRetrievePFOTool> m_pfotool; + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; + + }; + +} + +#endif diff --git a/Reconstruction/MET/METReconstruction/src/components/METReconstruction_entries.cxx b/Reconstruction/MET/METReconstruction/src/components/METReconstruction_entries.cxx index 758a79c0496374f5c542b04ebbf9f469811cccb8..62ebe9fed9bf56bdf4fa91cabf0c708824e28e18 100644 --- a/Reconstruction/MET/METReconstruction/src/components/METReconstruction_entries.cxx +++ b/Reconstruction/MET/METReconstruction/src/components/METReconstruction_entries.cxx @@ -2,6 +2,7 @@ // Top level tool #include "METReconstruction/METRecoTool.h" +#include "METReconstruction/METAssociationTool.h" // Builders #include "METReconstruction/METElectronTool.h" #include "METReconstruction/METPhotonTool.h" @@ -9,6 +10,12 @@ #include "METReconstruction/METTauTool.h" #include "METReconstruction/METMuonTool.h" #include "METReconstruction/METSoftTermsTool.h" +#include "METReconstruction/METElectronAssociator.h" +#include "METReconstruction/METPhotonAssociator.h" +#include "METReconstruction/METJetAssocTool.h" +#include "METReconstruction/METTauAssociator.h" +#include "METReconstruction/METMuonAssociator.h" +#include "METReconstruction/METSoftAssociator.h" // Truth tool #include "METReconstruction/METTruthTool.h" // CaloRegions @@ -19,18 +26,26 @@ #include "METReconstruction/METMuonElossTool.h" #include "METReconstruction/METRegionsTool.h" // Algs -#include "../src/METRecoAlg.h" -#include "../src/METReaderAlg.h" +#include "METRecoAlg.h" +#include "METReaderAlg.h" +#include "METAssocAlg.h" using namespace met; DECLARE_TOOL_FACTORY(METRecoTool) +DECLARE_TOOL_FACTORY(METAssociationTool) DECLARE_TOOL_FACTORY(METElectronTool) DECLARE_TOOL_FACTORY(METPhotonTool) DECLARE_TOOL_FACTORY(METJetTool) DECLARE_TOOL_FACTORY(METTauTool) DECLARE_TOOL_FACTORY(METMuonTool) DECLARE_TOOL_FACTORY(METSoftTermsTool) +DECLARE_TOOL_FACTORY(METElectronAssociator) +DECLARE_TOOL_FACTORY(METPhotonAssociator) +DECLARE_TOOL_FACTORY(METJetAssocTool) +DECLARE_TOOL_FACTORY(METTauAssociator) +DECLARE_TOOL_FACTORY(METMuonAssociator) +DECLARE_TOOL_FACTORY(METSoftAssociator) // DECLARE_TOOL_FACTORY(METTruthTool) DECLARE_TOOL_FACTORY(METCaloRegionsTool) @@ -42,6 +57,7 @@ DECLARE_TOOL_FACTORY(METRegionsTool) // DECLARE_ALGORITHM_FACTORY(METRecoAlg) DECLARE_ALGORITHM_FACTORY(METReaderAlg) +DECLARE_ALGORITHM_FACTORY(METAssocAlg) DECLARE_FACTORY_ENTRIES(METReconstruction) { DECLARE_TOOL(METRecoTool) @@ -51,6 +67,13 @@ DECLARE_FACTORY_ENTRIES(METReconstruction) { DECLARE_TOOL(METTauTool) DECLARE_TOOL(METMuonTool) DECLARE_TOOL(METSoftTermsTool) + DECLARE_TOOL(METAssociationTool) + DECLARE_TOOL(METElectronAssociator) + DECLARE_TOOL(METPhotonAssociator) + DECLARE_TOOL(METJetAssocTool) + DECLARE_TOOL(METTauAssociator) + DECLARE_TOOL(METMuonAssociator) + DECLARE_TOOL(METSoftAssociator) // DECLARE_TOOL(METTruthTool) DECLARE_TOOL(METCaloRegionsTool) @@ -62,4 +85,5 @@ DECLARE_FACTORY_ENTRIES(METReconstruction) { // DECLARE_ALGORITHM(METRecoAlg) DECLARE_ALGORITHM(METReaderAlg) + DECLARE_ALGORITHM(METAssocAlg) }