Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L1T DQM offline muon efficiency upgrades #21835

Merged
merged 10 commits into from Feb 5, 2018
215 changes: 107 additions & 108 deletions DQMOffline/L1Trigger/interface/L1TMuonDQMOffline.h
Expand Up @@ -12,16 +12,11 @@

// system include files
#include <memory>
#include <unistd.h>

// user include files
#include "DataFormats/L1Trigger/interface/Muon.h"
#include "DataFormats/L1Trigger/interface/BXVector.h"
#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/EDAnalyzer.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/LuminosityBlock.h"
Expand All @@ -31,7 +26,6 @@
#include "DQMServices/Core/interface/MonitorElement.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTReadoutCollection.h"
#include "DataFormats/MuonReco/interface/Muon.h"
#include "DataFormats/MuonReco/interface/MuonFwd.h"
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
Expand All @@ -57,81 +51,39 @@

#include "TRegexp.h"
#include "TString.h"
#include <iostream>
#include <fstream>
#include <utility>
#include <vector>

//
// helper class to manage GMT-Muon pairing
//

class MuonGmtPair {
public :
MuonGmtPair(const reco::Muon *muon, const l1t::Muon *regMu) :
m_muon(muon), m_regMu(regMu), m_eta(999.), m_phi_bar(999.), m_phi_end(999.) { };
MuonGmtPair(const MuonGmtPair& muonGmtPair);

~MuonGmtPair() { };

double dR();
double pt() const { return m_muon->pt(); };
double eta() const { return m_muon->eta(); };
double phi() const { return m_muon->phi(); };
int charge() const {return m_muon->charge(); };
double gmtPt() const { return m_regMu ? m_regMu->pt() : -1.; };
double gmtEta() const { return m_regMu ? m_regMu->eta() : -5.; };
double gmtPhi() const { return m_regMu ? m_regMu->phi() : -5.; };
int gmtCharge() const {return m_regMu ? m_regMu->charge() : -5; };
int gmtQual() const { return m_regMu ? m_regMu->hwQual() : -1; };

void propagate(edm::ESHandle<MagneticField> bField,
edm::ESHandle<Propagator> propagatorAlong,
edm::ESHandle<Propagator> propagatorOpposite);

private :
// propagation private members
TrajectoryStateOnSurface cylExtrapTrkSam(reco::TrackRef track, double rho);
TrajectoryStateOnSurface surfExtrapTrkSam(reco::TrackRef track, double z);
FreeTrajectoryState freeTrajStateMuon(reco::TrackRef track);

private :
const reco::Muon *m_muon;
const l1t::Muon *m_regMu;

edm::ESHandle<MagneticField> m_BField;
edm::ESHandle<Propagator> m_propagatorAlong;
edm::ESHandle<Propagator> m_propagatorOpposite;

double m_eta;
double m_phi_bar;
double m_phi_end;
};
class MuonGmtPair;

//
// DQM class declaration
//

