diff --git a/Reconstruction/MET/METInterface/METInterface/IMETMaker.h b/Reconstruction/MET/METInterface/METInterface/IMETMaker.h index 70b147082fb0e94fc965741f0152f42d781f6447..b59525fcfef80a7267099627b677987832f0ce16 100644 --- a/Reconstruction/MET/METInterface/METInterface/IMETMaker.h +++ b/Reconstruction/MET/METInterface/METInterface/IMETMaker.h @@ -22,6 +22,10 @@ #include "xAODMissingET/MissingETContainer.h" #include "xAODMissingET/MissingETAssociationMap.h" #include "xAODJet/JetContainer.h" +#include "xAODPFlow/PFOContainer.h" +#include "StoreGate/DataHandle.h" +#include "StoreGate/WriteHandle.h" + class IMETMaker : virtual public asg::IAsgTool { ASG_TOOL_INTERFACE(IMETMaker) @@ -102,10 +106,33 @@ public: const xAOD::MissingET* coreSoftTrk, bool doJetJVT) = 0; + /////////////////////////////////////////////////////////////////// // Additional utility commands /////////////////////////////////////////////////////////////////// + virtual StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0) = 0;//, + //MissingETBase::UsageHandler::Policy p); //jetOR + + virtual StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0) = 0;//, + //MissingETBase::UsageHandler::Policy p); //jetOR + + virtual const xAOD::PFOContainer* retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals, + xAOD::MissingETAssociationHelper* helper, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0, + MissingETBase::UsageHandler::Policy p=MissingETBase::UsageHandler::ParticleFlow) = 0; //jetOR + virtual StatusCode markInvisible(const xAOD::IParticleContainer* collection, xAOD::MissingETAssociationHelper* helper, xAOD::MissingETContainer* metCont) = 0; diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h index a5639d0d599470e231a553160bd0559a13b7342a..d13ea9e1474606045d63eaa768e944f83cc793fd 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h @@ -19,6 +19,8 @@ #include "METRecoInterface/METRecoCommon.h" #include "xAODEgamma/EgammaFwd.h" +#include "StoreGate/ReadDecorHandle.h" + #include <set> namespace met{ @@ -64,10 +66,21 @@ namespace met{ const met::METAssociator::ConstitHolder& constits, std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; + StatusCode extractPFOsFromLinks(const xAOD::Egamma* eg, + std::vector<const xAOD::IParticle*>& pfolist, + const met::METAssociator::ConstitHolder& constits) const; + + + StatusCode extractPFOs(const xAOD::Egamma* eg, + std::vector<const xAOD::IParticle*>& pfolist, + const met::METAssociator::ConstitHolder& constits) const; + + StatusCode extractFE(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& felist, const met::METAssociator::ConstitHolder& constits, - std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; + std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; //TODO: split in extractFEsFromLinks and extractFEs, similarly to PFOs, to use links + StatusCode extractTracks(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& constlist, @@ -80,6 +93,8 @@ namespace met{ StatusCode selectEgammaTracks(const xAOD::Egamma* el, const xAOD::TrackParticleContainer* trkCont, std::set<const xAOD::TrackParticle*>& tracklist) const; + + bool hasUnmatchedClusters(const xAOD::Egamma* eg, const xAOD::PFO* pfo) const; double m_tcMatch_dR; double m_tcMatch_maxRat; @@ -87,6 +102,23 @@ namespace met{ double m_extraTrkMatch_dR; + SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronNeutralPFOReadDecorKey; + SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronChargedPFOReadDecorKey; + SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonNeutralPFOReadDecorKey; + SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonChargedPFOReadDecorKey; + + SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronNeutralFEReadDecorKey; + SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronChargedFEReadDecorKey; + SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonNeutralFEReadDecorKey; + SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonChargedFEReadDecorKey; + + + bool m_usePFOElectronLinks; + bool m_usePFOPhotonLinks; + bool m_useFEElectronLinks; + bool m_useFEPhotonLinks; + bool m_checkUnmatched; + private: /// Default constructor: @@ -97,3 +129,4 @@ namespace met{ } #endif //> !METRECONSTRUCTION_METEGAMMAASSOCIATOR_H + diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h index 60cacc269128f24f2a4ac90091dcaf762f9f36bd..e49e701036a2a052ed90841fa122f6279f6968d1 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h @@ -71,6 +71,9 @@ namespace met{ private: bool m_doMuonClusterMatch; + SG::ReadDecorHandleKey<xAOD::MuonContainer> m_muonNeutralFEReadDecorKey; + SG::ReadDecorHandleKey<xAOD::MuonContainer> m_muonChargedFEReadDecorKey; + bool m_useFEMuonLinks; /// Default constructor: METMuonAssociator(); diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h index 1a41e1a510d5f0ac56545b68af8ec7658e0362fb..3eb54813bafdb21a6f0093e7f4b9144e6229edf3 100644 --- a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h +++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h @@ -67,7 +67,7 @@ namespace met{ StatusCode extractFE(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& felist, const met::METAssociator::ConstitHolder& constits, - std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; + std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links StatusCode extractTracks(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& constlist, @@ -78,6 +78,9 @@ namespace met{ /// Default constructor: METTauAssociator(); SG::ReadHandleKey<xAOD::TauJetContainer> m_tauContKey; + SG::ReadDecorHandleKey<xAOD::TauJetContainer> m_tauNeutralFEReadDecorKey; + SG::ReadDecorHandleKey<xAOD::TauJetContainer> m_tauChargedFEReadDecorKey; + bool m_useFETauLinks; }; diff --git a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx index 92f077f6ae757949ed488e2e346c68a7ef442b9e..ffbd514512c32d0909f490e581560adc0502ce4f 100644 --- a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx @@ -26,6 +26,11 @@ // DeltaR calculation #include "FourMomUtils/xAODP4Helpers.h" +typedef ElementLink<xAOD::ElectronContainer> ElectronLink_t; +typedef ElementLink<xAOD::PhotonContainer> PhotonLink_t; +typedef ElementLink<xAOD::PFOContainer> PFOLink_t; +typedef ElementLink<xAOD::FlowElementContainer> FELink_t; + namespace met { using namespace xAOD; @@ -44,6 +49,21 @@ namespace met { declareProperty( "TCMatchDeltaR", m_tcMatch_dR = 0.1 ); declareProperty( "ExtraTrackMatchDeltaR", m_extraTrkMatch_dR = 0.05 ); + + declareProperty( "ElectronNeutralPFOReadDecorKey", m_electronNeutralPFOReadDecorKey = "Electrons.neutralpfoLinks" ); + declareProperty( "ElectronChargedPFOReadDecorKey", m_electronChargedPFOReadDecorKey = "Electrons.chargedpfoLinks" ); + declareProperty( "PhotonNeutralPFOReadDecorKey", m_photonNeutralPFOReadDecorKey = "Photon.neutralpfoLinks" ); + declareProperty( "PhotonChargedPFOReadDecorKey", m_photonChargedPFOReadDecorKey = "Photon.chargedpfoLinks" ); + declareProperty( "ElectronNeutralFEReadDecorKey", m_electronNeutralFEReadDecorKey = "Electrons.neutralFELinks" ); + declareProperty( "ElectronChargedFEReadDecorKey", m_electronChargedFEReadDecorKey = "Electrons.chargedFELinks" ); + declareProperty( "PhotonNeutralFEReadDecorKey", m_photonNeutralFEReadDecorKey = "Photon.neutralFELinks" ); + declareProperty( "PhotonChargedFEReadDecorKey", m_photonChargedFEReadDecorKey = "Photon.chargedFELinks" ); + + declareProperty( "UsePFOElectronLinks", m_usePFOElectronLinks = false ); + declareProperty( "UsePFOPhotonLinks", m_usePFOPhotonLinks = false); + declareProperty( "UseFEElectronLinks", m_useFEElectronLinks = false ); + declareProperty( "UseFEPhotonLinks", m_useFEPhotonLinks = false); + declareProperty( "CheckUnmatched", m_checkUnmatched = false); } // Destructor @@ -64,6 +84,16 @@ namespace met { ATH_MSG_WARNING( "Invalid topocluster match method configured!" ); return StatusCode::FAILURE; } + + ATH_CHECK(m_electronNeutralPFOReadDecorKey.initialize()); + ATH_CHECK(m_electronChargedPFOReadDecorKey.initialize()); + ATH_CHECK(m_photonNeutralPFOReadDecorKey.initialize()); + ATH_CHECK(m_photonChargedPFOReadDecorKey.initialize()); + ATH_CHECK(m_electronNeutralFEReadDecorKey.initialize()); + ATH_CHECK(m_electronChargedFEReadDecorKey.initialize()); + ATH_CHECK(m_photonNeutralFEReadDecorKey.initialize()); + ATH_CHECK(m_photonChargedFEReadDecorKey.initialize()); + return StatusCode::SUCCESS; } @@ -151,9 +181,88 @@ namespace met { std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const { const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(obj); + + if ((m_usePFOElectronLinks && eg->type() == xAOD::Type::Electron) || (m_usePFOPhotonLinks && eg->type() == xAOD::Type::Photon)) { + ATH_CHECK( extractPFOsFromLinks(eg, pfolist,constits) ); + } + else { + ATH_CHECK( extractPFOs(eg, pfolist, constits) ); + } + + return StatusCode::SUCCESS; + } + + StatusCode METEgammaAssociator::extractPFOsFromLinks(const xAOD::Egamma* eg, + std::vector<const xAOD::IParticle*>& pfolist, + const met::METAssociator::ConstitHolder& constits) const + { + + ATH_MSG_VERBOSE("Extract PFOs From Links for " << eg->type() << " with pT " << eg->pt()); + + SG::ReadDecorHandle<xAOD::ElectronContainer, std::vector<PFOLink_t> > electronNeutralPFOReadDecorHandle (m_electronNeutralPFOReadDecorKey); + SG::ReadDecorHandle<xAOD::ElectronContainer, std::vector<PFOLink_t> > electronChargedPFOReadDecorHandle (m_electronChargedPFOReadDecorKey); + SG::ReadDecorHandle<xAOD::PhotonContainer, std::vector<PFOLink_t> > photonNeutralPFOReadDecorHandle (m_photonNeutralPFOReadDecorKey); + SG::ReadDecorHandle<xAOD::PhotonContainer, std::vector<PFOLink_t> > photonChargedPFOReadDecorHandle (m_photonChargedPFOReadDecorKey); + + const std::vector<PFOLink_t> nPFOLinks = (eg->type() == xAOD::Type::Electron)? electronNeutralPFOReadDecorHandle (*eg) : photonNeutralPFOReadDecorHandle (*eg); + const std::vector<PFOLink_t> cPFOLinks = (eg->type() == xAOD::Type::Electron)? electronChargedPFOReadDecorHandle (*eg) : photonChargedPFOReadDecorHandle (*eg); + + + // Charged PFOs + for (PFOLink_t pfoLink : cPFOLinks) { + if (pfoLink.isValid()){ + const xAOD::PFO* pfo_init = *pfoLink; + for (const auto& pfo : *constits.pfoCont){ + if (pfo->index() == pfo_init->index() && pfo->isCharged()){ //index-based match between JetETmiss and CHSParticleFlow collections + const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV"); + if( pfo->isCharged() && PVMatchedAcc(*pfo)&& ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) ) { + ATH_MSG_DEBUG("Accept cPFO with pt " << pfo->pt() << ", e " << pfo->e() << ", eta " << pfo->eta() << ", phi " << pfo->phi() ); + if (!m_checkUnmatched) {pfolist.push_back(pfo);} + else { + bool has_unmatched=hasUnmatchedClusters(eg,pfo_init); + if (!has_unmatched) {pfolist.push_back(pfo);} + } + } + } + } + } + } // end cPFO loop + + // Neutral PFOs + double eg_cl_e = eg->caloCluster()->e(); + double sumE_pfo = 0.; + + for (PFOLink_t pfoLink : nPFOLinks) { + if (pfoLink.isValid()){ + const xAOD::PFO* pfo_init = *pfoLink; + for (const auto& pfo : *constits.pfoCont){ + if (pfo->index() == pfo_init->index() && !pfo->isCharged()){ //index-based match between JetETmiss and CHSParticleFlow collections + double pfo_e = pfo->eEM(); + if( ( !pfo->isCharged()&& pfo->e() > FLT_MIN ) ){ + sumE_pfo += pfo_e; + ATH_MSG_DEBUG("E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e); + ATH_MSG_DEBUG("Accept nPFO with pt " << pfo->pt() << ", e " << pfo->e() << ", eta " << pfo->eta() << ", phi " << pfo->phi() << " in sum."); + ATH_MSG_DEBUG("Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e); + pfolist.push_back(pfo); + } + } + } + } + } // end nPFO links loop + + + return StatusCode::SUCCESS; + } + + StatusCode METEgammaAssociator::extractPFOs(const xAOD::Egamma* eg, + std::vector<const xAOD::IParticle*>& pfolist, + const met::METAssociator::ConstitHolder& constits) const + + { // safe to assume a single SW cluster? // will do so for now... const xAOD::IParticle* swclus = eg->caloCluster(); + ANA_MSG_INFO("Extract PFOs with DeltaR for " << eg->type() << " with pT " << eg->pt()); // Preselect PFOs based on proximity: dR<0.4 std::vector<const xAOD::PFO*> nearbyPFO; @@ -223,6 +332,9 @@ namespace met { return StatusCode::SUCCESS; } + + // TODO: split in extractFEsFromLinks and extractFEs, similarly to PFOs, to use links + StatusCode METEgammaAssociator::extractFE(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& felist, const met::METAssociator::ConstitHolder& constits, @@ -405,4 +517,69 @@ namespace met { return StatusCode::SUCCESS; } + + bool METEgammaAssociator::hasUnmatchedClusters(const xAOD::Egamma* eg, const xAOD::PFO* pfo) const{ + + bool has_unmatched=false; + float totSumpt=0; + float unmatchedSumpt=0; + float unmatchedE=0; + float unmatchedTotEMFrac=0; + double emfrac=0; + + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFrac("unmatchedFrac"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracSumpt("unmatchedFracSumpt"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracPt("unmatchedFracPt"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracE("unmatchedFracE"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracEClusterPFO("unmatchedFracEClusterPFO"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracPtClusterPFO("unmatchedFracPtClusterPFO"); + static SG::AuxElement::Decorator<Float_t> dec_unmatchedTotEMFrac("unmatchedTotEMFrac"); + + TLorentzVector totVec(0.,0.,0.,0.), unmatchedVec(0.,0.,0.,0.); + const std::vector<const xAOD::CaloCluster*> egClusters = xAOD::EgammaHelpers::getAssociatedTopoClusters(eg->caloCluster()); + std::set<const xAOD::CaloCluster*> cPFOClusters; + int nCluscPFO = pfo->nCaloCluster(); + + for (int cl = 0; cl < nCluscPFO; ++cl) { + if (pfo->cluster(cl)) cPFOClusters.insert( pfo->cluster(cl) ); + } + + std::vector<const xAOD::CaloCluster*> unmatchedClusters; + for (const xAOD::CaloCluster* pfoclus : cPFOClusters) { + TLorentzVector tmpVec; + tmpVec.SetPtEtaPhiE(pfoclus->pt(),pfoclus->eta(),pfoclus->phi(),pfoclus->e()); + totSumpt+=pfoclus->pt(); + totVec+=tmpVec; + bool inEgamma = false; + for (const xAOD::CaloCluster* phclus : egClusters) { + if (pfoclus == phclus) { + inEgamma = true; + } + } + if (!inEgamma) { + unmatchedClusters.push_back(pfoclus); + unmatchedSumpt+=pfoclus->pt(); + unmatchedE+=pfoclus->e(); + unmatchedVec+=tmpVec; + pfoclus->retrieveMoment(xAOD::CaloCluster::ENG_FRAC_EM ,emfrac); + unmatchedTotEMFrac=unmatchedTotEMFrac+emfrac*pfoclus->e(); + } + + } + + ATH_MSG_DEBUG("PFO associated to "<<nCluscPFO<< " cluster, of which " << unmatchedClusters.size() << "unmatched one and unmatched pt "<<unmatchedSumpt); + dec_unmatchedFrac(*pfo)=nCluscPFO>0 ? float(unmatchedClusters.size())/float(nCluscPFO) : -1; + dec_unmatchedFracPt(*pfo)= totVec.Pt()>0 ? float(unmatchedVec.Pt()/totVec.Pt()): -1; + dec_unmatchedFracSumpt(*pfo)= totSumpt>0 ? float(unmatchedSumpt/totSumpt): -1; + dec_unmatchedFracE(*pfo)= totVec.E()>0 ? float(unmatchedE/totVec.E()): -1; + dec_unmatchedTotEMFrac(*pfo)= totVec.E()>0 ? float(unmatchedTotEMFrac/totVec.E()): -1; + dec_unmatchedFracEClusterPFO(*pfo)= pfo->e()>0 ? float(unmatchedE/pfo->e()): -1; + dec_unmatchedFracPtClusterPFO(*pfo)= pfo->pt()>0 ? float(unmatchedE/pfo->pt()): -1; + + return has_unmatched; + } + + + } + diff --git a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx index 7d00b4456544d38828796d906a5840303b07d4ec..9ca70fe45eb295f2463a9ba74fbdc2a2eedf457d 100644 --- a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx @@ -22,6 +22,10 @@ // Tracking EDM #include "xAODTracking/Vertex.h" + +typedef ElementLink<xAOD::MuonContainer> MuonLink_t; +typedef ElementLink<xAOD::FlowElementContainer> FELink_t; + namespace met { using namespace xAOD; @@ -36,6 +40,9 @@ namespace met { { declareProperty("DoClusterMatch", m_doMuonClusterMatch=true); declareProperty("MuonKey",m_muContKey); + declareProperty( "MuonNeutralFEReadDecorKey", m_muonNeutralFEReadDecorKey = "Muons.neutralFELinks" ); + declareProperty( "MuonChargedFEReadDecorKey", m_muonChargedFEReadDecorKey = "Muons.chargedFELinks" ); + declareProperty( "UseFEMuonLinks", m_useFEMuonLinks = false ); } // Destructor @@ -51,6 +58,10 @@ namespace met { ATH_MSG_VERBOSE ("Initializing " << name() << "..."); ATH_CHECK( m_muContKey.assign(m_input_data_key)); ATH_CHECK( m_muContKey.initialize()); + + ATH_CHECK(m_muonNeutralFEReadDecorKey.initialize()); + ATH_CHECK(m_muonChargedFEReadDecorKey.initialize()); + if (m_doMuonClusterMatch) { ATH_CHECK(m_elementLinkName.initialize()); } @@ -213,6 +224,8 @@ namespace met { return StatusCode::SUCCESS; } + // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links + StatusCode METMuonAssociator::extractFE(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& felist, const met::METAssociator::ConstitHolder& constits, diff --git a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx index d5b0abf104c5dbecc541e92038ef20fd49f1e566..17f8a27646403f7b19f6f403181abb6b1b4b114f 100644 --- a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx +++ b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx @@ -33,6 +33,10 @@ #include "xAODCaloEvent/CaloVertexedTopoCluster.h" #include "PFlowUtils/IWeightPFOTool.h" + +typedef ElementLink<xAOD::TauJetContainer> TauLink_t; +typedef ElementLink<xAOD::FlowElementContainer> FELink_t; + namespace met { using namespace xAOD; @@ -45,6 +49,9 @@ namespace met { m_tauContKey("") { declareProperty("tauContainer",m_tauContKey); + declareProperty( "TauNeutralFEReadDecorKey", m_tauNeutralFEReadDecorKey = "TauJets.neutralFELinks" ); + declareProperty( "TauChargedFEReadDecorKey", m_tauChargedFEReadDecorKey = "TauJets.chargedFELinks" ); + declareProperty( "UseFETauLinks", m_useFETauLinks = false ); //? } // Destructor @@ -61,6 +68,9 @@ namespace met { ATH_CHECK( m_tauContKey.assign(m_input_data_key)); ATH_CHECK( m_tauContKey.initialize()); + ATH_CHECK(m_tauNeutralFEReadDecorKey.initialize()); + ATH_CHECK(m_tauChargedFEReadDecorKey.initialize()); + return StatusCode::SUCCESS; } @@ -187,6 +197,7 @@ namespace met { return StatusCode::SUCCESS; } + // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links StatusCode METTauAssociator::extractFE(const xAOD::IParticle* obj, std::vector<const xAOD::IParticle*>& felist, const met::METAssociator::ConstitHolder& constits, diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py index 6f2972858f92f1534b1ce2b0f9911e4a3d50f75d..c0d0e3aab1da58c946bff51a7ad35c022439ed0a 100644 --- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py +++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py @@ -2,7 +2,9 @@ from __future__ import print_function from AthenaCommon import CfgMgr + from GaudiKernel.Constants import INFO + import six ################################################################################# @@ -16,12 +18,14 @@ defaultInputKey = { 'EMJet' :'AntiKt4EMTopoJets', 'PFlowJet' :'AntiKt4EMPFlowJets', 'PFlowFEJet':'AntiKt4EMPFlowFEJets', + 'ORPFlowJet':'AntiKt4OverlapRemovedEMPFlowJets', 'Muon' :'Muons', 'Soft' :'', 'Clusters' :'CaloCalTopoClusters', 'Tracks' :'InDetTrackParticles', 'PFlowObj' :'CHSParticleFlowObjects', 'PFlowObjFE':'CHSFlowElements', + 'ORPFlowObj':'OverlapRemovedCHSParticleFlowObjects', 'PrimVxColl':'PrimaryVertices', 'Truth' :'TruthEvents', } @@ -36,7 +40,9 @@ class AssocConfig: self.objType = objType self.inputKey = inputKey -def getAssociator(config,suffix,doPFlow=False, +def getAssociator(config,suffix,doPFlow=False,usePFOElectronLinks=False,usePFOPhotonLinks=False, + useFEElectronLinks=False,useFEPhotonLinks=False, + useFEMuonLinks=False,useFETauLinks=False, trkseltool=None,trkisotool=None,caloisotool=None, modConstKey="", modClusColls={}): @@ -44,31 +50,49 @@ def getAssociator(config,suffix,doPFlow=False, import cppyy cppyy.include("METRecoInterface/METRecoCommon.h") - + doModClus = (modConstKey!="" and not doPFlow) if doModClus: modLCClus = modClusColls['LC{0}Clusters'.format(modConstKey)] modEMClus = modClusColls['EM{0}Clusters'.format(modConstKey)] - # Construct tool and set defaults for case-specific configuration if config.objType == 'Ele': from ROOT import met tool = CfgMgr.met__METElectronAssociator('MET_ElectronAssociator_'+suffix,TCMatchMethod=met.ClusterLink) + #tool.OutputLevel=VERBOSE + if usePFOElectronLinks: + tool.UsePFOElectronLinks = True + if useFEElectronLinks: + tool.UseFEElectronLinks = True + + if config.objType == 'Gamma': + from ROOT import met tool = CfgMgr.met__METPhotonAssociator('MET_PhotonAssociator_'+suffix,TCMatchMethod=met.ClusterLink) + + if usePFOPhotonLinks: + tool.UsePFOPhotonLinks = True + if useFEPhotonLinks: + tool.UseFEPhotonLinks = True + if config.objType == 'Tau': tool = CfgMgr.met__METTauAssociator('MET_TauAssociator_'+suffix) + if useFETauLinks: + tool.UseFETauLinks = True 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 == 'PFlowFEJet': - tool = CfgMgr.met__METJetAssocTool('MET_PFlowFEJetAssocTool_'+suffix) + if config.objType == 'ORPFlowJet': + tool = CfgMgr.met__METJetAssocTool('MET_OverlapRemovedPFlowJetAssocTool_'+suffix) if config.objType == 'Muon': tool = CfgMgr.met__METMuonAssociator('MET_MuonAssociator_'+suffix) + if useFEMuonLinks: + tool.UseFEMuonLinks = True + #tool.OutputLevel=VERBOSE if config.objType == 'Soft': tool = CfgMgr.met__METSoftAssociator('MET_SoftAssociator_'+suffix) tool.DecorateSoftConst = True @@ -79,13 +103,16 @@ def getAssociator(config,suffix,doPFlow=False, tool = CfgMgr.met__METTruthAssociator('MET_TruthAssociator_'+suffix) tool.RecoJetKey = config.inputKey + + + from METReconstruction.METRecoFlags import metFlags if doPFlow: tool.PFlow = True if metFlags.UseFlowElements() : tool.FlowElementCollection = modConstKey if modConstKey!="" else defaultInputKey["PFlowObjFE"] else: - tool.PFlowColl = modConstKey if modConstKey!="" else defaultInputKey["PFlowObj"] + tool.PFlowColl = modConstKey if modConstKey!="" else (defaultInputKey["PFlowObj"] if suffix!='AntiKt4OverlapRemovedEMPFlow' else defaultInputKey["ORPFlowObj"]) else: tool.UseModifiedClus = doModClus # set input/output key names @@ -107,8 +134,6 @@ def getAssociator(config,suffix,doPFlow=False, tool.TrackIsolationTool = trkisotool tool.CaloIsolationTool = caloisotool - #if not hasattr(ToolSvc,tool.name()): - # ToolSvc += tool return tool ################################################################################# @@ -132,6 +157,12 @@ class METAssocConfig: else: associator = getAssociator(config=config,suffix=self.suffix, doPFlow=self.doPFlow, + usePFOElectronLinks=self.usePFOElectronLinks, + usePFOPhotonLinks=self.usePFOPhotonLinks, + useFEElectronLinks=self.useFEElectronLinks, + useFEPhotonLinks=self.useFEPhotonLinks, + useFEMuonLinks=self.useFEMuonLinks, + useFETauLinks=self.useFETauLinks, trkseltool=self.trkseltool, trkisotool=self.trkisotool, caloisotool=self.caloisotool, @@ -147,6 +178,12 @@ class METAssocConfig: # def __init__(self,suffix,buildconfigs=[], doPFlow=False,doTruth=False, + usePFOElectronLinks=False, + usePFOPhotonLinks=False, + useFEElectronLinks=False, + useFEPhotonLinks=False, + useFEMuonLinks=False, + useFETauLinks=False, trksel=None, modConstKey="", modClusColls={} @@ -159,7 +196,7 @@ class METAssocConfig: if metFlags.UseFlowElements(): if modConstKey_tmp == "": modConstKey_tmp = "CHSFlowElements" else: - if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects" + if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects" if 'OverlapRemoved' not in suffix else "OverlapRemovedCHSParticleFlowObjects" else: if modConstKey_tmp == "": modConstKey_tmp = "OriginCorr" if modClusColls_tmp == {}: modClusColls_tmp = {'LCOriginCorrClusters':'LCOriginTopoClusters', @@ -169,11 +206,16 @@ class METAssocConfig: else: print (prefix, 'Creating MET Assoc config \''+suffix+'\'') self.suffix = suffix - self.doPFlow = doPFlow + self.doPFlow = doPFlow + self.usePFOElectronLinks = usePFOElectronLinks + self.usePFOPhotonLinks = usePFOPhotonLinks + self.useFEElectronLinks = useFEElectronLinks + self.useFEPhotonLinks = useFEPhotonLinks + self.useFEMuonLinks = useFEMuonLinks + self.useFETauLinks = useFETauLinks self.modConstKey=modConstKey_tmp self.modClusColls=modClusColls_tmp self.doTruth = doTruth - if trksel: self.trkseltool = trksel else: @@ -233,11 +275,11 @@ def getMETAssocAlg(algName='METAssociation',configs={},tools=[],msglvl=INFO): from METReconstruction.METRecoFlags import metFlags if configs=={} and tools==[]: - print( prefix, 'Taking configurations from METRecoFlags') + print (prefix, 'Taking configurations from METRecoFlags') configs = metFlags.METAssocConfigs() - print(configs) + print (configs) for key,conf in six.iteritems(configs): - print( prefix, 'Generate METAssocTool for MET_'+key) + print (prefix, 'Generate METAssocTool for MET_'+key) assoctool = getMETAssocTool(conf,msglvl) assocTools.append(assoctool) metFlags.METAssocTools()[key] = assoctool @@ -249,3 +291,4 @@ def getMETAssocAlg(algName='METAssociation',configs={},tools=[],msglvl=INFO): RecoTools=assocTools) # assocAlg.OutputLevel=DEBUG return assocAlg + diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py index de6c00f8784d0b986e836194e497096bee7197b4..1e9e4cab872e31a85c1589130102f391c20dd208 100644 --- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py +++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py @@ -65,7 +65,9 @@ if metFlags.DoPFlow() and metFlags.UseTracks(): AssocConfig('Soft')] cfg_akt4pf = METAssocConfig('AntiKt4EMPFlow', associators, - doPFlow=True + doPFlow=True, + usePFOElectronLinks=metFlags.UsePFOElectronLinks(), + usePFOPhotonLinks=metFlags.UsePFOPhotonLinks() ) metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf @@ -85,8 +87,13 @@ if metFlags.DoPFlow() and metFlags.UseTracks() and metFlags.UseFlowElements(): AssocConfig('Soft')] cfg_akt4pffe = METAssocConfig('AntiKt4EMPFlowFE', associators, - doPFlow=True + doPFlow=True, + useFEElectronLinks=metFlags.UseFEElectronLinks(), + useFEPhotonLinks=metFlags.UseFEPhotonLinks(), + useFEMuonLinks=metFlags.UseFEMuonLinks(), + useFETauLinks=metFlags.UseFETauLinks() ) metFlags.METAssocConfigs()[cfg_akt4pffe.suffix] = cfg_akt4pffe - metFlags.METAssocOutputList().append(cfg_akt4pffe.suffix) \ No newline at end of file + metFlags.METAssocOutputList().append(cfg_akt4pffe.suffix) + diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py index 99b0482d4042531a1c7f1e61341f2d525ecb9e5d..e22f3ac90551871efba9c5e14ba922e0cab8cb6d 100644 --- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py +++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py @@ -66,10 +66,54 @@ class METAssocOutputList(JobProperty): allowedTypes = ['list'] StoredValue = [] +class UsePFOElectronLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class UsePFOPhotonLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class UseFEElectronLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class UseFEPhotonLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class UseFETauLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class UseFEMuonLinks(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + +class DoORMet(JobProperty): + statusOn = True + allowedTypes = ['bool'] + StoredValue = False + + + jobproperties.add_Container(METRecoFlags) jobproperties.METRecoFlags.add_JobProperty(DoRegions) jobproperties.METRecoFlags.add_JobProperty(DoPFlow) +jobproperties.METRecoFlags.add_JobProperty(UsePFOElectronLinks) +jobproperties.METRecoFlags.add_JobProperty(UsePFOPhotonLinks) +jobproperties.METRecoFlags.add_JobProperty(UseFEElectronLinks) +jobproperties.METRecoFlags.add_JobProperty(UseFEPhotonLinks) +jobproperties.METRecoFlags.add_JobProperty(UseFETauLinks) +jobproperties.METRecoFlags.add_JobProperty(UseFEMuonLinks) +jobproperties.METRecoFlags.add_JobProperty(DoORMet) jobproperties.METRecoFlags.add_JobProperty(UseFlowElements) jobproperties.METRecoFlags.add_JobProperty(UseTracks) jobproperties.METRecoFlags.add_JobProperty(DecorateSoftConst) @@ -82,3 +126,4 @@ jobproperties.METRecoFlags.add_JobProperty(METAssocOutputList) jobproperties.METRecoFlags.add_JobProperty(METAssocTools) metFlags = jobproperties.METRecoFlags + diff --git a/Reconstruction/MET/METReconstruction/share/RunORMETReco.py b/Reconstruction/MET/METReconstruction/share/RunORMETReco.py new file mode 100644 index 0000000000000000000000000000000000000000..df8308ca13381e48d6386c55b08d72699d1a2143 --- /dev/null +++ b/Reconstruction/MET/METReconstruction/share/RunORMETReco.py @@ -0,0 +1,197 @@ +from AthenaCommon import Logging +log = Logging.logging.getLogger('run_fromAOD.py') + +from AthenaCommon.AthenaCommonFlags import athenaCommonFlags +athenaCommonFlags.FilesInput=[""] + +theApp.EvtMax = -1 + +import AthenaPoolCnvSvc.ReadAthenaPool +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() + +electronPT = 10000 +muonPT = 10000 +photonPT = 10000 +electronWP = "Medium" +muonWP = 1 +photonWP = "Tight" +electronETA = 2.47 +muonETA = 2.7 +photonETA = 2.47 +soft = "Clus" +metWP = "PFlow" + +usePFOElectronLinks = True +usePFOPhotonLinks = True +retainMuon = True + +############################################################################ +# Set up detector description +from AthenaCommon.GlobalFlags import globalflags +from IOVDbSvc.CondDB import conddb +if len(globalflags.ConditionsTag())!=0: + conddb.setGlobalTag(globalflags.ConditionsTag()) +include("RecExCond/AllDet_detDescr.py") + +############################################################################ +# MET reco and extract OR PFOs + +include("eflowRec/jetAlgs.py") # std jet reco (AntiKt4EMPFlowJets) + +from METReconstruction.METRecoFlags import jobproperties, metFlags +metFlags.UsePFOElectronLinks=usePFOElectronLinks +metFlags.UsePFOPhotonLinks=usePFOPhotonLinks +metFlags.DoORMet = False # used by ORMETAssoc.py + +include("METUtilities/ORMETAssoc.py") + +# doRetrieveORconstit = True to extract OR PFOs collection +# retainMuonConstit = True to include constituents associated to overlapping muons in OR PFOs collection +# (needed to recover standard muon-jet overlap removal) +# doORMet = True for OR MET reco + +from METUtilities.ORMETMakerConfig import getMETMakerAlg +makerAlg = getMETMakerAlg("AntiKt4EMPFlow", jetSelection=metWP, doRetrieveORconstit = True,retainMuonConstit = retainMuon, doORMet=False, muonID=muonWP, electronID=electronWP, photonID=photonWP) +makerAlg.ElectronPT = electronPT; +makerAlg.MuonPT = muonPT; +makerAlg.PhotonPT = photonPT +makerAlg.ElectronETA = electronETA; +makerAlg.MuonETA = muonETA; +makerAlg.PhotonETA = photonETA; +makerAlg.Soft = soft +makerAlg.OutputLevel = DEBUG +topSequence += makerAlg +metFlags.METOutputList().append("AntiKt4EMPFlow") + +############################################################################ +# OR MET reco + +include("METUtilities/ORjetReco.py") # OR jets reco (AntiKt4OverlapRemovedEMPFlowJets) + +from METReconstruction.METRecoFlags import jobproperties, metFlags +metFlags.UsePFOElectronLinks=usePFOElectronLinks +metFlags.UsePFOPhotonLinks=usePFOPhotonLinks +metFlags.DoORMet = True #used by ORMETAssoc.py + +include("METUtilities/ORMETAssoc.py") + +# doRetrieveORconstit = True to extract OR PFOs collection +# retainMuonConstit = True to include constituents associated to overlapping muons in OR PFOs collection +# (needed to recover standard muon-jet overlap removal) +# doORMet = True for OR MET reco + +from METUtilities.ORMETMakerConfig import getMETMakerAlg +makerAlg = getMETMakerAlg("AntiKt4OverlapRemovedEMPFlow", jetSelection=metWP, doRetrieveORconstit = False, retainMuonConstit = retainMuon, doORMet=True, muonID=muonWP, electronID=electronWP, photonID=photonWP) +makerAlg.ElectronPT = electronPT; +makerAlg.MuonPT = muonPT; +makerAlg.PhotonPT = photonPT +makerAlg.ElectronETA = electronETA; +makerAlg.MuonETA = muonETA; +makerAlg.PhotonETA = photonETA; +makerAlg.Soft = soft +makerAlg.OutputLevel = DEBUG +topSequence += makerAlg +metFlags.METOutputList().append("AntiKt4OverlapRemovedEMPFlow") + +log.warning('AssocOutputLists: %s', metFlags.METAssocOutputList()) +log.warning('OutputLists: %s', metFlags.METOutputList()) +include("METReconstruction/METReconstructionOutputAODList_jobOptions.py") + +############################################################################ + +from OutputStreamAthenaPool.MultipleStreamManager import MSMgr +xaodStream = MSMgr.NewStream( "StreamAOD" ) +xaodStream.AddItem("xAOD::JetContainer#AntiKt4OverlapRemovedEMPFlowJets") +xaodStream.AddItem("xAOD::JetAuxContainer#AntiKt4OverlapRemovedEMPFlowJetsAux.") +xaodStream.AddItem("xAOD::JetContainer#AntiKt4EMPFlowJets") +xaodStream.AddItem("xAOD::JetAuxContainer#AntiKt4EMPFlowJetsAux.") +for met in MissingETAODList: xaodStream.AddItem(met) + + + +out_dir = "/storage_tmp/atlas/fpiazza/QT/run_analysis/test_nullEleTerm/v15/" +message = "" +sample = "Wenu" + + + +#print sample +out_file = 'met.root' #out_dir+'%s_%s_test.root' %(svcMgr.EventSelector.InputCollections[0].split("/")[9],soft) + + + + +print("outfile", out_file) + +from MCTruthClassifier.MCTruthClassifierConf import MCTruthClassifier + +BkgElectronMCTruthClassifier = MCTruthClassifier(name = "BkgElectronMCTruthClassifier", + ParticleCaloExtensionTool = "") + + + + +alg = CfgMgr.Analysis(MCTruthClassifier = BkgElectronMCTruthClassifier, RetainMuon=True) + + + +#Configuration +# alg.SelectElectrons = False; +alg.ElectronID = "LHMedium"; +alg.MuonID = "LHMedium"; +alg.PhotonID = "Tight"; +alg.ElectronPT = 10000 +alg.MuonPT = 10000; #!!! 2500 +alg.PhotonPT = 10000 +alg.ElectronETA = 2.47; +alg.MuonETA = 2.7; +alg.PhotonETA = 2.47; +alg.SoftTerm = soft +#alg.InputJets = "AntiKt4EMPflowJets" #unass +# alg.PVtxMatchingCPFOs = True; + + +alg.OutfileName = out_file; +# alg.OutfileName = "/data/jmacdonald/QT/eflowRecBugFix/histograms/Zee/" + ID + "/METHistograms_useLinks" + useMETLinks + ".root"; + +topSequence += alg + + + +#tool=CfgMgr.met__METMaker("METMaker", OutputLevel=VERBOSE,JetSelection="Expert", CustomJetJvtCut=1.0,CustomJetJvtPtMax=1000000000) + +from METUtilities.METUtilitiesConf import met__METMaker +METmakerTool=met__METMaker(OutputLevel=VERBOSE, DoPFlow=True, JetSelection="PFlow") + +from AthenaCommon.AppMgr import ToolSvc +ToolSvc += METmakerTool + +muonSel = CfgMgr.CP__MuonSelectionTool("MuonSelectionTool", + MuQuality=1, # Medium + MaxEta=2.4) +ToolSvc += muonSel + +elecSelLH = CfgMgr.AsgElectronLikelihoodTool("ElectronLHSelectionTool", + WorkingPoint="MediumLHElectron") +ToolSvc += elecSelLH + +photonSelIsEM = CfgMgr.AsgPhotonIsEMSelector("PhotonIsEMSelectionTool", + WorkingPoint="TightPhoton") +ToolSvc += photonSelIsEM + +tauSel = CfgMgr.TauAnalysisTools__TauSelectionTool("TauSelectionTool") +ToolSvc += tauSel + + +#METmakerTool.DoPFlow=False +#print METmakerTool.DoPFlow +alg.METMaker=METmakerTool +alg.MuonSelectionTool=muonSel +alg.ElectronLHSelectionTool=elecSelLH +alg.PhotonIsEMSelectionTool=photonSelIsEM +alg.TauSelectionTool=tauSel + + +ServiceMgr.MessageSvc.defaultLimit = 9999999 + diff --git a/Reconstruction/MET/METUtilities/METUtilities/METMaker.h b/Reconstruction/MET/METUtilities/METUtilities/METMaker.h index 22157ea0ba3c48234aab0aa7f1045ee1ca29a04c..95ad07a05422107e6c41c8c3550d4cd185899c43 100644 --- a/Reconstruction/MET/METUtilities/METUtilities/METMaker.h +++ b/Reconstruction/MET/METUtilities/METUtilities/METMaker.h @@ -18,12 +18,16 @@ #include "AsgDataHandles/ReadHandleKey.h" #include "AsgTools/ToolHandle.h" #include "AsgTools/AsgTool.h" +#include "StoreGate/DataHandle.h" +#include "StoreGate/ReadDecorHandle.h" // METInterface includes #include "METInterface/IMETMaker.h" // EDM includes #include "xAODJet/JetContainer.h" +#include "xAODPFlow/PFOContainer.h" + // Tracking Tool #include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h" @@ -112,6 +116,28 @@ namespace met { const xAOD::MissingETContainer* metCoreCont, xAOD::MissingETAssociationHelper* helper, bool doJetJVT); + + StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0);//, + //MissingETBase::UsageHandler::Policy p); //jetOR + + StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0); + + const xAOD::PFOContainer* retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals, + xAOD::MissingETAssociationHelper* helper, + bool retainMuon = false, + const xAOD::IParticleContainer* collection=0, + MissingETBase::UsageHandler::Policy p=MissingETBase::UsageHandler::ParticleFlow); + StatusCode rebuildTrackMET(xAOD::MissingET* metJet, const xAOD::JetContainer* jets, xAOD::MissingETAssociationHelper* helper, @@ -173,6 +199,7 @@ namespace met { bool m_greedyPhotons; bool m_veryGreedyPhotons; + ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool; /// Default constructor: METMaker(); diff --git a/Reconstruction/MET/METUtilities/Root/METMaker.cxx b/Reconstruction/MET/METUtilities/Root/METMaker.cxx index 5bb1b9e416fa70d5ebf1c157686f2b518776be5c..00b9978bef65f429b6821088b2c5a91603186b98 100644 --- a/Reconstruction/MET/METUtilities/Root/METMaker.cxx +++ b/Reconstruction/MET/METUtilities/Root/METMaker.cxx @@ -39,6 +39,9 @@ // framework includes #include "AsgDataHandles/ReadHandle.h" +#include "xAODPFlow/PFOAuxContainer.h" +#include <xAODCore/AuxContainerBase.h> +#include <AthContainers/AuxElement.h> namespace met { @@ -80,6 +83,8 @@ namespace met { // Implement dphi as well if we start correcting the jet phi. // static const SG::AuxElement::Decorator< std::vector<float> > dec_constitObjDphis("ConstitObjectDphis"); + + /////////////////////////////////////////////////////////////////// // Public methods: /////////////////////////////////////////////////////////////////// @@ -129,6 +134,7 @@ namespace met { declareProperty("DoRemoveElecTrksEM", m_doRemoveElecTrksEM = false ); declareProperty("TrackSelectorTool", m_trkseltool ); + } // Destructor @@ -589,6 +595,7 @@ namespace met { bool originalInputs = jets->empty() ? false : !acc_originalObject.isAvailable(*jets->front()); for(const auto& jet : *jets) { + const MissingETAssociation* assoc = 0; if(originalInputs) { assoc = MissingETComposition::getAssociation(map,jet); @@ -834,6 +841,7 @@ namespace met { ATH_MSG_VERBOSE( "Jet OR px, py, pt, E = " << opx << ", " << opy << ", " << opt << ", " << constjet.E() - calvec.ce() ); if(isMuFSRJet) { + if(met_muonEloss) { met_muonEloss->add(opx,opy,opt); } else { @@ -1079,6 +1087,154 @@ namespace met { return rebuildMET(met,collection,helper,MissingETBase::UsageHandler::PhysicsObject); } + + + // Retrieve non overlapping constituents //fede ? + //////////////////////////////////////// + + // Fill OverlapRemovedCHSParticleFlowObjects: view container + // and OverlapRemovedCHSCharged/NeutralParticleFlowObjects: should be writable to AODs + StatusCode METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon, + const xAOD::IParticleContainer* collection)//, + //MissingETBase::UsageHandler::Policy p); // + { + + const xAOD::PFOContainer *OR_cpfos = retrieveOverlapRemovedConstituents(cpfo, metHelper,retainMuon,collection); + const xAOD::PFOContainer *OR_npfos = retrieveOverlapRemovedConstituents(npfo, metHelper,retainMuon,collection); + + for (const auto tmp_constit : *cpfo){ + xAOD::PFO* constit=new xAOD::PFO(); + chargedPFOContainerWriteHandle->push_back(constit); + *constit=*tmp_constit; + + bool keep=false; + for (const auto ORconstit : *OR_cpfos){ + if (ORconstit->index()==tmp_constit->index() && ORconstit->charge()==tmp_constit->charge()) {keep=true;} + } + if (keep==false){constit->setP4(0., 0., 0., 0.);} + + ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << ((keep==true) ? "" : "not ") <<" in OverlapRemovedCHSParticleFlowObjects"); + } // end cPFO loop + + for (const auto tmp_constit : *npfo){ + xAOD::PFO* constit=new xAOD::PFO(); + neutralPFOContainerWriteHandle->push_back(constit); + *constit=*tmp_constit; + + bool keep=false; + for (const auto ORconstit : *OR_npfos){ + if (ORconstit->index()==tmp_constit->index() && ORconstit->charge()==tmp_constit->charge()) {keep=true;} + } + if (keep==false){constit->setP4(0., 0., 0., 0.);} + + ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << ((keep==true) ? "" : "not ") <<" in OverlapRemovedCHSParticleFlowObjects"); + } // end nPFO loop + + // Merge charged & neutral PFOs into the global view container + PFOContainerWriteHandle->assign(neutralPFOContainerWriteHandle->begin(), neutralPFOContainerWriteHandle->end()); + PFOContainerWriteHandle->insert(PFOContainerWriteHandle->end(), + chargedPFOContainerWriteHandle->begin(), + chargedPFOContainerWriteHandle->end()); + + return StatusCode::SUCCESS; + } + + + + // Fill only OverlapRemovedCHSParticleFlowObjects, view container + StatusCode METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, + xAOD::MissingETAssociationHelper* metHelper, + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle, + bool retainMuon, + const xAOD::IParticleContainer* collection) + { + const xAOD::PFOContainer *OR_pfos = retrieveOverlapRemovedConstituents(pfo, metHelper,retainMuon,collection); + *PFOContainerWriteHandle.ptr()=*OR_pfos; + + for (const auto tmp_constit : *PFOContainerWriteHandle.ptr()){ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << " in OverlapRemovedCHSParticleFlowObjects");} + + return StatusCode::SUCCESS; + } + + + + const xAOD::PFOContainer* METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals, xAOD::MissingETAssociationHelper* helper, bool retainMuon, const xAOD::IParticleContainer* collection, MissingETBase::UsageHandler::Policy p) + { + + ATH_MSG_VERBOSE("Policy " << p <<" " <<MissingETBase::UsageHandler::ParticleFlow); + const xAOD::MissingETAssociationMap* map = helper->map(); + + + // If muon is selected, flag it as non selected to retain its constituents in OR jets (to recover std. muon-jet overlap) + std::vector<size_t> muon_index; + if (retainMuon){ + bool originalInputs = !acc_originalObject.isAvailable(*collection->front()); + + for(const auto& obj : *collection) { + const IParticle* orig = obj; + bool selected = false; + if(!originalInputs) { orig = *acc_originalObject(*obj); } + std::vector<const xAOD::MissingETAssociation*> assocs = xAOD::MissingETComposition::getAssociations(map,orig); + if(assocs.empty()) { + ATH_MSG_WARNING("Object is not in association map. Did you make a deep copy but fail to set the \"originalObjectLinks\" decoration?"); + ATH_MSG_WARNING("If not, Please apply xAOD::setOriginalObjectLinks() from xAODBase/IParticleHelpers.h"); + } + if(MissingETComposition::objSelected(helper,orig)) { + ATH_MSG_DEBUG("Muon with index "<<orig->index() << " is selected. Flag it as non selected before getOverlapRemovedSignals"); + muon_index.push_back(orig->index()); + for(size_t i = 0; i < assocs.size(); i++) helper->setObjSelectionFlag(assocs[i],orig,false); + } + } + + /*ATH_MSG_VERBOSE("Check selected muons before getOverlapRemovedSignals"); + for(const auto& obj : *collection) { + const IParticle* orig = obj; + if(!originalInputs) { orig = *acc_originalObject(*obj); } + ATH_MSG_VERBOSE("Muon with index "<<orig->index() << " is " << (MissingETComposition::objSelected(helper,orig) ? "" : "non-") << "selected" ); + }*/ + } // end retainMuon + + const xAOD::PFOContainer* ORsignals =static_cast<const xAOD::PFOContainer*>(map->getOverlapRemovedSignals(helper,signals,p)); + + /*for (const auto tmp_const : *signals){ // printout overlap removed constituents + bool keep=false; + for (const auto constit : *ORsignals){ + if (constit->index()==tmp_const->index() && constit->charge()==tmp_const->charge()){keep=true;} + } + if (keep==false){ANA_MSG_DEBUG("Retrieve OR constituents: DON'T keep " << tmp_const->index() << " with charge " << tmp_const->charge() << " and pt "<<tmp_const->pt());} + }*/ + + // Flag back muons as selected + if (retainMuon && muon_index.size()>0){ + bool originalInputs = !acc_originalObject.isAvailable(*collection->front()); + for(const auto& obj : *collection) { + const IParticle* orig = obj; + bool selected = false; + if(!originalInputs) { orig = *acc_originalObject(*obj); } + std::vector<const xAOD::MissingETAssociation*> assocs = xAOD::MissingETComposition::getAssociations(map,orig); + for (size_t ind=0; ind<muon_index.size();ind++){ + if(orig->index()==muon_index.at(ind)) { + for(size_t i = 0; i < assocs.size(); i++) helper->setObjSelectionFlag(assocs[i],orig,true); + } + } + } + /*ATH_MSG_VERBOSE("Check selected muons after getOverlapRemovedSignals"); + for(const auto& obj : *collection) { + const IParticle* orig = obj; + if(!originalInputs) { orig = *acc_originalObject(*obj); } + ATH_MSG_VERBOSE("Muon with index "<<orig->index() << " is selected?" << MissingETComposition::objSelected(helper,orig)); + }*/ + } + + return ORsignals; + } + + // Accept Track //////////////// bool METMaker::acceptTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* vx) const diff --git a/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py b/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..4dfdef96dd366f98dad6372a03eafb7499939f23 --- /dev/null +++ b/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py @@ -0,0 +1,51 @@ +# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + +from __future__ import print_function +from AthenaConfiguration.ComponentFactory import CompFactory + + +def getMETMakerAlg(suffix,jetSelection="Tier0",jetColl="",doRetrieveORconstit=False, retainMuonConstit=False, doORMet=False, muonID=1, electronID="Medium", photonID="Tight"): + + print ("Generate METMaker and METMakerAlg for METAssoc_"+suffix) + + doPFlow = 'PFlow' in suffix + doTruth = suffix.startswith('Truth') + metMaker = CompFactory.getComp("met::METMaker")('METMaker_'+suffix, + DoPFlow=doPFlow, + DoSoftTruth=doTruth, + JetSelection=jetSelection, + ) + + muonSel = CompFactory.getComp("CP::MuonSelectionTool")("MuonSelectionTool_METMakerAlg", + MuQuality=muonID, # Medium + MaxEta=2.4) + + elecSelLH = CompFactory.AsgElectronLikelihoodTool("EleSelLikelihood_METMakerAlg", + WorkingPoint=electronID+"LHElectron") + + photonSelIsEM = CompFactory.AsgPhotonIsEMSelector("PhotonSelIsEM_METMakerAlg", + WorkingPoint=photonID+"Photon") + + tauSel = CompFactory.getComp("TauAnalysisTools::TauSelectionTool")("TauSelectionTool_METMakerAlg") + + if jetColl=="": + jetColl = suffix+'Jets' + if doTruth: + jetColl = suffix.split('_')[1]+'Jets' + makerAlg = CompFactory.getComp("met::ORMETMakerAlg")('ORMETMakerAlg_'+suffix, + METMapName='METAssoc_AntiKt4EMPFlow', + ORMETMapName='METAssoc_'+suffix, + METCoreName='MET_Core_'+suffix, + METName='MET_Reference_'+suffix, + InputJets=jetColl, + Maker=metMaker, + MuonSelectionTool=muonSel, + ElectronLHSelectionTool=elecSelLH, + PhotonIsEMSelectionTool=photonSelIsEM, + TauSelectionTool=tauSel, + DoRetrieveORconstit=doRetrieveORconstit, + RetainMuonConstit=retainMuonConstit, + DoORMet=doORMet, + ) + return makerAlg + diff --git a/Reconstruction/MET/METUtilities/share/ORMETAssoc.py b/Reconstruction/MET/METUtilities/share/ORMETAssoc.py new file mode 100644 index 0000000000000000000000000000000000000000..2e5b5ff074e6273c240a1f6d46069ec767e66055 --- /dev/null +++ b/Reconstruction/MET/METUtilities/share/ORMETAssoc.py @@ -0,0 +1,28 @@ +from METReconstruction.METRecoFlags import jobproperties, metFlags +from METReconstruction.METAssocConfig import AssocConfig, METAssocConfig, getMETAssocAlg +from METReconstruction.METRecoConfig import getMETRecoAlg + +JetType = 'PFlowJet' if metFlags.DoORMet==False else 'ORPFlowJet' + +#if metFlags.DoORMet==True : modConstKey = "OverlapRemovedCHSParticleFlowObjects" + +associators = [AssocConfig(JetType), + AssocConfig('Muon'), + AssocConfig('Ele'), + AssocConfig('Gamma'), + #AssocConfig('Tau'), # TODO, need to fix links in METTauAssociator + AssocConfig('Soft')] +cfg_akt4pf = METAssocConfig('AntiKt4EMPFlow' if metFlags.DoORMet==False else 'AntiKt4OverlapRemovedEMPFlow', + associators, + doPFlow=True, + usePFOElectronLinks=metFlags.UsePFOElectronLinks, + usePFOPhotonLinks=metFlags.UsePFOPhotonLinks + ) + +metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf +metFlags.METAssocOutputList().append(cfg_akt4pf.suffix) +metAlg = getMETAssocAlg('METAssociation' if metFlags.DoORMet==False else 'METAssociationOR',configs={cfg_akt4pf.suffix:cfg_akt4pf}) +topSequence += metAlg + + + diff --git a/Reconstruction/MET/METUtilities/share/ORjetReco.py b/Reconstruction/MET/METUtilities/share/ORjetReco.py new file mode 100644 index 0000000000000000000000000000000000000000..802ef57eab2bbd018a5fa78c810ce17c40d22adf --- /dev/null +++ b/Reconstruction/MET/METUtilities/share/ORjetReco.py @@ -0,0 +1,165 @@ +from JetRec.JetRecFlags import jetFlags +jetFlags.usePFlow = True + +######################################### +# PseudoJet algorithms + +gtrackget = CfgMgr.PseudoJetAlgorithm( + "orgtrackget", + InputContainer = "JetSelectedTracks", + Label = "GhostTrack", + OutputContainer = "ORPseudoJetGhostTracks", + SkipNegativeEnergy = True, + #GhostScale = 0.0, + #OutputLevel=VERBOSE, +) +topSequence += gtrackget + +pflowget = CfgMgr.PseudoJetAlgorithm( + "orpflowget", + InputContainer = "OverlapRemovedCHSParticleFlowObjects", + Label = "EMPFlow", + OutputContainer = "ORPseudoJetPFlow", + SkipNegativeEnergy = True, + #GhostScale = 0.0, + #OutputLevel=VERBOSE, +) + +topSequence += pflowget + +######################################### +# Modifiers + +# Jet vertex fraction with selection. +JVFTool = CfgMgr.JetVertexFractionTool( + "jvfOR", + VertexContainer = "PrimaryVertices", + AssociatedTracks = "GhostTrack", + TrackVertexAssociation = "JetTrackVtxAssoc", + TrackParticleContainer = "InDetTrackParticles", + #TrackSelector = trackselloose, + JVFName = "JVF", + K_JVFCorrScale = 0.01, + #Z0Cut = 3.0, + PUTrkPtCut = 30000.0, +) + +JVFTool.JetContainer="AntiKt4OverlapRemovedEMPFlowJets" +ToolSvc += JVFTool + +# Jet vertex tagger. +JVTTool = CfgMgr.JetVertexTaggerTool( + "jvtOR", + VertexContainer = "PrimaryVertices", + # AssociatedTracks = "GhostTrack", + # TrackVertexAssociation = tvassoc.TrackVertexAssociation, + # TrackSelector = trackselloose, + JVTName = "Jvt", + +) + +JVTTool.JetContainer="AntiKt4OverlapRemovedEMPFlowJets" + +ToolSvc += JVTTool + +# Jet track info. +JetTrackMomentsTool = CfgMgr.JetTrackMomentsTool( + "trkmomsOR", + JetContainer="AntiKt4OverlapRemovedEMPFlowJets", + VertexContainer = "PrimaryVertices", + AssociatedTracks = "GhostTrack", + TrackVertexAssociation = "JetTrackVtxAssoc", + TrackMinPtCuts = [500, 1000], + #TrackSelector = trackselloose, +) + +ToolSvc += JetTrackMomentsTool + +# Jet track vector sum info +JetTrackSumMomentsTool = CfgMgr.JetTrackSumMomentsTool( + "trksummomsOR", + JetContainer="AntiKt4OverlapRemovedEMPFlowJets", + VertexContainer = "PrimaryVertices", + AssociatedTracks = "GhostTrack", + TrackVertexAssociation = "JetTrackVtxAssoc",#tvassoc.TrackVertexAssociation, + #InputContainer = "InDetTrackParticles", + RequireTrackPV = True, + #TrackSelector = trackselloose, +) + +ToolSvc+=JetTrackSumMomentsTool + + +constitfourmom_pflow = CfgMgr.JetConstitFourMomTool( + "constitfourmom_pflowOR", + JetScaleNames = ["DetectorEtaPhi"], + AltConstitColls = [""], + AltConstitScales = [0], + AltJetScales = ["JetConstitScaleMomentum"] + ) +ToolSvc+=constitfourmom_pflow + +jetens = CfgMgr.JetCaloEnergies("jetensOR", + JetContainer="AntiKt4OverlapRemovedEMPFlowJets" +) +ToolSvc+=jetens + +ecpfsfrac = CfgMgr.JetECPSFractionTool("ecpsfracOR", + JetContainer="AntiKt4OverlapRemovedEMPFlowJets" +) +ToolSvc+=ecpfsfrac + +width= CfgMgr.JetWidthTool("widthOR", + JetContainer="AntiKt4OverlapRemovedEMPFlowJets" +) +ToolSvc+=width + +jetfilter=CfgMgr.JetFilterTool("jetfilter", PtMin=10000) +ToolSvc+=jetfilter + +######################################### +# Calibration + +from JetRec.JetRecCalibrationFinder import jrcf + +JetRecCalibrationFinder = CfgMgr.JetCalibrationTool("JetCalibOR", + JetCollection="AntiKt4EMPFlow", + ConfigFile="JES_MC15cRecommendation_PFlow_Aug2016_rel21.config", + CalibSequence="JetArea_Residual_AbsoluteEtaJES", + RhoKey="Kt4EMPFlowEventShape", + CalibArea="00-04-77") +ToolSvc+=JetRecCalibrationFinder + + +######################################### +# Set up the jet finder +JetFinder_AntiKt4 = CfgMgr.JetFinder("AntiKt4OverlapRemovedEMPFlowJetsFinder", + JetAlgorithm = "AntiKt", + JetRadius = 0.4, + GhostArea = 0.01, + PtMin = 5000, + OutputLevel=INFO, + ) + +######################################### +# Setup a jet builder + +JetBuilder_AntiKt4 = CfgMgr.JetFromPseudojet("jblda", Attributes = ["ActiveArea", "ActiveArea4vec"], + OutputLevel=INFO) +JetFinder_AntiKt4.JetBuilder = JetBuilder_AntiKt4 + +######################################### +# Setup a JetRecTool + +JetRecTool = CfgMgr.JetRecTool("AntiKt4OREMPFlowJets", + InputPseudoJets = ["ORPseudoJetGhostTracks","ORPseudoJetPFlow"], + OutputLevel=INFO) +JetRecTool.JetFinder = JetFinder_AntiKt4 +JetRecTool.OutputContainer = "AntiKt4OverlapRemovedEMPFlowJets" +JetRecTool.JetModifiers = [constitfourmom_pflow,jetens,JetTrackMomentsTool,JetTrackSumMomentsTool,JetRecCalibrationFinder,JVFTool,JVTTool,jetfilter,ecpfsfrac,width] +#JetRecTool.JetModifiers = [constitfourmom_pflow,jetens,JetTrackMomentsTool,JetTrackSumMomentsTool,JVFTool,JVTTool,jetfilter,ecpfsfrac,width] + +######################################### +# JetAlgorithm +topSequence += CfgMgr.JetAlgorithm("jetalgAntiKt4OREMPFlowJets",Tools = [JetRecTool]) + diff --git a/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..64de6fd3c72ef494f4a3ef3513f16b175acb96e2 --- /dev/null +++ b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx @@ -0,0 +1,420 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ORMETMakerAlg.h" +#include "METInterface/IMETMaker.h" +#include "METUtilities/METHelpers.h" + +#include "xAODMissingET/MissingETAuxContainer.h" +#include "xAODMissingET/MissingETComposition.h" +#include "xAODMissingET/MissingETAssociationMap.h" +#include "xAODMissingET/MissingETAssociationHelper.h" + +#include "MuonAnalysisInterfaces/IMuonSelectionTool.h" +#include "EgammaAnalysisInterfaces/IAsgElectronLikelihoodTool.h" +#include "EgammaAnalysisInterfaces/IAsgPhotonIsEMSelector.h" +#include "PATCore/AcceptData.h" +#include "TauAnalysisTools/ITauSelectionTool.h" +#include <xAODCore/ShallowCopy.h> + +#include "xAODPFlow/PFOAuxContainer.h" //jetOR + + +using std::string; +using namespace xAOD; + +namespace met { + + typedef ElementLink<xAOD::IParticleContainer> iplink_t; + static const SG::AuxElement::ConstAccessor< std::vector<iplink_t > > acc_constitObjLinks("ConstitObjectLinks"); + + //********************************************************************** + + ORMETMakerAlg::ORMETMakerAlg(const std::string& name, + ISvcLocator* pSvcLocator ) + : ::AthAlgorithm( name, pSvcLocator ), + m_metKey(""), + m_metmaker(this), + m_muonSelTool(this,""), + m_elecSelLHTool(this,""), + m_photonSelIsEMTool(this,""), + m_tauSelTool(this,"") + + + { + declareProperty( "Maker", m_metmaker ); + declareProperty( "METCoreName", m_CoreMetKey = "MET_Core" ); + declareProperty("METName", m_metKey = std::string("MET_Reference"),"MET container"); + declareProperty("METMapName", m_metMapKey = "METAssoc" ); + declareProperty("ORMETMapName", m_ORMetMapKey = "ORMETAssoc" ); + + declareProperty( "METSoftClName", m_softclname = "SoftClus" ); + declareProperty( "METSoftTrkName", m_softtrkname = "PVSoftTrk" ); + + declareProperty( "InputJets", m_JetContainerKey = "AntiKt4EMPFlowJets" ); + declareProperty( "InputElectrons", m_ElectronContainerKey = "Electrons" ); + declareProperty( "InputPhotons", m_PhotonContainerKey = "Photons" ); + declareProperty( "InputTaus", m_TauJetContainerKey = "TauJets" ); + declareProperty( "InputMuons", m_MuonContainerKey = "Muons" ); + + declareProperty( "MuonSelectionTool", m_muonSelTool ); + declareProperty( "ElectronLHSelectionTool", m_elecSelLHTool ); + declareProperty( "PhotonIsEMSelectionTool" , m_photonSelIsEMTool ); + declareProperty( "TauSelectionTool", m_tauSelTool ); + + declareProperty( "DoTruthLeptons", m_doTruthLep = false ); + + declareProperty( "DoRetrieveORconstit", m_doRetrieveORconstit = false ); + declareProperty( "RetainMuonConstit", m_retainMuonConstit = false ); + declareProperty( "DoORMet", m_doORMet = false ); + + //pT thresholds + declareProperty("ElectronPT", m_electronPT = 10000, "pT for electrons"); + declareProperty("MuonPT", m_muonPT = 10000, "pT for muons"); + declareProperty("PhotonPT", m_photonPT = 10000, "pT for photons"); + declareProperty("TauPT", m_tauPT = 10000, "pT for photons"); + + //eta thresholds + declareProperty("ElectronETA", m_electronETA = 2.47, "eta for electrons"); + declareProperty("MuonETA", m_muonETA = 2.7, "eta for muons"); + declareProperty("PhotonETA", m_photonETA = 2.47, "eta for photons"); + declareProperty("TauETA", m_tauETA = 2.47, "eta for photons"); + + // True or fake electrons / muons + declareProperty("UsePromptElectrons", m_usePromptElectrons = "True", "To use true (prompt) electrons in MET or not"); + declareProperty("UseUnmatched", m_useUnmatched = "True", "Include or reject egamma with unmatched clusters"); + declareProperty("DoBadMuon", m_doBadMuon = "False", "To reject BadMuon or not"); + + declareProperty("DoJVT", m_doJVT = "False"); + declareProperty("Soft", m_soft = "Clus"); + + + } + + //********************************************************************** + + ORMETMakerAlg::~ORMETMakerAlg() { } + + //********************************************************************** + + StatusCode ORMETMakerAlg::initialize() { + ATH_MSG_INFO("Initializing " << name() << "..."); + ATH_MSG_INFO("Retrieving tools..."); + + // retrieve tools + if( m_metmaker.retrieve().isFailure() ) { + ATH_MSG_ERROR("Failed to retrieve tool: " << m_metmaker->name()); + return StatusCode::FAILURE; + }; + + if( m_muonSelTool.retrieve().isFailure() ) { + ATH_MSG_ERROR("Failed to retrieve tool: " << m_muonSelTool->name()); + return StatusCode::FAILURE; + }; + + if( m_elecSelLHTool.retrieve().isFailure() ) { + ATH_MSG_ERROR("Failed to retrieve tool: " << m_elecSelLHTool->name()); + return StatusCode::FAILURE; + }; + + if( m_photonSelIsEMTool.retrieve().isFailure() ) { + ATH_MSG_ERROR("Failed to retrieve tool: " << m_photonSelIsEMTool->name()); + return StatusCode::FAILURE; + }; + + if( m_tauSelTool.retrieve().isFailure() ) { + ATH_MSG_ERROR("Failed to retrieve tool: " << m_tauSelTool->name()); + return StatusCode::FAILURE; + }; + ATH_CHECK( m_ElectronContainerKey.initialize() ); + ATH_CHECK( m_PhotonContainerKey.initialize() ); + ATH_CHECK( m_TauJetContainerKey.initialize() ); + ATH_CHECK( m_MuonContainerKey.initialize() ); + ATH_CHECK( m_JetContainerKey.initialize() ); + ATH_CHECK( m_CoreMetKey.initialize() ); + ATH_CHECK( m_metKey.initialize() ); + ATH_CHECK( m_metMapKey.initialize() ); + ATH_CHECK( m_ORMetMapKey.initialize() ); + ATH_CHECK(m_chargedPFOContainerWriteHandleKey.initialize()); + ATH_CHECK(m_neutralPFOContainerWriteHandleKey.initialize()); + ATH_CHECK(m_PFOContainerWriteHandleKey.initialize()); + + return StatusCode::SUCCESS; + } + + //********************************************************************** + + StatusCode ORMETMakerAlg::finalize() { + ATH_MSG_INFO ("Finalizing " << name() << "..."); + return StatusCode::SUCCESS; + } + + //********************************************************************** + + StatusCode ORMETMakerAlg::execute() { + ATH_MSG_VERBOSE("Executing " << name() << "..."); + + // Create a MissingETContainer with its aux store + auto ctx = getContext(); + auto metHandle= SG::makeHandle (m_metKey,ctx); + ATH_CHECK( metHandle.record (std::make_unique<xAOD::MissingETContainer>(), std::make_unique<xAOD::MissingETAuxContainer>()) ); + xAOD::MissingETContainer* newMet=metHandle.ptr(); + + + SG::ReadHandle<xAOD::MissingETAssociationMap> metMap(m_metMapKey); + if (!metMap.isValid()) { + ATH_MSG_WARNING("Unable to retrieve MissingETAssociationMap: " << m_metMapKey.key()); + return StatusCode::FAILURE; + } + + MissingETAssociationHelper metHelper(&(*metMap)); + + SG::ReadHandle<xAOD::MissingETAssociationMap> ORMetMap(m_ORMetMapKey); + if (m_doORMet && !ORMetMap.isValid()) { + ATH_MSG_WARNING("Unable to retrieve MissingETAssociationMap: " << m_ORMetMapKey.key()); + return StatusCode::FAILURE; + } + + + MissingETAssociationHelper ORMetHelper((m_doORMet ? &(*ORMetMap) : 0)); + + // Retrieve containers *********************************************** + + /// MET + SG::ReadHandle<xAOD::MissingETContainer> coreMet(m_CoreMetKey); + if (!coreMet.isValid()) { + ATH_MSG_WARNING("Unable to retrieve MissingETContainer: " << m_CoreMetKey.key()); + return StatusCode::FAILURE; + } + + /// Jets + SG::ReadHandle<xAOD::JetContainer> Jets(m_JetContainerKey); + if (!Jets.isValid()) { + ATH_MSG_WARNING("Unable to retrieve JetContainer: " << Jets.key()); + return StatusCode::FAILURE; + } + + /// Electrons + SG::ReadHandle<xAOD::ElectronContainer> Electrons(m_ElectronContainerKey); + if (!Electrons.isValid()) { + ATH_MSG_WARNING("Unable to retrieve ElectronContainer: " << Electrons.key()); + return StatusCode::FAILURE; + } + + /// Photons + SG::ReadHandle<xAOD::PhotonContainer> Gamma(m_PhotonContainerKey); + if (!Gamma.isValid()) { + ATH_MSG_WARNING("Unable to retrieve GammaContainer: " << Gamma.key()); + return StatusCode::FAILURE; + } + + /// Taus + SG::ReadHandle<xAOD::TauJetContainer> TauJets(m_TauJetContainerKey); + if (!TauJets.isValid()) { + ATH_MSG_WARNING("Unable to retrieve TauJetContainer: " << TauJets.key()); + return StatusCode::FAILURE; + } + + /// Muons + SG::ReadHandle<xAOD::MuonContainer> Muons(m_MuonContainerKey); + if (!Muons.isValid()) { + ATH_MSG_WARNING("Unable to retrieve MuonContainer: " << Muons.key()); + return StatusCode::FAILURE; + } + + ///PFOs for OR constituents + SG::ReadHandle<xAOD::PFOContainer> PFOs("CHSParticleFlowObjects"); + if (!PFOs.isValid() && m_doRetrieveORconstit ) { + ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << PFOs.key()); + return StatusCode::FAILURE; + } + + // Select and flag objects for final MET building *************************** + + MissingETBase::UsageHandler::Policy objScale = MissingETBase::UsageHandler::PhysicsObject; + if(m_doTruthLep) objScale = MissingETBase::UsageHandler::TruthParticle; + // Electrons + if(!m_ElectronContainerKey.empty()) { + ConstDataVector<ElectronContainer> metElectrons(SG::VIEW_ELEMENTS); + for(const auto& el : *Electrons) { + if(accept(el)) { + metElectrons.push_back(el); + + } + } + if( m_metmaker->rebuildMET("RefEle", xAOD::Type::Electron, newMet, + metElectrons.asDataVector(), + &metHelper, objScale).isFailure() ) { + ATH_MSG_WARNING("Failed to build electron term."); + } + ATH_MSG_DEBUG("Selected " << metElectrons.size() << " MET electrons. " + << acc_constitObjLinks(*(*newMet)["RefEle"]).size() << " are non-overlapping."); + } + + // Photons + if(!m_PhotonContainerKey.empty()) { + ConstDataVector<PhotonContainer> metPhotons(SG::VIEW_ELEMENTS); + for(const auto& ph : *Gamma) { + if(accept(ph)) { + metPhotons.push_back(ph); + } + } + if( m_metmaker->rebuildMET("RefGamma", xAOD::Type::Photon, newMet, + metPhotons.asDataVector(), + &metHelper, objScale).isFailure() ) { + ATH_MSG_WARNING("Failed to build photon term."); + } + ATH_MSG_DEBUG("Selected " << metPhotons.size() << " MET photons. " + << acc_constitObjLinks(*(*newMet)["RefGamma"]).size() << " are non-overlapping."); + } + + // Taus + if(!m_TauJetContainerKey.empty()) { + ConstDataVector<TauJetContainer> metTaus(SG::VIEW_ELEMENTS); + for(const auto& tau : *TauJets) { + if(accept(tau)) { + metTaus.push_back(tau); + } + } + if( m_metmaker->rebuildMET("RefTau", xAOD::Type::Tau, newMet, + metTaus.asDataVector(), + &metHelper, objScale).isFailure() ){ + ATH_MSG_WARNING("Failed to build tau term."); + } + ATH_MSG_DEBUG("Selected " << metTaus.size() << " MET taus. " + << acc_constitObjLinks(*(*newMet)["RefTau"]).size() << " are non-overlapping."); + } + + // Muons + ConstDataVector<MuonContainer> metMuons(SG::VIEW_ELEMENTS); + if(!m_MuonContainerKey.empty()) { + for(const auto& mu : *Muons) { + if(accept(mu)) { + metMuons.push_back(mu); + } + } + + if(m_doTruthLep) objScale = MissingETBase::UsageHandler::OnlyTrack; + + if (m_doORMet && m_retainMuonConstit) { + if( m_metmaker->rebuildMET("Muons", xAOD::Type::Muon, newMet, + metMuons.asDataVector(), + &ORMetHelper, objScale).isFailure() ) { + ATH_MSG_WARNING("Failed to build muon term."); + } + } else { + if( m_metmaker->rebuildMET("Muons", xAOD::Type::Muon, newMet, + metMuons.asDataVector(), + &metHelper, objScale).isFailure() ) { + ATH_MSG_WARNING("Failed to build muon term."); + } + } + ATH_MSG_DEBUG("Selected " << metMuons.size() << " MET muons. " + << acc_constitObjLinks(*(*newMet)["Muons"]).size() << " are non-overlapping."); + } + + if (m_doRetrieveORconstit) { + + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle(m_PFOContainerWriteHandleKey,ctx); //jetOR + ATH_CHECK(PFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(SG::VIEW_ELEMENTS)));//jetOR + + /**** If want to write CHScharged/neutralOverlapRemovedPFlowObjects container to AOD **** + + SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle(m_PFOContainerWriteHandleKey,ctx); //jetOR + ATH_CHECK(PFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR + + ///jetOR cPFO + SG::ReadHandle<xAOD::PFOContainer> cPFO("CHSChargedParticleFlowObjects"); + if (!cPFO.isValid()) { + ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << cPFO.key()); + return StatusCode::FAILURE; + } + ///jetOR nPFO + SG::ReadHandle<xAOD::PFOContainer> nPFO("CHSNeutralParticleFlowObjects"); + if (!nPFO.isValid()) { + ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << nPFO.key()); + return StatusCode::FAILURE; + } + SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle(m_chargedPFOContainerWriteHandleKey,ctx); //jetOR + SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle(m_neutralPFOContainerWriteHandleKey,ctx); //jetOR + ATH_CHECK(chargedPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR + ATH_CHECK(neutralPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR + */ + + + ATH_MSG_INFO("Retrieve OR constituents"); + ConstDataVector<PFOContainer> met_PFO(SG::VIEW_ELEMENTS); + for(const auto& pfo : *PFOs) {met_PFO.push_back(pfo);} + if (metMuons.size()>0 && m_retainMuonConstit) {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_PFO.asDataVector(),&metHelper,PFOContainerWriteHandle,true, metMuons.asDataVector()));} + else {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_PFO.asDataVector(),&metHelper,PFOContainerWriteHandle,false));} + + /**** If want to write CHScharged/neutralOverlapRemovedPFlowObjects container to AOD **** + + ConstDataVector<PFOContainer> met_cPFO(SG::VIEW_ELEMENTS); + for(const auto& pfo : *cPFOs) {met_cPFO.push_back(pfo);} + ConstDataVector<PFOContainer> met_nPFO(SG::VIEW_ELEMENTS); + for(const auto& pfo : *nPFOs) {met_nPFO.push_back(pfo);} + if (metMuons.size()>0 && m_retainMuonConstit) {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_cPFO.asDataVector(), met_nPFO.asDataVector(),&metHelper,chargedPFOContainerWriteHandle,neutralPFOContainerWriteHandle,PFOContainerWriteHandle,true, metMuons.asDataVector()));} + else {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_cPFO.asDataVector(), met_nPFO.asDataVector(),&metHelper,chargedPFOContainerWriteHandle,neutralPFOContainerWriteHandle,PFOContainerWriteHandle,false));}*/ + } + + + m_doJVT= (m_soft=="Clus" ? false : true); + if (m_doORMet) { + if( m_metmaker->rebuildJetMET("RefJet", (m_soft=="Clus" ? m_softclname : m_softtrkname), newMet, + Jets.cptr(), coreMet.cptr(), &ORMetHelper, m_doJVT ).isFailure() ) { + ATH_MSG_WARNING("Failed to build jet and soft terms."); + } + ATH_MSG_DEBUG("Of " << Jets.cptr()->size() << " jets, " + << acc_constitObjLinks(*(*newMet)["RefJet"]).size() << " are non-overlapping, " + << acc_constitObjLinks(*(*newMet)[(m_soft=="Clus" ? m_softclname : m_softtrkname)]).size() << " are soft"); + } else { + if( m_metmaker->rebuildJetMET("RefJet", (m_soft=="Clus" ? m_softclname : m_softtrkname), newMet, + Jets.cptr(), coreMet.cptr(), &metHelper, m_doJVT ).isFailure() ) { + ATH_MSG_WARNING("Failed to build jet and soft terms."); + } + ATH_MSG_DEBUG("Of " << Jets.cptr()->size() << " jets, " + << acc_constitObjLinks(*(*newMet)["RefJet"]).size() << " are non-overlapping, " + << acc_constitObjLinks(*(*newMet)[(m_soft=="Clus" ? m_softclname : m_softtrkname)]).size() << " are soft"); + } + + + ATH_CHECK( buildMETSum("Final"+m_soft, + newMet, + (m_soft=="Clus")? (*newMet)["SoftClus"]->source() : (*newMet)["PVSoftTrk"]->source()) + ); + + xAOD::MissingET* metSum = (*newMet)["Final"+m_soft]; + std::cout << "MET sum = " << 0.001 * metSum->met() << " GeV" << std::endl; + std::cout << "MET jet = " << 0.001 * (*newMet)["RefJet"]->met() << " GeV" << std::endl; + std::cout << "MET mu = " << 0.001 * (*newMet)["Muons"]->met() << " GeV" << std::endl; + std::cout << "MET el = " << 0.001 * (*newMet)["RefEle"]->met() << " GeV" << std::endl; + std::cout << "MET ph = " << 0.001 * (*newMet)["RefGamma"]->met() << " GeV" << std::endl; + std::cout << "MET tau = " << 0.001 * (*newMet)["RefTau"]->met() << " GeV" << std::endl; + std::cout << "MET soft = " << 0.001 * (*newMet)["Soft"+m_soft]->met() << " GeV" << std::endl; + + return StatusCode::SUCCESS; + } + + + bool ORMETMakerAlg::accept(const xAOD::Muon* mu){ + if( mu->pt()<m_muonPT && fabs(mu->eta())>m_muonETA) return false; + return static_cast<bool>(m_muonSelTool->accept(*mu)); + } + + bool ORMETMakerAlg::accept(const xAOD::Electron* el){ + if( fabs(el->eta())>m_electronETA || el->pt()<m_electronPT) return false; + return static_cast<bool> (m_elecSelLHTool->accept(el)); + } + + bool ORMETMakerAlg::accept(const xAOD::Photon* ph){ + if( !(ph->author()&20) || fabs(ph->eta())>m_photonETA || ph->pt()<m_photonPT) return false; + return static_cast<bool> (m_photonSelIsEMTool->accept(ph)); + } + + bool ORMETMakerAlg::accept(const xAOD::TauJet* tau){ + return static_cast<bool>(m_tauSelTool->accept( *tau )); + } +} + diff --git a/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..f33812e64b8552a3d0241a53219a0df86c7ee58d --- /dev/null +++ b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h @@ -0,0 +1,134 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +// ORMETMakerAlg.h + +#ifndef ORMETMakerAlg_H +#define ORMETMakerAlg_H + +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ToolHandle.h" +#include "StoreGate/DataHandle.h" + +#include "xAODEgamma/Electron.h" +#include "xAODEgamma/Photon.h" +#include "xAODMuon/Muon.h" +#include "xAODTau/TauJet.h" + +#include "xAODJet/JetContainer.h" +#include "xAODMuon/MuonContainer.h" +#include "xAODEgamma/ElectronContainer.h" +#include "xAODEgamma/PhotonContainer.h" +#include "xAODTau/TauJetContainer.h" + +#include "xAODMissingET/MissingETContainer.h" +#include "xAODMissingET/MissingETAssociationMap.h" + + +class IMETMaker; +class IAsgElectronLikelihoodTool; +class IAsgPhotonIsEMSelector; +namespace CP { + class IMuonSelectionTool; +} +namespace TauAnalysisTools { + class ITauSelectionTool; +} + +namespace met { + class ORMETMakerAlg : public AthAlgorithm { + + public: + + /// Constructor with parameters: + ORMETMakerAlg(const std::string& name, ISvcLocator* pSvcLocator); + + /// Destructor: + virtual ~ORMETMakerAlg(); + + /// Athena algorithm's Hooks + virtual StatusCode initialize() override; + virtual StatusCode execute() override; + virtual StatusCode finalize() override; + + private: + + /// Default constructor: + ORMETMakerAlg(); + + bool accept(const xAOD::Electron* el); + bool accept(const xAOD::Photon* ph); + bool accept(const xAOD::TauJet* tau); + bool accept(const xAOD::Muon* muon); + + std::string m_softclname; + std::string m_softtrkname; + std::string m_soft; + + //In release 21 need to replace the names of the containers by the appropriate data handles + SG::ReadHandleKey<xAOD::ElectronContainer> m_ElectronContainerKey; + SG::ReadHandleKey<xAOD::PhotonContainer> m_PhotonContainerKey; + SG::ReadHandleKey<xAOD::TauJetContainer> m_TauJetContainerKey; + SG::ReadHandleKey<xAOD::MuonContainer> m_MuonContainerKey; + SG::ReadHandleKey<xAOD::JetContainer> m_JetContainerKey; + + SG::ReadHandleKey<xAOD::MissingETContainer> m_CoreMetKey; + + SG::WriteHandleKey<xAOD::MissingETContainer> m_metKey; + SG::ReadHandleKey<xAOD::MissingETAssociationMap> m_metMapKey; + SG::ReadHandleKey<xAOD::MissingETAssociationMap> m_ORMetMapKey; + + SG::WriteHandleKey<xAOD::PFOContainer> m_chargedPFOContainerWriteHandleKey{this,"PFOChargedOutputName","OverlapRemovedCHSChargedParticleFlowObjects","WriteHandleKey for charged PFO"}; //jetOR + SG::WriteHandleKey<xAOD::PFOContainer> m_neutralPFOContainerWriteHandleKey{this,"PFONeutralOutputName","OverlapRemovedCHSNeutralParticleFlowObjects","WriteHandleKey for charged PFO"}; //jetOR + SG::WriteHandleKey<xAOD::PFOContainer> m_PFOContainerWriteHandleKey{this,"PFOOutputName","OverlapRemovedCHSParticleFlowObjects","WriteHandleKey for PFO"}; //jetOR + + +SG::ReadHandleKey<xAOD::PFOContainer> m_inPFOKey{this, "InPFOKey", "", "ReadHandleKey for modified PFlow Objects"}; +SG::WriteHandleKey<xAOD::PFOContainer> m_outPFOKey{this, "OutPFOKey", "", "WriteHandleKey for modified PFlow Objects"}; + + + + + + bool m_doTruthLep; + bool m_doRetrieveORconstit; + bool m_retainMuonConstit; + bool m_doORMet; + + + double m_electronPT; + double m_muonPT; + double m_photonPT; + double m_tauPT; + + double m_electronETA; + double m_muonETA; + double m_photonETA; + double m_tauETA; + + bool m_selectElectrons; + + bool m_usePromptElectrons; + + bool m_doBadMuon; + bool m_useUnmatched; + bool m_doJVT; + + + /// Athena configured tools + ToolHandle<IMETMaker> m_metmaker; + + ToolHandle<CP::IMuonSelectionTool> m_muonSelTool; + ToolHandle<IAsgElectronLikelihoodTool> m_elecSelLHTool; + ToolHandle<IAsgPhotonIsEMSelector> m_photonSelIsEMTool; + ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelTool; + + }; + +} + +#endif + diff --git a/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx b/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx index fe20a9a707eefa077c41a1d692af8b95c1910878..94926277c49db9d4f513beb2337acc581a551f25 100644 --- a/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx +++ b/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx @@ -6,6 +6,7 @@ // Algs #include "../METUtilAlg.h" #include "../METMakerAlg.h" +#include "../ORMETMakerAlg.h" using namespace met; @@ -16,4 +17,6 @@ DECLARE_COMPONENT( METSignificance ) DECLARE_COMPONENT( METUtilAlg ) DECLARE_COMPONENT( METMakerAlg ) +DECLARE_COMPONENT( ORMETMakerAlg ) +