diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx index facd9d7573205eff47da7eabf960615d4091a2a4..f6f6b5af79c7dcb8a7343475943f20fc4fef555b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/ObjectLoaderStandardCuts.cxx @@ -92,10 +92,8 @@ namespace top { ///-- Muons --/// if (topConfig->useMuons()) { if (topConfig->useAntiMuons()) objectSelection->muonSelection(new top::AntiMuonMC15(topConfig->muonPtcut(), - new top::StandardIsolation( - topConfig->muonIsolation(), - topConfig-> - muonIsolationLoose()))); + new top::AntiMuonIsolation( + topConfig->muonIsolation()))); else objectSelection->muonSelection(new top::MuonMC15(topConfig->muonPtcut(), new top::StandardIsolation(topConfig->muonIsolation(), topConfig->muonIsolationLoose()), diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx index e82352ac44cba16f8d770a6a616f20d1605c9ae9..f316a07c1299e6778de0b2ca43ce348555685e71 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopConfiguration/Root/ConfigurationSettings.cxx @@ -125,7 +125,7 @@ namespace top { "Allows muon reconstruction using 2-station muons with missing inner MS station for |eta|<1.3 for Loose tree - Default: True (only for HighPt)", "True"); registerParameter("MuonIsolation", - "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None", + "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, AntiMuon_nominal, AntiMuon_shapeSyst1, AntiMuon_shapeSyst2, None", "PflowTight_FixedRad"); registerParameter("MuonIsolationLoose", "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None", diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx index 979bd53901cd55562e1a374f29ea2eb4957be8fe..090bec4dbaf097a2e318bf4b5fee7d64be17e1b4 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/AntiMuonMC15.cxx @@ -7,13 +7,11 @@ #include "TopEvent/EventTools.h" namespace top { - AntiMuonMC15::AntiMuonMC15(const double ptcut, IsolationBase* /* isolation */) : + AntiMuonMC15::AntiMuonMC15(const double ptcut, AntiMuonIsolation* isolation) : m_ptcut(ptcut), - m_muonSelectionTool("CP::MuonSelectionTool") { - //m_muonSelectionToolLoose("CP::MuonSelectionToolLoose"), - //m_isolation(isolation) + m_muonSelectionTool("CP::MuonSelectionTool"), + m_isolation(isolation) { top::check(m_muonSelectionTool.retrieve(), "Failed to retrieve muonSelectionTool"); -// top::check( m_muonSelectionToolLoose.retrieve() , "Failed to retrieve muonSelectionToolLoose" ); } bool AntiMuonMC15::passSelection(const xAOD::Muon& mu) const { @@ -22,22 +20,7 @@ namespace top { ///-- https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesMC15 --/// if (!m_muonSelectionTool->accept(mu)) return false; - - if (mu.energyLossType() != xAOD::Muon::NotIsolated) return false; - - float eloss = 0; - bool ok = mu.parameter(eloss, xAOD::Muon::EnergyLoss); - if (ok && eloss > 6000) return false; - - float etcone20 = 0, ptvarcone40 = 0; - ok = mu.isolation(etcone20, xAOD::Iso::etcone20); - if (ok && etcone20 / mu.pt() < 0.03) return false; - - //if (mu.auxdataConst<float>("miniIso")/mu.pt() > .1) return false; - ok = mu.isolation(ptvarcone40, xAOD::Iso::ptvarcone40); - if (ok && ptvarcone40 / mu.pt() > 0.1) return false; - - return true; + return m_isolation->passSelection(mu); } bool AntiMuonMC15::passSelectionLoose(const xAOD::Muon& /*mu*/) const { @@ -53,9 +36,9 @@ namespace top { // << " * quality=" << m_quality << " (tight=0, medium=1, loose=2, v.loose=3)\n" << " * Everything else from muon tool - fill this in?\n"; -// if (!m_isolation) -// os << " * No isolation requirement\n"; -// else -// m_isolation->print(os); + if (!m_isolation) + os << " * No isolation requirement\n"; + else + m_isolation->print(os); } } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx index ece125b44f9b17cc7f6ab6c5e7abce7513f85fa5..ca7568df92ad3b1e0825a1e26f6f697089a1d077 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/Root/IsolationTools.cxx @@ -105,6 +105,79 @@ namespace top { os << " * Approximate Mini Isolation\n"; os << " * iso/pT > " << m_fraction << "\n"; } + + AntiMuonIsolation::AntiMuonIsolation(const std::string& workingPoint) : + m_workingPoint(workingPoint) { + if (m_workingPoint.substr(0,9) != "AntiMuon_") { + ATH_MSG_WARNING("Ignoring isolation working point \"" + << workingPoint + << "\" which is not appropriate for AntiMuons.\n" + << "Will use \"AntiMuon_nominal\" instead."); + m_workingPoint = "AntiMuon_nominal"; + } + else if (m_workingPoint != "AntiMuon_nominal" + && m_workingPoint != "AntiMuon_shapeSyst1" + && m_workingPoint != "AntiMuon_shapeSyst2") { + ATH_MSG_ERROR("Cannot use undefined isolation working point " + << workingPoint + << " for AntiMuons.\n" + << "Should be one of \"AntiMuon_nominal\", \"AntiMuon_shapeSyst1\", \"AntiMuon_shapeSyst2\"."); + throw std::runtime_error("Attempt to use inappropriate isolation working point for AntiMuons"); + } + } + + bool AntiMuonIsolation::passSelection(const xAOD::IParticle& p) const { + //muons + if (p.type() != xAOD::Type::Muon) { + ATH_MSG_ERROR("Cannot use this function for anything else but muons"); + throw std::runtime_error("Cannot use this function for anything else but muons"); + } + + const xAOD::Muon* mu = dynamic_cast<const xAOD::Muon*>(&p); + if (mu == nullptr) { + ATH_MSG_ERROR("Impossible to cast pointer to xAOD::IParticle into pointer to xAOD::Muon"); + throw std::runtime_error("Impossible to cast pointer to xAOD::IParticle into pointer to xAOD::Muon"); + } + + if (mu->energyLossType() != xAOD::Muon::NotIsolated) return false; + + float eloss = 0; + bool ok = mu->parameter(eloss, xAOD::Muon::EnergyLoss); + if (ok && eloss > 6000) return false; + + float etcone20 = 0, ptvarcone40 = 0; + ok = mu->isolation(etcone20, xAOD::Iso::etcone20); + if (ok && etcone20 / mu->pt() < 0.03) return false; + + ok = mu->isolation(ptvarcone40, xAOD::Iso::ptvarcone40); + if (m_workingPoint == "AntiMuon_nominal") { + if (ok && ptvarcone40 / mu->pt() > 0.1) return false; + } + else if (m_workingPoint == "AntiMuon_shapeSyst1") { + if (ok && ptvarcone40 / mu->pt() > 0.05) return false; + } + else if (m_workingPoint == "AntiMuon_shapeSyst2") { + if (ok && (ptvarcone40 / mu->pt() <= 0.05 || ptvarcone40 / mu->pt() > 0.1)) return false; + } + + return true; + } + + void AntiMuonIsolation::print(std::ostream& os) const { + os << " * AntiMuon Isolation : " << m_workingPoint << "\n"; + os << " * energyLossType : NotIsolated\n"; + os << " * EnergyLoss <= 6 GeV\n"; + os << " * etcone20/pT > 0.03\n"; + if (m_workingPoint == "AntiMuon_nominal") { + os << " * ptvarcone40/pT <= 0.1\n"; + } + else if (m_workingPoint == "AntiMuon_shapeSyst1") { + os << " * ptvarcone40/pT <= 0.05\n"; + } + else if (m_workingPoint == "AntiMuon_shapeSyst2") { + os << " * 0.05 < ptvarcone40/pT <= 0.1\n"; + } + } StandardIsolation::StandardIsolation(const std::string& tightLeptonIsolation, const std::string& looseLeptonIsolation) : @@ -123,6 +196,23 @@ namespace top { if (tightLeptonIsolation == "None") m_doTightIsolation = false; if (looseLeptonIsolation == "None") m_doLooseIsolation = false; + + if ( tightLeptonIsolation == "AntiMuon_nominal" + || tightLeptonIsolation == "AntiMuon_shapeSyst1" + || tightLeptonIsolation == "AntiMuon_shapeSyst2" ) { + ATH_MSG_ERROR("Cannot use isolation working point " + << tightLeptonIsolation + << " which is suitable for AntiMuons only."); + throw std::runtime_error("Attempt to use inappropriate isolation working point, suitable for AntiMuons only"); + } + if ( looseLeptonIsolation == "AntiMuon_nominal" + || looseLeptonIsolation == "AntiMuon_shapeSyst1" + || looseLeptonIsolation == "AntiMuon_shapeSyst2" ) { + ATH_MSG_ERROR("Cannot use isolation working point " + << looseLeptonIsolation + << " which is suitable for AntiMuons only."); + throw std::runtime_error("Attempt to use inappropriate isolation working point, suitable for AntiMuons only"); + } } bool StandardIsolation::passSelection(const xAOD::IParticle& p) const { diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h index 66c7dbec39e0ebd000e5e7fd653038ab6dfa9bbc..f2649f72dc3f12941d7bf296d4ea0c4585434b18 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/AntiMuonMC15.h @@ -24,7 +24,7 @@ namespace top { * @param isolation The isolation the user wants to apply. Don't want any * isolation to be applied? Then leave this as a nullptr. */ - AntiMuonMC15(const double ptcut, IsolationBase* isolation); + AntiMuonMC15(const double ptcut, AntiMuonIsolation* isolation); ///Does nothing. virtual ~AntiMuonMC15() {} @@ -53,10 +53,9 @@ namespace top { ///Proper tool to select muons. ToolHandle<CP::IMuonSelectionTool> m_muonSelectionTool; -// ToolHandle<CP::IMuonSelectionTool> m_muonSelectionToolLoose; ///Isolation tool, can be nullptr meaning "no isolation requirement" -// std::unique_ptr<top::IsolationBase> m_isolation; + std::unique_ptr<top::AntiMuonIsolation> m_isolation; }; } diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h index f503b60d8f4b5fc965a8e2f88bcd3508eeb27067..895812faecad09a375fb8dd066ed01bb512888bf 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopObjectSelectionTools/TopObjectSelectionTools/IsolationTools.h @@ -191,6 +191,40 @@ namespace top { double m_fractionLoose; }; +/** + * @brief Apply the cuts relevant for Anti-muon model + */ + class AntiMuonIsolation: public IsolationBase { + public: + /** + * @brief Applies the cuts to etcone and ptcone like we used to in Run-I + * + * This sets up the isolation tool and configures it with the cuts. + */ + AntiMuonIsolation(const std::string& workingPoint = "AntiMuon_Nominal"); + + /** + * @brief Does this particle pass the anti-muon isolation cuts? + * + * @param p Particle that we're worried about. + * @return True if it passes the isolation cuts. + */ + virtual bool passSelection(const xAOD::IParticle& p) const override; + + /** + * @brief Loose WP not implemented for Anti-muon + * + * @param p Particle that we're worried about. + * @return Always true. + */ + virtual bool passSelectionLoose(const xAOD::IParticle& /*p*/) const override {return true;}; + + ///Come on, you really need me to tell you what this does? + virtual void print(std::ostream& os) const override; + protected: + std::string m_workingPoint; + }; + /** * @brief Apply the cuts to etcone and ptcone like we used to in Run-I */