class L1TMuonDQMOffline : public DQMEDAnalyzer {
public:
enum Control {kCtrlTagPt, kCtrlTagEta, kCtrlTagPhi, kCtrlProbePt, kCtrlProbeEta, kCtrlProbePhi, kCtrlTagProbeDr, kCtrlMuonGmtDeltaR, kCtrlNTightVsAll, kCtrlNProbesVsTight};
enum EffType {kEffPt, kEffPhi, kEffEta, kEffVtx};
enum ResType {kResPt, kRes1OverPt, kResQOverPt, kResPhi, kResEta, kResCh};
enum EtaRegion {kEtaRegionAll, kEtaRegionBmtf, kEtaRegionOmtf, kEtaRegionEmtf, kEtaRegionOut};
enum QualLevel {kQualAll, kQualOpen, kQualDouble, kQualSingle};

L1TMuonDQMOffline(const edm::ParameterSet& ps);
~L1TMuonDQMOffline() override;

protected:
// Luminosity Block
void beginLuminosityBlock(edm::LuminosityBlock const& lumiBlock, edm::EventSetup const& c) override;
virtual void dqmEndLuminosityBlock (edm::LuminosityBlock const& lumiBlock, edm::EventSetup const& c);
void dqmBeginRun(const edm::Run& run, const edm::EventSetup& iSetup) override;
virtual void bookControlHistos(DQMStore::IBooker &);
virtual void bookEfficiencyHistos(DQMStore::IBooker &ibooker, int ptCut);
virtual void bookEfficiencyHistos(DQMStore::IBooker &ibooker);
virtual void bookResolutionHistos(DQMStore::IBooker &ibooker);
void bookHistograms(DQMStore::IBooker &ibooker, const edm::Run& run, const edm::EventSetup& iSetup) override;
//virtual void analyze (const edm::Event& e, const edm::EventSetup& c);

private:
void analyze (const edm::Event& e, const edm::EventSetup& c) override;

private:
// Helper Functions
const unsigned int getNVertices(edm::Handle<reco::VertexCollection> & vertex);
const reco::Vertex getPrimaryVertex(edm::Handle<reco::VertexCollection> & vertex,edm::Handle<reco::BeamSpot> & beamSpot);
bool matchHlt(edm::Handle<trigger::TriggerEvent> & triggerEvent, const reco::Muon * mu);

Expand All @@ -140,87 +92,134 @@ class L1TMuonDQMOffline : public DQMEDAnalyzer {
void getTightMuons(edm::Handle<reco::MuonCollection> & muons, const reco::Vertex & vertex);
void getProbeMuons(edm::Handle<edm::TriggerResults> & trigResults,edm::Handle<trigger::TriggerEvent> & trigEvent);

private:
HLTConfigProvider m_hltConfig;

edm::ESHandle<MagneticField> m_BField;
edm::ESHandle<Propagator> m_propagatorAlong;
edm::ESHandle<Propagator> m_propagatorOpposite;

enum Resol
{
RESOL_Pt,
RESOL_1overPt,
RESOL_Eta,
RESOL_Phi,
RESOL_Charge,

RESOL_Pt_OPEN,
RESOL_1overPt_OPEN,
RESOL_Eta_OPEN,
RESOL_Phi_OPEN,
RESOL_Charge_OPEN,

RESOL_Pt_DOUBLE,
RESOL_1overPt_DOUBLE,
RESOL_Eta_DOUBLE,
RESOL_Phi_DOUBLE,
RESOL_Charge_DOUBLE,

RESOL_Pt_SINGLE,
RESOL_1overPt_SINGLE,
RESOL_Eta_SINGLE,
RESOL_Phi_SINGLE,
RESOL_Charge_SINGLE,
};

enum Control
{
CONTROL_MuonGmtDeltaR,
CONTROL_NTightVsAll,
CONTROL_NProbesVsTight,
};

// histos
std::map<int, std::map<std::string, MonitorElement*> > m_EfficiencyHistos;
std::map<Resol, MonitorElement*> m_ResolutionHistos;
std::vector<float> getHistBinsEff(EffType eff);
std::tuple<int, double, double> getHistBinsRes(ResType res);

// Keys for histogram maps
typedef std::tuple<ResType, EtaRegion, QualLevel> m_histoKeyResType; // resolution histograms
typedef std::tuple<EffType, int, EtaRegion, QualLevel> m_histoKeyEffNumVarType; // efficiency numerator histograms for all variables except eta
typedef std::pair<int, QualLevel> m_histoKeyEffNumEtaType; // efficiency numerator histograms for eta variable
typedef std::tuple<EffType, int, EtaRegion> m_histoKeyEffDenVarType; // efficiency denominator histograms for all variables except eta

// Histograms and histogram containers
std::map<std::tuple<EffType, int, EtaRegion, QualLevel>, MonitorElement*> m_EfficiencyNumVarHistos;
std::map<std::pair<int, QualLevel>, MonitorElement*> m_EfficiencyNumEtaHistos;
std::map<std::tuple<EffType, int, EtaRegion>, MonitorElement*> m_EfficiencyDenVarHistos;
std::map<EtaRegion, MonitorElement*> m_EfficiencyDenPtHistos;
std::map<int, MonitorElement*> m_EfficiencyDenEtaHistos;
std::map<std::tuple<ResType, EtaRegion, QualLevel>, MonitorElement*> m_ResolutionHistos;
std::map<Control, MonitorElement*> m_ControlHistos;

// helper variables
std::vector<const reco::Muon*> m_TightMuons;
std::vector<const reco::Muon*> m_ProbeMuons;
std::vector<const reco::Muon*> m_TightMuons;
std::vector<const reco::Muon*> m_ProbeMuons;
std::vector<MuonGmtPair> m_MuonGmtPairs;

std::vector<reco::MuonCollection> m_RecoMuons;
std::vector<l1t::MuonBxCollection> m_L1tMuons;
std::vector<reco::Muon> m_RecoRecoMuons;
BXVector<l1t::Muon> m_L1tL1tMuons;
std::vector<reco::MuonCollection> m_RecoMuons;
std::vector<l1t::MuonBxCollection> m_L1tMuons;
std::vector<reco::Muon> m_RecoRecoMuons;
BXVector<l1t::Muon> m_L1tL1tMuons;

std::vector<std::pair<int, QualLevel>> m_cuts;

// vectors of enum values to loop over
const std::vector<EffType> m_effTypes;
const std::vector<ResType> m_resTypes;
const std::vector<EtaRegion> m_etaRegions;
const std::vector<QualLevel> m_qualLevelsRes;

// maps with histogram name bits
std::map<EffType, std::string> m_effStrings;
std::map<EffType, std::string> m_effLabelStrings;
std::map<ResType, std::string> m_resStrings;
std::map<ResType, std::string> m_resLabelStrings;
std::map<EtaRegion, std::string> m_etaStrings;
std::map<QualLevel, std::string> m_qualStrings;

// config params
bool m_verbose;
std::string m_HistFolder;
std::vector<int> m_GmtPtCuts;
double m_TagPtCut;
double m_recoToL1PtCutFactor;
std::vector<edm::ParameterSet> m_cutsVPSet;
edm::EDGetTokenT<reco::MuonCollection> m_MuonInputTag;
edm::EDGetTokenT<l1t::MuonBxCollection> m_GmtInputTag;
edm::EDGetTokenT<reco::VertexCollection> m_VtxInputTag;
edm::EDGetTokenT<reco::BeamSpot> m_BsInputTag;
edm::EDGetTokenT<trigger::TriggerEvent> m_trigInputTag;
std::string m_trigProcess;
edm::EDGetTokenT<edm::TriggerResults> m_trigProcess_token;

std::vector<std::string> m_trigNames;
std::vector<double> m_effVsPtBins;
std::vector<double> m_effVsPhiBins;
std::vector<double> m_effVsEtaBins;
std::vector<double> m_effVsVtxBins;

std::vector<int> m_trigIndices;

float m_MaxMuonEta;
float m_MaxGmtMuonDR;
float m_MaxHltMuonDR;
bool m_useAtVtxCoord;
float m_maxGmtMuonDR;
float m_minTagProbeDR;
float m_maxHltMuonDR;
};

//
// helper class to manage GMT-Muon pairing
//
class MuonGmtPair {
public :
MuonGmtPair(const reco::Muon *muon, const l1t::Muon *regMu, bool useAtVtxCoord);
MuonGmtPair(const MuonGmtPair& muonGmtPair);
~MuonGmtPair() { };

double dR();
double pt() const { return m_muon->pt(); };
double eta() const { return m_muon->eta(); };
double phi() const { return m_muon->phi(); };
int charge() const { return m_muon->charge(); };
double gmtPt() const { return m_regMu ? m_regMu->pt() : -1.; };
double gmtEta() const { return m_regMu ? m_gmtEta : -5.; };
double gmtPhi() const { return m_regMu ? m_gmtPhi : -5.; };
int gmtCharge() const {return m_regMu ? m_regMu->charge() : -5; };
int gmtQual() const { return m_regMu ? m_regMu->hwQual() : -1; };

L1TMuonDQMOffline::EtaRegion etaRegion() const;
double getDeltaVar(const L1TMuonDQMOffline::ResType) const;
double getVar(const L1TMuonDQMOffline::EffType) const;

void propagate(edm::ESHandle<MagneticField> bField,
edm::ESHandle<Propagator> propagatorAlong,
edm::ESHandle<Propagator> propagatorOpposite);

// CB ignored at present
// float m_MinMuonDR;
private :
// propagation private members
TrajectoryStateOnSurface cylExtrapTrkSam(reco::TrackRef track, double rho);
TrajectoryStateOnSurface surfExtrapTrkSam(reco::TrackRef track, double z);
FreeTrajectoryState freeTrajStateMuon(reco::TrackRef track);

private :
const reco::Muon *m_muon;
const l1t::Muon *m_regMu;

edm::ESHandle<MagneticField> m_BField;
edm::ESHandle<Propagator> m_propagatorAlong;
edm::ESHandle<Propagator> m_propagatorOpposite;

// L1T muon eta and phi coordinates to be used
// Can be the coordinates from the 2nd muon station or from the vertex
double m_gmtEta;
double m_gmtPhi;

double m_eta;
double m_phi_bar;
double m_phi_end;
};

#endif
70 changes: 42 additions & 28 deletions DQMOffline/L1Trigger/python/L1TMuonDQMEfficiency_cff.py
@@ -1,40 +1,54 @@
import FWCore.ParameterSet.Config as cms

from DQMOffline.L1Trigger.L1TMuonDQMOffline_cfi import muonEfficiencyThresholds, muonEfficiencyThresholds_HI
# generate the efficiency strings for the DQMGenericClient from the pt and quality cuts
def generateEfficiencyStrings(ptQualCuts):
numDenDir = "numerators_and_denominators/"
varStrings = ['pt', 'eta', 'phi', 'vtx']
etaStrings = ['etaMin0_etaMax0p83', 'etaMin0p83_etaMax1p24', 'etaMin1p24_etaMax2p4', 'etaMin0_etaMax2p4']
qualStrings = {0:'qualAll', 4:'qualOpen', 8:'qualDouble', 12:'qualSingle'}

plots = ["EffvsPt", "EffvsEta", "EffvsPhi",
"EffvsPt_OPEN", "EffvsEta_OPEN", "EffvsPhi_OPEN",
"EffvsPt_DOUBLE", "EffvsEta_DOUBLE", "EffvsPhi_DOUBLE",
"EffvsPt_SINGLE", "EffvsEta_SINGLE", "EffvsPhi_SINGLE"]
efficiencyStrings = []
for ptQualCut in ptQualCuts:
effDenNamePrefix = numDenDir+"effDen_"
effNumNamePrefix = numDenDir+"effNum_"
effNamePrefix = "eff_"
for varString in varStrings:
effDenNameVar = effDenNamePrefix+varString
effNumNameVar = effNumNamePrefix+varString+"_"+str(ptQualCut[0])
effNameVar = effNamePrefix+varString+"_"+str(ptQualCut[0])
if varString != "pt":
effDenNameVar += "_"+str(ptQualCut[0])
effDenNameEta = ''
effNumNameEta = ''
effNameEta = ''
if varString != "eta":
for etaString in etaStrings:
effDenName = effDenNameVar+"_"+etaString
effNumName = effNumNameVar+"_"+etaString+"_"+qualStrings[ptQualCut[1]]
effName = effNameVar+"_"+etaString+"_"+qualStrings[ptQualCut[1]]
efficiencyStrings.append(effName+" '"+effName+";;L1 muon efficiency' "+effNumName+" "+effDenName)
else:
effDenName = effDenNameVar
effNumName = effNumNameVar+"_"+qualStrings[ptQualCut[1]]
effName = effNameVar+"_"+qualStrings[ptQualCut[1]]
efficiencyStrings.append(effName+" '"+effName+";;L1 muon efficiency' "+effNumName+" "+effDenName)
return efficiencyStrings

allEfficiencyPlots = []
for plot in plots:
for threshold in muonEfficiencyThresholds:
plotName = '{0}_{1}'.format(plot, threshold)
allEfficiencyPlots.append(plotName)
from DQMServices.Core.DQMEDHarvester import DQMEDHarvester
from DQMOffline.L1Trigger.L1TMuonDQMOffline_cfi import ptQualCuts, ptQualCuts_HI

allEfficiencyPlots_HI = []
for plot in plots:
for threshold in muonEfficiencyThresholds_HI:
plotName = '{0}_{1}'.format(plot, threshold)
allEfficiencyPlots_HI.append(plotName)

from DQMOffline.L1Trigger.L1TEfficiencyHarvesting_cfi import l1tEfficiencyHarvesting
l1tMuonDQMEfficiency = l1tEfficiencyHarvesting.clone(
plotCfgs = cms.untracked.VPSet(
cms.untracked.PSet(
numeratorDir = cms.untracked.string("L1T/L1TMuon/numerators_and_denominators"),
outputDir = cms.untracked.string("L1T/L1TMuon"),
numeratorSuffix = cms.untracked.string("_Num"),
denominatorSuffix = cms.untracked.string("_Den"),
plots = cms.untracked.vstring(allEfficiencyPlots)
)
)
l1tMuonDQMEfficiency = DQMEDHarvester("DQMGenericClient",
subDirs = cms.untracked.vstring("L1T/L1TMuon/"),
efficiency = cms.vstring(),
efficiencyProfile = cms.untracked.vstring(generateEfficiencyStrings(ptQualCuts)),
resolution = cms.vstring(),
outputFileName = cms.untracked.string(""),
verbose = cms.untracked.uint32(0)
)

# modifications for the pp reference run
from Configuration.Eras.Modifier_ppRef_2017_cff import ppRef_2017
ppRef_2017.toModify(l1tMuonDQMEfficiency,
plotCfgs = {0:dict(plots = allEfficiencyPlots_HI)}
efficiencyProfile = cms.untracked.vstring(generateEfficiencyStrings(ptQualCuts_HI))
)