Commit 2f6675f7 authored by Timothee Theveneaux-Pelzer's avatar Timothee Theveneaux-Pelzer 🖖 Committed by Nils Erik Krumnack
Browse files

AnalysisTop: Implementation of anti-muon shape systematics - ANALYSISTO-1044

parent 05144e93
......@@ -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()),
......
......@@ -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",
......
......@@ -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);
}
}
......@@ -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 {
......
......@@ -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;
};
}
......
......@@ -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
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment