From d68ec3c3efdf22152b2e47a023aada83060a8316 Mon Sep 17 00:00:00 2001
From: Moe Wakida <moe.wakida@cern.ch>
Date: Tue, 30 Jun 2020 14:54:21 +0000
Subject: [PATCH] Implement efficiency and L2StandAloneMuon plots to
 TrigMuonMonitoringMT, ATR-20317

---
 .../python/L2MuonSAMonConfig.py               | 455 +++++++++++++++++-
 .../python/TrigMuonEfficiencyMonConfig.py     |  45 +-
 .../src/L2MuonSAMonMT.cxx                     | 367 +++++++++++++-
 .../TrigMuonMonitoringMT/src/L2MuonSAMonMT.h  |  12 +-
 .../src/MuonMatchingTool.cxx                  | 134 ++++--
 .../src/MuonMatchingTool.h                    |  29 +-
 .../src/MuonMatchingTool.icc                  |  37 +-
 .../src/TrigMuonEfficiencyMonMT.cxx           |  51 +-
 .../src/TrigMuonEfficiencyMonMT.h             |   5 +-
 .../src/TrigMuonMonitorAlgorithm.h            |   2 +-
 10 files changed, 1004 insertions(+), 133 deletions(-)

diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/L2MuonSAMonConfig.py b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/L2MuonSAMonConfig.py
index 5cf22eb6f97..5b60726c934 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/L2MuonSAMonConfig.py
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/L2MuonSAMonConfig.py
@@ -1,18 +1,459 @@
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 
 def L2MuonSAMonConfig(helper):
     
     from AthenaConfiguration.ComponentFactory import CompFactory
-    monAlg = helper.addAlgorithm(CompFactory.L2MuonSAMonMT,'L2MuonSAMonMT')
+    # HLT_mu6_L1MU6 is test chain for small statistics, so it will be removed.
+    Chains = ['HLT_mu6_L1MU6', 'HLT_mu26_ivarmedium_L1MU20']
 
+    for chain in Chains:
 
-    histGroup = helper.addGroup(monAlg, 'L2MuonSAMonMT', 'HLT/MuonMon/L2MuonSA')
+        GroupName = 'L2MuonSA_'+chain
 
+        monAlg = helper.addAlgorithm(CompFactory.L2MuonSAMonMT,'L2MuonSAMonMT_'+chain)
+        monAlg.MonitoredChains = [chain]
+        monAlg.Group = GroupName
 
-    import ROOT
-    histGroup.defineHistogram('saPt',title='L2MuonSA Pt;p_{T} [GeV];Events', type='TH1F', path='',xbins=25,xmin=-60.0,xmax=60.0)
-    histGroup.defineHistogram('saEta',title='L2MuonSA Eta;#eta;Events', type='TH1F', path='',xbins=25,xmin=-3.0,xmax=3.0)
-    histGroup.defineHistogram('saPhi',title='L2MuonSA Phi;#phi;Events', type='TH1F', path='',xbins=25,xmin=-ROOT.TMath.Pi(),xmax=ROOT.TMath.Pi())
+        histGroup = helper.addGroup(monAlg, GroupName, 'HLT/MuonMon/L2MuonSA/'+chain)
+    
+    
+        import ROOT
+        # basic EDM variables
+        histGroup.defineHistogram(GroupName+'_Pt;L2MuonSA_Pt',
+                                  title='L2MuonSA Pt '+chain+';p_{T} [GeV];Events', 
+                                  type='TH1F', path='',xbins=210,xmin=-105.,xmax=105.)
+
+        histGroup.defineHistogram(GroupName+'_Pt;L2MuonSA_Pt_Barrel',
+                                  title='L2MuonSA Pt Barrel '+chain+';p_{T} [GeV];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=210,xmin=-105.,xmax=105.)
+
+        histGroup.defineHistogram(GroupName+'_Pt;L2MuonSA_Pt_Endcap',
+                                  title='L2MuonSA Pt Endcap '+chain+';p_{T} [GeV];Events',
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=210,xmin=-105.,xmax=105.)
+
+        histGroup.defineHistogram(GroupName+'_Eta;L2MuonSA_Eta',
+                                  title='L2MuonSA Eta '+chain+';#eta;Events', 
+                                  type='TH1F', path='',xbins=108,xmin=-2.7,xmax=2.7)
+
+        histGroup.defineHistogram(GroupName+'_Phi;L2MuonSA_Phi',
+                                  title='L2MuonSA Phi '+chain+';#phi;Events', 
+                                  type='TH1F', path='',xbins=96,xmin=-ROOT.TMath.Pi(),xmax=ROOT.TMath.Pi())
+
+        histGroup.defineHistogram(GroupName+'_Phi;L2MuonSA_Phi_Barrel',
+                                  title='L2MuonSA Phi Barrel '+chain+';#phi;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=96,xmin=-ROOT.TMath.Pi(),xmax=ROOT.TMath.Pi())
+
+        histGroup.defineHistogram(GroupName+'_Phi;L2MuonSA_Phi_Endcap',
+                                  title='L2MuonSA Phi Endcap '+chain+';#phi;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=96,xmin=-ROOT.TMath.Pi(),xmax=ROOT.TMath.Pi())
+
+        histGroup.defineHistogram(GroupName+'_Eta,'+GroupName+'_Phi;L2MuonSA_Eta_vs_Phi',
+                                  title='L2MuonSA Eta vs Phi '+chain+';#eta;#phi', 
+                                  type='TH2F', path='',xbins=108,xmin=-2.7,xmax=2.7, ybins=96,ymin=-ROOT.TMath.Pi(),ymax=ROOT.TMath.Pi())
+
+
+
+        # position and superpoint
+        histGroup.defineHistogram(GroupName+'_saddr;L2MuonSA_saddr',
+                                  title='L2MuonSA station address '+chain+';address;Events',
+                                  type='TH1I', path='',xbins=6,xmin=-1,xmax=5)
+
+        histGroup.defineHistogram(GroupName+'_MDTpoints_z,'+GroupName+'_MDTpoints_r;L2MuonSA_MDTpoints_z_vs_r',
+                                  title='L2MuonSA MDT superpoint Z vs R (mm) '+chain+';Z[mm];R[mm]', 
+                                  type='TH2F', path='',xbins=200,xmin=-24000,xmax=24000, ybins=200,ymin=-14000,ymax=14000)
+
+
+
+        # L1 RoI eta vs. phi in case mF failed
+        histGroup.defineHistogram(GroupName+'_roiEta,'+GroupName+'_roiPhi;L2MuonSA_failed_L1_eta_vs_phi',
+                                  title='L1 RoI Eta vs. Phi in case of L2MuonSA failure '+chain+';#eta;#phi', 
+                                  cutmask=GroupName+'mf_failure',
+                                  type='TH2F', path='',xbins=108,xmin=-2.7,xmax=2.7, ybins=96,ymin=-ROOT.TMath.Pi(),ymax=ROOT.TMath.Pi())
+
+
+
+        # MuonFeatureDetails
+        # process floe
+        histGroup.defineHistogram(GroupName+'_proc_flow;L2MuonSA_proc_flow',
+                                  title='L2MuonSA process flow '+chain+';;Events', 
+                                  type='TH1I', path='',xbins=6,xmin=1,xmax=7,
+                                  xlabels=["input","n L1 hits > 0","L1 emu ok at trigger layer","n MDT hits > 0 at middle layer","MDT fit ok at middle layer","MDT fit ok at >= 2 layers"])
+
+
+        # RPC
+        histGroup.defineHistogram(GroupName+'_RPC_Pad_N;L2MuonSA_RPC_Pad_N',
+                                  title='L2MuonSA RPC number of hits '+chain+';RPC number of hits;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1I', path='',xbins=20,xmin=0,xmax=20)
+
+
+        # TGC
+        histGroup.defineHistogram(GroupName+'_TGC_Mid_rho_chi2;L2MuonSA_TGC_Mid_rho_chi2',
+                                  title='L2MuonSA TGC big wheel rho fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_TGC_Mid_phi_chi2;L2MuonSA_TGC_Mid_phi_chi2',
+                                  title='L2MuonSA TGC big wheel phi fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_TGC_Mid_rho_N;L2MuonSA_TGC_Mid_rho_N',
+                                  title='L2MuonSA TGC big wheel number of hits in rho '+chain+';TGC BW rho nhits;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=20,xmin=0,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_TGC_Mid_phi_N;L2MuonSA_TGC_Mid_phi_N',
+                                  title='L2MuonSA TGC big wheel number of hits in phi '+chain+';TGC BW phi nhits;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=20,xmin=0,xmax=20)
+
+
+        # MDT
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_fit_chi2;L2MuonSA_MDT_Inn_fit_chi2_barrel',
+                                  title='L2MuonSA barrel MDT Inner station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_fit_chi2;L2MuonSA_MDT_Mid_fit_chi2_barrel',
+                                  title='L2MuonSA barrel MDT Middle station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_fit_chi2;L2MuonSA_MDT_Out_fit_chi2_barrel',
+                                  title='L2MuonSA barrel MDT Outer station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_fit_chi2;L2MuonSA_MDT_Inn_fit_chi2_endcap',
+                                  title='L2MuonSA endcap MDT Inner station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_fit_chi2;L2MuonSA_MDT_Mid_fit_chi2_endcap',
+                                  title='L2MuonSA endcap MDT Middle station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_fit_chi2;L2MuonSA_MDT_Out_fit_chi2_endcap',
+                                  title='L2MuonSA endcap MDT Outer station fit chi2 '+chain+';chi2;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=10)
+
+        histGroup.defineHistogram(GroupName+'_MDT_N;L2MuonSA_MDT_N_barrel',
+                                  title='L2MuonSA barrel MDT number of hits '+chain+';MDT nhits;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_N;L2MuonSA_MDT_Inn_N_barrel',
+                                  title='L2MuonSA barrel MDT Inner number of hits '+chain+';MDT nhits Inner;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_N;L2MuonSA_MDT_Mid_N_barrel',
+                                  title='L2MuonSA barrel MDT Middle number of hits '+chain+';MDT nhits Middle;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_N;L2MuonSA_MDT_Out_N_barrel',
+                                  title='L2MuonSA barrel MDT Outer number of hits '+chain+';MDT nhits Outer;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_N;L2MuonSA_MDT_N_endcap',
+                                  title='L2MuonSA endcap MDT number of hits '+chain+';MDT nhits;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_N;L2MuonSA_MDT_Inn_N_endcap',
+                                  title='L2MuonSA endcap MDT Inner number of hits '+chain+';MDT nhits Inner;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_N;L2MuonSA_MDT_Mid_N_endcap',
+                                  title='L2MuonSA endcap MDT Middle number of hits '+chain+';MDT nhits Middle;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_N;L2MuonSA_MDT_Out_N_endcap',
+                                  title='L2MuonSA endcap MDT Outer number of hits '+chain+';MDT nhits Outer;Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1I', path='',xbins=40,xmin=0,xmax=40)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_residual;L2MuonSA_MDT_Inn_residual_barrel',
+                                  title='L2MuonSA barrel MDT Inner station residual '+chain+';MDT Inner barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_residual;L2MuonSA_MDT_Mid_residual_barrel',
+                                  title='L2MuonSA barrel MDT Middle station residual '+chain+';MDT Middle barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_residual;L2MuonSA_MDT_Out_residual_barrel',
+                                  title='L2MuonSA barrel MDT Outer station residual '+chain+';MDT Outer barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_residual_OffMatch;L2MuonSA_MDT_Inn_residual_barrel_OffMatch',
+                                  title='L2MuonSA barrel MDT Inner station residual matched with Offline '+chain+';MDT Inner barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_residual_OffMatch;L2MuonSA_MDT_Mid_residual_barrel_OffMatch',
+                                  title='L2MuonSA barrel MDT Middle station residual matched with Offline '+chain+';MDT Middle barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_residual_OffMatch;L2MuonSA_MDT_Out_residual_barrel_OffMatch',
+                                  title='L2MuonSA barrel MDT Outer station residual matched with Offline '+chain+';MDT Outer barrel residual [cm];Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Inn_residual;L2MuonSA_MDT_Inn_residual_barrel_vs_LB',
+                                  title='L2MuonSA barrel MDT Inner station residual vs LB '+chain+';LB;MDT Inner barrel residual [cm]', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Mid_residual;L2MuonSA_MDT_Mid_residual_barrel_vs_LB',
+                                  title='L2MuonSA barrel MDT Middle station residual vs LB '+chain+';LB;MDT Middle barrel residual [cm]', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Out_residual;L2MuonSA_MDT_Out_residual_barrel_vs_LB',
+                                  title='L2MuonSA barrel MDT Outer station residual vs LB '+chain+';LB;MDT Outer barrel residual [cm]', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_residual;L2MuonSA_MDT_Inn_residual_endcap',
+                                  title='L2MuonSA endcap MDT Inner station residual '+chain+';MDT Inner endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_residual;L2MuonSA_MDT_Mid_residual_endcap',
+                                  title='L2MuonSA endcap MDT Middle station residual '+chain+';MDT Middle endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_residual;L2MuonSA_MDT_Out_residual_endcap',
+                                  title='L2MuonSA endcap MDT Outer station residual '+chain+';MDT Outer endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Inn_residual_OffMatch;L2MuonSA_MDT_Inn_residual_endcap_OffMatch',
+                                  title='L2MuonSA endcap MDT Inner station residual matched with Offline '+chain+';MDT Inner endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Mid_residual_OffMatch;L2MuonSA_MDT_Mid_residual_endcap_OffMatch',
+                                  title='L2MuonSA endcap MDT Middle station residual matched with Offline '+chain+';MDT Middle endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_MDT_Out_residual_OffMatch;L2MuonSA_MDT_Out_residual_endcap_OffMatch',
+                                  title='L2MuonSA endcap MDT Outer station residual matched with Offline '+chain+';MDT Outer endcap residual [cm];Events', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH1F', path='',xbins=100,xmin=-20,xmax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Inn_residual;L2MuonSA_MDT_Inn_residual_endcap_vs_LB',
+                                  title='L2MuonSA endcap MDT Inner station residual vs LB '+chain+';LB;MDT Inner endcap residual [cm]', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Mid_residual;L2MuonSA_MDT_Mid_residual_endcap_vs_LB',
+                                  title='L2MuonSA endcap MDT Middle station residual vs LB '+chain+';LB;MDT Middle endcap residual [cm]', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+        histGroup.defineHistogram(GroupName+'_LB,'+GroupName+'_MDT_Out_residual;L2MuonSA_MDT_Out_residual_endcap_vs_LB',
+                                  title='L2MuonSA endcap MDT Outer station residual vs LB '+chain+';LB;MDT Outer endcap residual [cm]', 
+                                  cutmask=GroupName+'_isEndcap',
+                                  type='TH2F', path='',xbins=750,xmin=1.,xmax=1501.,ybins=80,ymin=-20,ymax=20)
+
+
+
+        # Comparison to Offline
+        # dR wrt Offline
+        histGroup.defineHistogram(GroupName+'_dRmin;L2MuonSA_dR_toRecMuonCB',
+                                  title='dR between L2MuonSA and Offline '+chain+';#DeltaR;Events', 
+                                  type='TH1F', path='',xbins=100,xmin=0,xmax=2)
+
+
+        # L1 RoI wrt offline
+        histGroup.defineHistogram(GroupName+'_initialRoI_dR;L2MuonSA_initialRoI_dR_toRecMuonCB',
+                                  title='L2MuonSA initialRoI dR wrt offline CB '+chain+';dR(initialRoI vs offl CB);Events', 
+                                  type='TH1F', path='',xbins=100,xmin=0.,xmax=0.5)
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_initialRoI_dEta;L2MuonSA_initialRoI_dEta_vs_Eta_toRecMuonCB',
+                                  title='L2MuonSA initialRoI wrt Offline CB muon, d#eta '+chain+';offl CB #eta;d#eta(initialRoI vs offl CB)', 
+                                  type='TH2F', path='',xbins=54,xmin=-2.7,xmax=2.7, ybins=60,ymin=-0.3,ymax=0.3)
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_initialRoI_dPhi;L2MuonSA_initialRoI_dPhi_vs_Eta_toRecMuonCB',
+                                  title='L2MuonSA initialRoI wrt Offline CB muon, d#phi '+chain+';offl CB #eta;d#phi(initialRoI vs offl CB)', 
+                                  type='TH2F', path='',xbins=54,xmin=-2.7,xmax=2.7, ybins=44,ymin=-0.2,ymax=0.2)
+
+
+        # pt resolution (barrel, endcap1, endcap2, or endcap3) (A-side or C-side)
+        histGroup.defineHistogram(GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB',
+                                  title='L2MuonSA pT resolution wrt Offline '+chain+';p_{T} resol;Events', 
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_BR',
+                                  title='L2MuonSA pT resolution wrt Offline Barrel '+chain+';p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isBarrel',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_EC1',
+                                  title='L2MuonSA pT resolution wrt Offline Endcap1 '+chain+';p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap1',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_EC2',
+                                  title='L2MuonSA pT resolution wrt Offline Endcap2 '+chain+';p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap2',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_EC3',
+                                  title='L2MuonSA pT resolution wrt Offline Endcap3 '+chain+';p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap3',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+
+        histGroup.defineHistogram(GroupName+'_offPt_signed,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_pt_barrel_A',
+                                  title='L2MuonSA barrel A pT resolution wrt Offline in pt '+chain+';p_{T} [GeV/c];p_{T} resol', 
+                                  cutmask=GroupName+'_isBarrelA',
+                                  type='TH2F', path='',xbins=104,xmin=-52.,xmax=52.,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offPt_signed,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_pt_barrel_C',
+                                  title='L2MuonSA barrel C pT resolution wrt Offline in pt '+chain+';p_{T} [GeV/c];p_{T} resol', 
+                                  cutmask=GroupName+'_isBarrelC',
+                                  type='TH2F', path='',xbins=104,xmin=-52.,xmax=52.,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offPt_signed,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_pt_endcap_A',
+                                  title='L2MuonSA endcap A pT resolution wrt Offline in pt '+chain+';p_{T} [GeV/c];p_{T} resol', 
+                                  cutmask=GroupName+'_isEndcapA',
+                                  type='TH2F', path='',xbins=104,xmin=-52.,xmax=52.,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offPt_signed,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_pt_endcap_C',
+                                  title='L2MuonSA endcap C pT resolution wrt Offline in pt '+chain+';p_{T} [GeV/c];p_{T} resol', 
+                                  cutmask=GroupName+'_isEndcapC',
+                                  type='TH2F', path='',xbins=104,xmin=-52.,xmax=52.,ybins=100,ymin=-2.,ymax=2.)
+
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_eta',
+                                  title='L2MuonSA pT resolution wrt Offline in eta '+chain+';#eta;p_{T} resol', 
+                                  type='TH2F', path='',xbins=27,xmin=-2.7,xmax=2.7,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_eta_pT4_6',
+                                  title='L2MuonSA pT resolution wrt Offline in eta (pT4GeV-6GeV) '+chain+';#eta;p_{T} resol', 
+                                  cutmask=GroupName+'_pt4to6',
+                                  type='TH2F', path='',xbins=27,xmin=-2.7,xmax=2.7,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_eta_pT6_8',
+                                  title='L2MuonSA pT resolution wrt Offline in eta (pT6GeV-8GeV) '+chain+';#eta;p_{T} resol', 
+                                  cutmask=GroupName+'_pt6to8',
+                                  type='TH2F', path='',xbins=27,xmin=-2.7,xmax=2.7,ybins=100,ymin=-2.,ymax=2.)
+
+        histGroup.defineHistogram(GroupName+'_offEta,'+GroupName+'_ptresol;L2MuonSA_ptresol_toRecMuonCB_eta_pT8_x',
+                                  title='L2MuonSA pT resolution wrt Offline in eta (pT over 8GeV) '+chain+';#eta;p_{T} resol', 
+                                  cutmask=GroupName+'_ptover8',
+                                  type='TH2F', path='',xbins=27,xmin=-2.7,xmax=2.7,ybins=100,ymin=-2.,ymax=2.)
+
+
+        # inverse pt resolution (positive or negative muon) (A-side or C-side) (barrel, endcap1, endcap2, or endcap3)
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos',
+                                  title='L2MuonSA pT resolution wrt Offline positive muons '+chain+';1/p_{T} resol;Events', 
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg',
+                                  title='L2MuonSA pT resolution wrt Offline negative muons '+chain+';1/p_{T} resol;Events', 
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_BR_A',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons Barrel A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isBarrelA',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_BR_A',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons Barrel A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isBarrelA',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC1_A',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap1 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap1A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC1_A',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap1 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap1A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC2_A',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap2 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap2A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC2_A',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap2 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap2A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC3_A',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap3 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap3A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC3_A',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap3 A-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap3A',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_BR_C',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons Barrel C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isBarrelC',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_BR_C',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons Barrel C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isBarrelC',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC1_C',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap1 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap1C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC1_C',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap1 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap1C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC2_C',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap2 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap2C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC2_C',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap2 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap2C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_pos;L2MuonSA_invptresol_toRecMuonCB_pos_EC3_C',
+                                  title='L2MuonSA pT resolution wrt Offline pos muons EndCap3 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap3C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
+
+        histGroup.defineHistogram(GroupName+'_invptresol_neg;L2MuonSA_invptresol_toRecMuonCB_neg_EC3_C',
+                                  title='L2MuonSA pT resolution wrt Offline neg muons EndCap3 C-side '+chain+';1/p_{T} resol;Events', 
+                                  cutmask=GroupName+'_isEndcap3C',
+                                  type='TH1F', path='',xbins=100,xmin=-2.,xmax=2.)
 
     return
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/TrigMuonEfficiencyMonConfig.py b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/TrigMuonEfficiencyMonConfig.py
index 8b46219d9d7..8259e12f8fe 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/TrigMuonEfficiencyMonConfig.py
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/python/TrigMuonEfficiencyMonConfig.py
@@ -1,4 +1,4 @@
-#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 import re
 import math
@@ -8,7 +8,9 @@ def TrigMuonEfficiencyMonConfig(helper):
     
     from AthenaConfiguration.ComponentFactory import CompFactory
 
-    Chains = ['HLT_mu26_ivarmedium_L1MU20', 'HLT_mu50_L1MU20', 'HLT_mu6_L1MU6']
+    # HLT_mu6_L1MU6 is test chain for small statistics, so it will be removed.
+    # To do: add multi-muon chain and msonly chain
+    Chains = ['HLT_mu6_L1MU6', 'HLT_mu26_ivarmedium_L1MU20', 'HLT_mu50_L1MU20']
 
     cached_regex = {}
     def regex(pat):
@@ -42,17 +44,48 @@ def TrigMuonEfficiencyMonConfig(helper):
                                       type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
 
             histGroup.defineHistogram(GroupName+'_L2SApass,'+GroupName+'_'+variable+';EffL2SA_'+variable+'_wrt_Upstream',
-                                      title='L2MuonSA Efficiency '+chain+';'+xlabel+';Efficiency',
+                                      title='L2MuonSA Efficiency '+chain+' wrt Upstream;'+xlabel+';Efficiency',
                                       cutmask=GroupName+'_L1pass',
                                       type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
 
+            histGroup.defineHistogram(GroupName+'_L2SApass,'+GroupName+'_'+variable+';EffL2SA_'+variable+'_wrt_offlineCB',
+                                      title='L2MuonSA Efficiency '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
             histGroup.defineHistogram(GroupName+'_L2CBpass,'+GroupName+'_'+variable+';EffL2CB_'+variable+'_wrt_Upstream',
-                                      title='L2muComb Efficiency '+chain+';'+xlabel+';Efficiency',
+                                      title='L2muComb Efficiency '+chain+' wrt Upstream;'+xlabel+';Efficiency',
+                                      cutmask=GroupName+'_L2SApass',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_L2CBpass,'+GroupName+'_'+variable+';EffL2CB_'+variable+'_wrt_offlineCB',
+                                      title='L2muComb Efficiency '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_EFSApass,'+GroupName+'_'+variable+';EffEFSA_'+variable+'_wrt_Upstream',
+                                      title='EFSA Muon Efficiency '+chain+' wrt Upstream;'+xlabel+';Efficiency',
+                                      cutmask=GroupName+'_L2CBpass',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_EFSApass,'+GroupName+'_'+variable+';EffEFSA_'+variable+'_wrt_offlineCB',
+                                      title='EFSA Muon Efficiency '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_EFSApass,'+GroupName+'_'+variable+';EffEFSA_'+variable+'_wrt_offlineCB_passedL2SA',
+                                      title='EFSA Muon Efficiency passed L2SA '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
                                       cutmask=GroupName+'_L2SApass',
                                       type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
 
-            histGroup.defineHistogram(GroupName+'_EFpass,'+GroupName+'_'+variable+';EffEF_'+variable+'_wrt_Upstream',
-                                      title='EF Muon Efficiency '+chain+';'+xlabel+';Efficiency',
+            histGroup.defineHistogram(GroupName+'_EFCBpass,'+GroupName+'_'+variable+';EffEFCB_'+variable+'_wrt_Upstream',
+                                      title='EFCB Muon Efficiency '+chain+' wrt Upstream;'+xlabel+';Efficiency',
+                                      cutmask=GroupName+'_EFSApass',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_EFCBpass,'+GroupName+'_'+variable+';EffEFCB_'+variable+'_wrt_offlineCB',
+                                      title='EFCB Muon Efficiency '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
+                                      type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
+
+            histGroup.defineHistogram(GroupName+'_EFCBpass,'+GroupName+'_'+variable+';EffEFCB_'+variable+'_wrt_offlineCB_passedL2CB',
+                                      title='EFCB Muon Efficiency passed L2CB '+chain+' wrt offlineCB;'+xlabel+';Efficiency',
                                       cutmask=GroupName+'_L2CBpass',
                                       type='TEfficiency', path='',xbins=xbins,xmin=xmin,xmax=xmax)
 
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.cxx b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.cxx
index f06a8de21dd..04da9b03c36 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.cxx
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.cxx
@@ -1,9 +1,11 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "L2MuonSAMonMT.h"
 
+#include "xAODTrigMuon/TrigMuonDefs.h"
+#include "MuonMatchingTool.h"
 
 L2MuonSAMonMT :: L2MuonSAMonMT(const std::string& name, ISvcLocator* pSvcLocator )
   : TrigMuonMonitorAlgorithm(name, pSvcLocator)
@@ -12,34 +14,365 @@ L2MuonSAMonMT :: L2MuonSAMonMT(const std::string& name, ISvcLocator* pSvcLocator
 
 StatusCode L2MuonSAMonMT :: initialize(){
   StatusCode sc = TrigMuonMonitorAlgorithm::initialize();
-  ATH_CHECK( m_L2MuonSAContainerKey.initialize() );
+  ATH_CHECK( m_matchTool.retrieve() );
   return sc;
 }
 
 
-StatusCode L2MuonSAMonMT :: fillVariables(const EventContext &ctx) const {
+StatusCode L2MuonSAMonMT :: fillVariablesPerChain(const EventContext &ctx, const std::string &chain) const {
 
   ATH_MSG_DEBUG ("Filling histograms for " << name() << "...");
 
-  SG::ReadHandle<xAOD::L2StandAloneMuonContainer> muonSAs(m_L2MuonSAContainerKey, ctx);
-  if (! muonSAs.isValid() ) {
-    ATH_MSG_ERROR("evtStore() does not contain xAOD::L2StandAloneMuon collection with name "<< m_L2MuonSAContainerKey);
-    return StatusCode::FAILURE;
+  auto lb = Monitored::Scalar<int>(m_group+"_LB",-1.0);
+  lb = GetEventInfo(ctx)->lumiBlock();
+
+  const float ZERO_LIMIT = 0.00001;
+
+  std::vector< TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer> > featureCont = getTrigDecisionTool()->features<xAOD::L2StandAloneMuonContainer>( chain, TrigDefs::includeFailedDecisions );
+  for(const TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer>& muLinkInfo : featureCont){
+    ATH_CHECK( muLinkInfo.isValid() );
+    const ElementLink<xAOD::L2StandAloneMuonContainer> muEL = muLinkInfo.link;
+
+
+    // basic EDM variables
+    auto saPt = Monitored::Scalar<float>(m_group+"_Pt",-1.0);
+    auto saEta = Monitored::Scalar<float>(m_group+"_Eta",-1.0);
+    auto saPhi = Monitored::Scalar<float>(m_group+"_Phi",-1.0);
+    auto saddr = Monitored::Scalar<int>(m_group+"_saddr",-1.0);
+    auto roiEta = Monitored::Scalar<float>(m_group+"_roiEta",-1.0);
+    auto roiPhi = Monitored::Scalar<float>(m_group+"_roiPhi",-1.0);
+    auto mf_failure = Monitored::Scalar<bool>(m_group+"_mf_failure",false);
+
+    saPt = (*muEL)->pt();
+    saEta = (*muEL)->eta();
+    saPhi = (*muEL)->phi();
+    saddr = (*muEL)->sAddress();
+    roiEta = (*muEL)->roiEta();
+    roiPhi = (*muEL)->roiPhi();
+
+    ATH_MSG_DEBUG("saPt = " << saPt << ", saEta =" << saEta << ", saPhi = " << saPhi << ", saddr = " << saddr);
+    if(fabs(saPt) < ZERO_LIMIT) mf_failure = true;
+
+    fill(m_group, roiEta, roiPhi, mf_failure);
+    if( mf_failure ) continue;
+
+    // define barrel or endcap
+    auto isBarrel = Monitored::Scalar<bool>(m_group+"_isBarrel",false);
+    auto isEndcap = Monitored::Scalar<bool>(m_group+"_isEndcap",false);
+
+    if(saddr == -1)  isEndcap = true;
+    else isBarrel = true;;
+
+    fill(m_group, saPt, saEta, saPhi, saddr, isBarrel, isEndcap);
+
+
+    // define process flow
+    std::vector<int> proc_flow;
+    auto mon_proc_flow = Monitored::Collection(m_group+"_proc_flow", proc_flow);
+
+    bool isL1hitThere               = false;
+    bool isL1emuOkForTriggerPlane   = false;
+    bool isMDThitThereForTriggerPlane = false;
+    bool isMDTFitOkForTriggerPlane    = false;
+    bool isMDTFitOkFor2Plane          = false;
+
+
+    // detector variables
+    // RPC and TGC
+    auto nRPC = Monitored::Scalar<int>(m_group+"_RPC_Pad_N",0);
+    auto TGCMidRhoChi2 = Monitored::Scalar<float>(m_group+"_TGC_Mid_rho_chi2",-1.0);
+    auto TGCMidPhiChi2 = Monitored::Scalar<float>(m_group+"_TGC_Mid_phi_chi2",-1.0);
+    auto nTGCMidRho = Monitored::Scalar<int>(m_group+"_TGC_Mid_rho_N",0);
+    auto nTGCMidPhi = Monitored::Scalar<int>(m_group+"_TGC_Mid_phi_N",0);
+
+    nRPC = (*muEL)->rpcHitLayer().size();
+    TGCMidRhoChi2 = (*muEL)->tgcMidRhoChi2();
+    TGCMidPhiChi2 = (*muEL)->tgcMidPhiChi2();
+    nTGCMidRho = (*muEL)->tgcMidRhoN();
+    nTGCMidPhi = (*muEL)->tgcMidPhiN();
+
+    fill(m_group, nRPC, TGCMidRhoChi2, TGCMidPhiChi2, nTGCMidRho, nTGCMidPhi, isBarrel, isEndcap);
+
+
+    // use process flow
+    if(isBarrel){
+      if( nRPC > 0 ) isL1hitThere = true;
+      float rpcFitMidSlope = (*muEL)->rpcFitMidSlope();
+      if( fabs(rpcFitMidSlope) > ZERO_LIMIT ) isL1emuOkForTriggerPlane = true;
+    }
+    else {
+      if( nTGCMidRho > 0 && nTGCMidPhi > 0 ) isL1hitThere = true;
+      float TGCMid1Z  = (*muEL)->tgcMid1Z();
+      if( fabs(TGCMid1Z) > ZERO_LIMIT ) isL1emuOkForTriggerPlane = true;
+    }
+
+
+    // define inner, middle, and outer
+    int inner  = 0;
+    int middle = 1;
+    int outer  = 2;
+
+    if (isEndcap) {
+      inner  = xAOD::L2MuonParameters::Chamber::EndcapInner;
+      middle = xAOD::L2MuonParameters::Chamber::EndcapMiddle;
+      outer  = xAOD::L2MuonParameters::Chamber::EndcapOuter;
+    } else {
+      inner  = xAOD::L2MuonParameters::Chamber::BarrelInner;
+      middle = xAOD::L2MuonParameters::Chamber::BarrelMiddle;
+      outer  = xAOD::L2MuonParameters::Chamber::BarrelOuter;
+    }
+
+    float sign = 1;
+    if( saPhi < 0 ) sign = -1;
+
+
+    // super point
+    std::vector<float> sp_r, sp_z;
+    sp_r.clear();
+    sp_z.clear();
+
+    auto mon_sp_r= Monitored::Collection(m_group+"_MDTpoints_r", sp_r);
+    auto mon_sp_z= Monitored::Collection(m_group+"_MDTpoints_z", sp_z);
+
+    if( fabs((*muEL)->superPointR(inner)) > ZERO_LIMIT ) {
+      sp_r.push_back( sign * (*muEL)->superPointR(inner) );
+      sp_z.push_back( (*muEL)->superPointZ(inner) );
+    }
+    if( fabs((*muEL)->superPointR(middle)) > ZERO_LIMIT ) {
+      sp_r.push_back( sign * (*muEL)->superPointR(middle) );
+      sp_z.push_back( (*muEL)->superPointZ(middle) );
+    }
+    if( fabs((*muEL)->superPointR(outer)) > ZERO_LIMIT ) {
+      sp_r.push_back( sign * (*muEL)->superPointR(outer) );
+      sp_z.push_back( (*muEL)->superPointZ(outer) );
+    }
+
+    fill(m_group, mon_sp_r, mon_sp_z);
+
+
+    // MDT
+    auto MDTInnChi2 = Monitored::Scalar<float>(m_group+"_MDT_Inn_fit_chi2",-1.0);
+    auto MDTMidChi2 = Monitored::Scalar<float>(m_group+"_MDT_Mid_fit_chi2",-1.0);
+    auto MDTOutChi2 = Monitored::Scalar<float>(m_group+"_MDT_Out_fit_chi2",-1.0);
+    auto n_mdt_hits = Monitored::Scalar<int>(m_group+"_MDT_N",0);
+    auto n_mdt_hits_inner = Monitored::Scalar<int>(m_group+"_MDT_Inn_N",0);
+    auto n_mdt_hits_middle = Monitored::Scalar<int>(m_group+"_MDT_Mid_N",0);
+    auto n_mdt_hits_outer = Monitored::Scalar<int>(m_group+"_MDT_Out_N",0);
+
+    MDTInnChi2 = (*muEL)->superPointChi2(inner);
+    MDTMidChi2 = (*muEL)->superPointChi2(middle);
+    MDTOutChi2 = (*muEL)->superPointChi2(outer);
+
+
+    std::vector<float> res_inn, res_mid, res_out;
+    res_inn.clear();
+    res_mid.clear();
+    res_out.clear();
+
+    auto mon_res_inn = Monitored::Collection(m_group+"_MDT_Inn_residual",res_inn);
+    auto mon_res_mid = Monitored::Collection(m_group+"_MDT_Mid_residual",res_mid);
+    auto mon_res_out = Monitored::Collection(m_group+"_MDT_Out_residual",res_out);
+
+
+    n_mdt_hits = (*muEL)->nMdtHits();
+
+    for (int i_tube=0; i_tube<n_mdt_hits; i_tube++) {
+      float res = (*muEL)->mdtHitResidual(i_tube) / 10 ; // to cm
+      int imr = (*muEL)->mdtHitChamber(i_tube);
+
+      if (imr == inner) {
+        n_mdt_hits_inner++;
+        res_inn.push_back(res);
+      }
+      else if (imr == middle) {
+        n_mdt_hits_middle++;
+        res_mid.push_back(res);
+      }
+      else if (imr == outer) {
+        n_mdt_hits_outer++;
+        res_out.push_back(res);
+      }
+    }
+
+    fill(m_group, MDTInnChi2, MDTMidChi2, MDTOutChi2, n_mdt_hits, n_mdt_hits_inner, n_mdt_hits_middle, n_mdt_hits_outer, mon_res_inn, mon_res_mid, mon_res_out, lb, isBarrel, isEndcap);
+
+
+    // use process flow
+    float MDTInnR = (*muEL)->superPointR(inner);
+    float MDTMidR = (*muEL)->superPointR(middle);
+    float MDTOutR = (*muEL)->superPointR(outer);
+
+    if( n_mdt_hits_middle > 0 ) isMDThitThereForTriggerPlane = true;
+    if( MDTMidR > ZERO_LIMIT ) isMDTFitOkForTriggerPlane = true;
+    if( isMDTFitOkForTriggerPlane && (MDTInnR > ZERO_LIMIT || MDTOutR > ZERO_LIMIT) ) isMDTFitOkFor2Plane  = true;
+
+    proc_flow.push_back(1);
+    if( isL1hitThere )                 proc_flow.push_back(2);
+    if( isL1emuOkForTriggerPlane )     proc_flow.push_back(3);
+    if( isMDThitThereForTriggerPlane ) proc_flow.push_back(4);
+    if( isMDTFitOkForTriggerPlane )    proc_flow.push_back(5);
+    if( isMDTFitOkFor2Plane )          proc_flow.push_back(6);
+
+    fill(m_group, mon_proc_flow);
+
+
+    // matching to offline
+    const float DR_cut = 0.4;
+    const xAOD::Muon* RecMuonCB = m_matchTool->matchOff(ctx, saEta, saPhi, DR_cut);
+    if(RecMuonCB == nullptr) continue;
+
+    std::vector<float> res_inn_OffMatch = res_inn;
+    std::vector<float> res_mid_OffMatch = res_mid;
+    std::vector<float> res_out_OffMatch = res_out;
+
+    auto mon_res_inn_OffMatch = Monitored::Collection(m_group+"_MDT_Inn_residual_OffMatch",res_inn_OffMatch);
+    auto mon_res_mid_OffMatch = Monitored::Collection(m_group+"_MDT_Mid_residual_OffMatch",res_mid_OffMatch);
+    auto mon_res_out_OffMatch = Monitored::Collection(m_group+"_MDT_Out_residual_OffMatch",res_out_OffMatch);
+
+    fill(m_group, mon_res_inn_OffMatch, mon_res_mid_OffMatch, mon_res_out_OffMatch, isBarrel, isEndcap);
+
   }
 
-  // variables
-  auto saPt = Monitored::Scalar<double>("saPt",-1.0);
-  auto saEta = Monitored::Scalar<double>("saEta",-1.0);
-  auto saPhi = Monitored::Scalar<double>("saPhi",-1.0);
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode L2MuonSAMonMT :: fillVariablesPerOfflineMuonPerChain(const EventContext&, const xAOD::Muon* mu, const std::string &chain) const {
+
+  ATH_MSG_DEBUG ("Filling histograms for " << name() << "...");
 
-  for (const auto& l2sa : *muonSAs) {
-    saPt = l2sa->pt();
-    saEta = l2sa->eta();
-    saPhi = l2sa->phi();
-    fill("L2MuonSAMonMT", saPt, saEta, saPhi);
+  const float ZERO_LIMIT = 0.00001;
+  const float DR_MATCHED = 0.25;
+
+
+  // offline muon variables
+  auto offEta = Monitored::Scalar<float>(m_group+"_offEta",0.);
+  auto offPt_signed = Monitored::Scalar<float>(m_group+"_offPt_signed",0.);
+  offEta = mu->eta();
+
+  float offPt = mu->pt()/1e3;
+  float offPhi = mu->phi();
+  float offCharge = mu->charge();
+  offPt_signed = offPt * offCharge;
+
+  // dR wrt offline
+  float match_dR = 1000.;
+  const xAOD::L2StandAloneMuon *samu = m_matchTool->matchSA(mu, chain, match_dR);
+  auto dRmin = Monitored::Scalar<float>(m_group+"_dRmin",1000.);
+  if(samu != nullptr) dRmin = xAOD::P4Helpers::deltaR(mu, samu, false); 
+
+  fill(m_group, dRmin);
+  if( dRmin > DR_MATCHED ) return StatusCode::SUCCESS; // not matched to L2MuonSA
+
+  
+  // L1 RoI wrt offline 
+  float saPt  = samu->pt();
+  float roiEta = samu->roiEta();
+  float roiPhi = samu->roiPhi();
+
+  auto roidEta = Monitored::Scalar<float>(m_group+"_initialRoI_dEta",0.);
+  auto roidPhi = Monitored::Scalar<float>(m_group+"_initialRoI_dPhi",0.);
+  auto roidR = Monitored::Scalar<float>(m_group+"_initialRoI_dR",0.);
+
+  roidEta = roiEta - offEta;
+  roidPhi = xAOD::P4Helpers::deltaPhi(offPhi, roiPhi);
+  roidR = sqrt(roidEta*roidEta + roidPhi*roidPhi);
+  
+  fill(m_group, roidEta, roidPhi, roidR, offEta);
+
+
+  // pt resolution, inverse pt resolution
+  auto ptresol = Monitored::Scalar<float>(m_group+"_ptresol",0.);
+  auto invptresol = Monitored::Scalar<float>(m_group+"_invptresol",0.);
+  if ( fabs(offPt) > ZERO_LIMIT && fabs(saPt) > ZERO_LIMIT ) {
+    ptresol = fabs(saPt)/fabs(offPt) - 1.;
+    invptresol = (1./(offPt * offCharge) - 1./saPt) / (1./(offPt * offCharge));
   }
 
 
+  // inverse pt resolution depends on charge of offline muon
+  std::vector<float> invptresol_pos, invptresol_neg;
+  invptresol_pos.clear();
+  invptresol_neg.clear();
+
+  auto mon_invptresol_pos = Monitored::Collection(m_group+"_invptresol_pos",invptresol_pos);
+  auto mon_invptresol_neg = Monitored::Collection(m_group+"_invptresol_neg",invptresol_neg);
+
+  if( offCharge > 0. ) invptresol_pos.push_back(invptresol);
+  else invptresol_neg.push_back(invptresol);
+
+
+  // region variables
+  const float ETA_OF_BARREL   = 1.05;
+  const float ETA_OF_ENDCAP1   = 1.5;
+  const float ETA_OF_ENDCAP2   = 2.0;
+  const float ETA_OF_ENDCAP3   = 2.5;
+
+  auto isBarrel = Monitored::Scalar<bool>(m_group+"_isBarrel",false);
+  auto isBarrelA = Monitored::Scalar<bool>(m_group+"_isBarrelA",false);
+  auto isBarrelC = Monitored::Scalar<bool>(m_group+"_isBarrelC",false);
+  auto isEndcapA = Monitored::Scalar<bool>(m_group+"_isEndcapA",false);
+  auto isEndcapC = Monitored::Scalar<bool>(m_group+"_isEndcapC",false);
+  auto isEndcap1 = Monitored::Scalar<bool>(m_group+"_isEndcap1",false);
+  auto isEndcap2 = Monitored::Scalar<bool>(m_group+"_isEndcap2",false);
+  auto isEndcap3 = Monitored::Scalar<bool>(m_group+"_isEndcap3",false);
+  auto isEndcap1A = Monitored::Scalar<bool>(m_group+"_isEndcap1A",false);
+  auto isEndcap2A = Monitored::Scalar<bool>(m_group+"_isEndcap2A",false);
+  auto isEndcap3A = Monitored::Scalar<bool>(m_group+"_isEndcap3A",false);
+  auto isEndcap1C = Monitored::Scalar<bool>(m_group+"_isEndcap1C",false);
+  auto isEndcap2C = Monitored::Scalar<bool>(m_group+"_isEndcap2C",false);
+  auto isEndcap3C = Monitored::Scalar<bool>(m_group+"_isEndcap3C",false);
+
+  // offline pt variables
+  auto pt4to6 = Monitored::Scalar<bool>(m_group+"_pt4to6",false);
+  auto pt6to8 = Monitored::Scalar<bool>(m_group+"_pt6to8",false);
+  auto ptover8 = Monitored::Scalar<bool>(m_group+"_ptover8",false);
+
+
+  // define region
+  if( fabs(offEta) < ETA_OF_BARREL ) {
+    if( offEta > 0. ) isBarrelA = true;
+    else isBarrelC = true;
+  }
+  else{
+    if( offEta > 0. ) isEndcapA = true;
+    else isEndcapC = true;
+  }
+
+
+  if( fabs(offEta) < ETA_OF_BARREL ){
+    isBarrel = true;
+    if( offEta > 0. ) isBarrelA = true;
+    else isBarrelC = true;
+  }
+  else if ( fabs(offEta) < ETA_OF_ENDCAP1 ){
+    isEndcap1 = true;
+    if( offEta > 0. ) isEndcap1A = true;
+    else isEndcap1C = true;
+  }
+  else if ( fabs(offEta) < ETA_OF_ENDCAP2 ){
+    isEndcap2 = true;
+    if( offEta > 0. ) isEndcap2A = true;
+    else isEndcap2C = true;
+  }
+  else if ( fabs(offEta) < ETA_OF_ENDCAP3 ){
+    isEndcap3 = true;
+    if( offEta > 0. ) isEndcap3A = true;
+    else isEndcap3C = true;
+  }
+
+
+  if( fabs(offPt) > 4 ){
+    if( fabs(offPt) < 6 ) pt4to6 = true;
+    else if( fabs(offPt) < 8 ) pt6to8 = true;
+    else ptover8 = true;
+  }
+
+
+  fill(m_group, ptresol, offPt_signed, offEta, isBarrel, isEndcap1, isEndcap2, isEndcap3, isBarrelA, isBarrelC, isEndcapA, isEndcapC, pt4to6, pt6to8, ptover8);  
+  fill(m_group, mon_invptresol_pos, mon_invptresol_neg, isBarrelA, isBarrelC, isEndcap1A, isEndcap2A, isEndcap3A, isEndcap1C, isEndcap2C, isEndcap3C);
+
+  
   return StatusCode::SUCCESS;
 }
-
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.h b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.h
index 97ca033244d..bde836feef5 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.h
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/L2MuonSAMonMT.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMUONMONITORINGMT_L2MUONSAMONMT_H
@@ -8,6 +8,8 @@
 #include "TrigMuonMonitorAlgorithm.h"
 #include "xAODTrigMuon/L2StandAloneMuonContainer.h"
 
+class MuonMatchingTool;
+
 /*
 This is a class for monitoring L2MuonSA.
  */
@@ -19,12 +21,12 @@ class L2MuonSAMonMT : public TrigMuonMonitorAlgorithm{
   virtual StatusCode initialize() override;
 
  protected:
-  virtual StatusCode fillVariables(const EventContext &ctx) const override;
+  virtual StatusCode fillVariablesPerChain(const EventContext &ctx, const std::string &chain) const override;
+  virtual StatusCode fillVariablesPerOfflineMuonPerChain(const EventContext& ctx, const xAOD::Muon* mu, const std::string &chain) const override;
 
+  Gaudi::Property<std::string> m_group {this, "Group", "", "Histogram group"};
 
- private:
-  SG::ReadHandleKey<xAOD::L2StandAloneMuonContainer> m_L2MuonSAContainerKey {this, "L2StandAloneMuonContainerName", "HLT_MuonL2SAInfo", "L2MuonSA container"};
-  
+  ToolHandle<MuonMatchingTool> m_matchTool {this, "MuonMatchingTool", "MuonMatchingTool", "Tool for matching offline and online objects"};
 
 };
 
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.cxx b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.cxx
index 062109d0afe..0c8d8e5742f 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.cxx
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.cxx
@@ -1,14 +1,11 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonMatchingTool.h"
 #include "xAODTrigger/MuonRoIContainer.h"
 
-static const InterfaceID IID_MuonMatchingTool("IID_MuonMatchingTool", 1, 0);
-
-const InterfaceID& MuonMatchingTool::interfaceID() { return IID_MuonMatchingTool; }
-
+const static double ZERO_LIMIT = 1.e-5;
 
 MuonMatchingTool :: MuonMatchingTool(const std::string& type, const std::string& name, const IInterface*  parent)
   : AthAlgTool(type, name, parent)
@@ -21,74 +18,100 @@ StatusCode MuonMatchingTool :: initialize(){
   if(m_use_extrapolator){
     ATH_CHECK( m_extrapolator.retrieve() );
   }
+  ATH_CHECK( m_MuonContainerKey.initialize() );
+  ATH_CHECK( m_MuonRoIContainerKey.initialize() );
 
   return StatusCode::SUCCESS;
 }
 
 
-template<>
-std::tuple<double,double> MuonMatchingTool :: trigPosForMatch<xAOD::L2StandAloneMuon>(const xAOD::L2StandAloneMuon *trig) const {
-  return std::forward_as_tuple(trig->roiEta(), trig->roiPhi()); 
+const Amg::Vector3D MuonMatchingTool :: offlineMuonAtPivot(const xAOD::Muon* mu) const{
+  const xAOD::TrackParticle* track = mu->primaryTrackParticle();
+  std::unique_ptr<const Trk::TrackParameters> extPars(extTrackToPivot(track));
+  return extPars ? extPars->position() : Amg::Vector3D(0.,0.,0.);
 }
 
+
 template<>
-std::tuple<double,double> MuonMatchingTool :: offlinePosForMatch<xAOD::L2StandAloneMuonContainer>(const xAOD::Muon *mu) const {
-  double eta = mu->eta();
-  double phi = mu->phi();
-  if(m_use_extrapolator){
-    const xAOD::TrackParticle* track = mu->primaryTrackParticle();
-    const Trk::TrackParameters* extPar = extTrackToPivot(track);
-    if(extPar){
-      ATH_MSG_DEBUG("exrapolation successful");
-      eta = extPar->position().eta();
-      phi = extPar->position().phi();
-      delete extPar; extPar = nullptr;
-    }
-  }
-  return std::forward_as_tuple(eta, phi);
+std::tuple<bool, double,double> MuonMatchingTool :: trigPosForMatch<xAOD::L2StandAloneMuon>(const xAOD::L2StandAloneMuon *trig){
+  return std::forward_as_tuple(true, trig->roiEta(), trig->roiPhi());
 }
 
 
-StatusCode MuonMatchingTool :: matchEF(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
+std::tuple<bool, double,double> MuonMatchingTool :: trigPosForMatchEFSA(const xAOD::Muon *trig){
+  const xAOD::TrackParticle* mooreMuon = trig->trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle);
+  return mooreMuon ? std::forward_as_tuple(true, mooreMuon->eta(), mooreMuon->phi()) : std::forward_as_tuple(false, 0., 0.);
+}
+
+
+const xAOD::Muon* MuonMatchingTool :: matchEFSA(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
+  ATH_MSG_DEBUG("MuonMonitoring::matchEFSA()");
+  float reqdR = 0.03;
+  return match<xAOD::Muon>( mu, trig, reqdR, pass, &MuonMatchingTool::trigPosForMatchEFSA);
+}
+
+
+const xAOD::Muon* MuonMatchingTool :: matchEF(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
   ATH_MSG_DEBUG("MuonMonitoring::matchEF()");
-  return match<xAOD::MuonContainer>( mu, trig, 0.03, pass);
+  float reqdR = 0.03;
+  return match<xAOD::Muon>( mu, trig, reqdR, pass);
 }
 
 
+const xAOD::L2StandAloneMuon* MuonMatchingTool :: matchSA(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
+  ATH_MSG_DEBUG("MuonMonitoring::matchSA()");
+  float reqdR = 0.25;
+  if(m_use_extrapolator){
+    reqdR = reqdRL1byPt(mu->pt());
+    const Amg::Vector3D extPos = offlineMuonAtPivot(mu);
+    if(extPos.norm()>ZERO_LIMIT){
+      return match<xAOD::L2StandAloneMuon>( &extPos, trig, reqdR, pass);
+    }
+  }
+  return match<xAOD::L2StandAloneMuon>( mu, trig, reqdR, pass);
+}
 
-StatusCode MuonMatchingTool :: matchSA(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
+const xAOD::L2StandAloneMuon* MuonMatchingTool :: matchSA(  const xAOD::Muon *mu, std::string trig, float &dR) const {
   ATH_MSG_DEBUG("MuonMonitoring::matchSA()");
-  double reqdR = 0.25;
-  if(m_use_extrapolator) reqdR = reqdRL1byPt(mu->pt());
-  return match<xAOD::L2StandAloneMuonContainer>( mu, trig, reqdR, pass);
+  bool pass = false;
+  return match<xAOD::L2StandAloneMuon>( mu, trig, dR, pass);
 }
 
 
-StatusCode MuonMatchingTool :: matchCB(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
+const xAOD::L2CombinedMuon* MuonMatchingTool :: matchCB(  const xAOD::Muon *mu, std::string trig, bool &pass) const {
   ATH_MSG_DEBUG("MuonMonitoring::matchCB()");
-  return match<xAOD::L2CombinedMuonContainer>( mu, trig, 0.03, pass);
+  float reqdR = 0.03;
+  return match<xAOD::L2CombinedMuon>( mu, trig, reqdR, pass);
 }
 
 
-StatusCode MuonMatchingTool :: matchL1(  const xAOD::Muon *mu, SG::ReadHandle<xAOD::MuonRoIContainer> &murois, std::string trig, bool &pass) const {
+const xAOD::MuonRoI* MuonMatchingTool :: matchL1(  const xAOD::Muon *mu, const EventContext& ctx, std::string trig, bool &pass) const {
 
   double refEta = mu->eta();
   double refPhi = mu->phi();
   double reqdR = 0.25;
   if(m_use_extrapolator){
-    const xAOD::TrackParticle* track = mu->primaryTrackParticle();
-    const Trk::TrackParameters* extPar = extTrackToPivot(track);
-    if(extPar){
-      ATH_MSG_DEBUG("exrapolation successful");
-      refEta = extPar->position().eta();
-      refPhi = extPar->position().phi();
-      reqdR = reqdRL1byPt(mu->pt());
-      delete extPar; extPar = nullptr;
+    reqdR = reqdRL1byPt(mu->pt());
+    const Amg::Vector3D extPos = offlineMuonAtPivot(mu);
+    if(extPos.norm()>ZERO_LIMIT){
+      refEta = extPos.eta();
+      refPhi = extPos.phi();
     }
   }
 
   pass = false;
-  for(const auto &roi : *murois){
+  const xAOD::MuonRoI *closest = nullptr;
+  SG::ReadHandle<xAOD::MuonRoIContainer> rois(m_MuonRoIContainerKey, ctx);
+  if (! rois.isValid() ) {
+    ATH_MSG_ERROR("evtStore() does not contain xAOD::MuonRoI collection with name "<< m_MuonRoIContainerKey);
+    return closest;
+  }
+  if(rois->getConstStore()==nullptr){
+    xAOD::MuonRoIContainer *ncptr = const_cast<xAOD::MuonRoIContainer*>(rois.get());
+    ncptr->setStore(DataLink<SG::IConstAuxStore>(m_MuonRoIContainerKey.key()+"Aux.", ctx));
+  }
+
+  for(const auto &roi : *rois){
     double roiEta = roi->eta();
     double roiPhi = roi->phi();
     int roiThr = roi->getThrNumber();
@@ -100,14 +123,43 @@ StatusCode MuonMatchingTool :: matchL1(  const xAOD::Muon *mu, SG::ReadHandle<xA
     if( dR<reqdR && roiThr>=L1ItemSTI(trig)){
       reqdR = dR;
       pass = true;
+      closest = roi;
       ATH_MSG_DEBUG("* L1 muon eta=" << roiEta << " phi=" << roiPhi  << " dR=" << dR <<  " isPassed=true" ); 
     }
   }
 
-  return StatusCode::SUCCESS;
+  return closest;
 }
 
 
+const xAOD::Muon* MuonMatchingTool :: matchOff( const EventContext& ctx, float trigEta, float trigPhi, float DR_cut) const {
+
+  const xAOD::Muon *muon = nullptr;
+
+  SG::ReadHandle<xAOD::MuonContainer> muons(m_MuonContainerKey, ctx);
+  if (! muons.isValid() ) {
+    ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "<< m_MuonContainerKey);
+    return muon;
+  }
+
+  for(const auto &mu : *muons){
+    float offEta = mu->eta();
+    float offPhi = mu->phi();
+
+    float deta = offEta - trigEta;
+    float dphi = xAOD::P4Helpers::deltaPhi(offPhi, trigPhi);
+    double dR = sqrt(deta*deta + dphi*dphi);
+
+    if(dR < DR_cut){
+      DR_cut = dR;
+      muon = mu;
+      ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi  << " offEta=" << offEta << " offPhi=" << offPhi << " dR=" << dR);
+    }
+  }  
+
+  return muon;
+}
+
 
 double MuonMatchingTool :: FermiFunction(double x, double x0, double w) const {
   return 1/(1+TMath::Exp(-10*(x-x0)/w));
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.h b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.h
index 92e2a5cceba..8471246d712 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.h
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMUONMONITORINGMT_MUONMATCHINGTOOL_H
@@ -24,7 +24,6 @@
 class MuonMatchingTool : public AthAlgTool {
 
  public:
-  static const InterfaceID& interfaceID();
   MuonMatchingTool(const std::string& type, const std::string &name, const IInterface* parent);
 
   virtual StatusCode initialize() override;
@@ -44,10 +43,14 @@ class MuonMatchingTool : public AthAlgTool {
 
 
 
-  StatusCode matchL1(const xAOD::Muon *mu, SG::ReadHandle<xAOD::MuonRoIContainer> &murois, std::string trigger, bool &pass) const;
-  StatusCode matchSA(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
-  StatusCode matchCB(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
-  StatusCode matchEF(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
+  const xAOD::MuonRoI* matchL1(const xAOD::Muon *mu, const EventContext& ctx, std::string trigger, bool &pass) const;
+  const xAOD::L2StandAloneMuon* matchSA(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
+  const xAOD::L2StandAloneMuon* matchSA(const xAOD::Muon *mu, std::string trigger, float &dR) const;
+  const xAOD::L2CombinedMuon* matchCB(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
+  const xAOD::Muon* matchEFSA(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
+  const xAOD::Muon* matchEF(const xAOD::Muon *mu, std::string trigger, bool &pass) const;
+
+  const xAOD::Muon* matchOff( const EventContext& ctx, float trigEta, float trigPhi, float DR_cut) const;
 
   const Trk::TrackParameters* extTrackToPivot(const xAOD::TrackParticle *track) const;
   const Trk::TrackParameters* extTrackToTGC(const xAOD::TrackParticle *track) const;
@@ -58,13 +61,19 @@ class MuonMatchingTool : public AthAlgTool {
 
  private:
   // private methods
-  // Template methods that perform different matching schemes for T=xAOD::L2StandAloneMuon, xAOD::L2CombinedMuon and xAOD::Muon (EF).
   // See MuonMatchingTool.cxx for specialization and MuonMatchingTool.icc for implementation
-  template<class T> inline std::tuple<double,double> trigPosForMatch(const T *trig) const;
-  template<class T> inline std::tuple<double,double> offlinePosForMatch(const xAOD::Muon *mu) const;
-  template<class T> StatusCode match(const xAOD::Muon *mu, std::string trigger, double reqdR, bool &pass) const;
+  template<class T, class OFFL> const T* match(const OFFL *offl, std::string trigger, float &reqdR, bool &pass,
+				   std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*) = &MuonMatchingTool::trigPosForMatch<T>) const;
+  const Amg::Vector3D offlineMuonAtPivot(const xAOD::Muon *mu) const;
   double FermiFunction(double x, double x0, double w) const;
 
+  // static methods
+  // Template methods that perform different matching schemes for T=xAOD::L2StandAloneMuon, xAOD::L2CombinedMuon and xAOD::Muon (EF).
+  template<class T> static inline std::tuple<bool,double,double> trigPosForMatch(const T *trig);
+  static inline std::tuple<bool,double,double> trigPosForMatchEFSA(const xAOD::Muon *trig);
+  
+  SG::ReadHandleKey<xAOD::MuonRoIContainer> m_MuonRoIContainerKey {this, "MuonRoIContainerName", "LVL1MuonRoIs", "Level 1 muon container"};
+  SG::ReadHandleKey<xAOD::MuonContainer> m_MuonContainerKey {this, "MuonContainerName", "Muons", "Offline muon container"};
 
   // properties
   Gaudi::Property<bool> m_use_extrapolator {this, "UseExtrapolator", false, "Flag to enable the extrapolator for matching offline and trigger muons"};
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.icc b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.icc
index 83bf382f854..d2d2c35f28b 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.icc
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/MuonMatchingTool.icc
@@ -1,30 +1,32 @@
 /* -*- mode:c++ -*-
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
-template<class T> std::tuple<double,double> MuonMatchingTool :: trigPosForMatch(const T *trig) const { 
-  return std::forward_as_tuple(trig->eta(), trig->phi()); 
-}
-
-template<class T> std::tuple<double,double> MuonMatchingTool :: offlinePosForMatch(const xAOD::Muon *mu) const { 
-  return std::forward_as_tuple(mu->eta(), mu->phi());
+template<class T> std::tuple<bool,double,double> MuonMatchingTool :: trigPosForMatch(const T *trig) {
+  return std::forward_as_tuple(true, trig->eta(), trig->phi());
 }
 
 
-template<class T>
-StatusCode MuonMatchingTool :: match(const xAOD::Muon* mu, std::string trig, double reqdR, bool &pass) const {
+template<class T, class OFFL>
+const T* MuonMatchingTool :: match(const OFFL* offl, std::string trig, float &reqdR, bool &pass,
+                                   std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*)) const {
 
   ATH_MSG_DEBUG("MuonMonitoring::match<T>");
+
+  using CONTAINER = DataVector<T>;
   
-  const auto [offlEta, offlPhi] = offlinePosForMatch<T>(mu);
+  double offlEta = offl->eta();
+  double offlPhi = offl->phi();
 
-  std::vector< TrigCompositeUtils::LinkInfo<T> > featureCont = m_trigDec->features<T>( trig, TrigDefs::includeFailedDecisions );
-  for(const TrigCompositeUtils::LinkInfo<T>& featureLinkInfo : featureCont){
-    ATH_CHECK( featureLinkInfo.isValid() );
-    const ElementLink<T> link = featureLinkInfo.link;
+  std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > featureCont = m_trigDec->features<CONTAINER>( trig, TrigDefs::includeFailedDecisions );
+  const T* ptr = nullptr;
+  for(const TrigCompositeUtils::LinkInfo<CONTAINER>& featureLinkInfo : featureCont){
+    if ( !featureLinkInfo.isValid() ) continue;
+    const ElementLink<CONTAINER> link = featureLinkInfo.link;
 
-    const auto [trigEta, trigPhi] = trigPosForMatch(*link);
+    const auto [status, trigEta, trigPhi] = trigPosForMatchFunc(*link);
+    if(!status) continue;
     double deta = offlEta - trigEta;
     double dphi = xAOD::P4Helpers::deltaPhi(offlPhi, trigPhi);
     double dR = sqrt(deta*deta + dphi*dphi);
@@ -33,12 +35,13 @@ StatusCode MuonMatchingTool :: match(const xAOD::Muon* mu, std::string trig, dou
     if( dR<reqdR ){
       reqdR = dR;
       pass = ( featureLinkInfo.state == TrigCompositeUtils::ActiveState::ACTIVE );
-      ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi  << " pt=" << (*link)->pt() << " dR=" << dR <<  " isPassed=" << pass);
+      ptr = *link.cptr();
+      ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi  << " pt=" << ptr->pt() << " dR=" << dR <<  " isPassed=" << pass);
     }
   }
 
 
-  return StatusCode::SUCCESS;
+  return ptr;
 
 }
 
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.cxx b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.cxx
index 6ebc8c59fd5..d0af1bf86fd 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.cxx
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigMuonEfficiencyMonMT.h"
@@ -15,7 +15,6 @@ TrigMuonEfficiencyMonMT :: TrigMuonEfficiencyMonMT(const std::string& name, ISvc
 StatusCode TrigMuonEfficiencyMonMT :: initialize(){
   StatusCode sc = TrigMuonMonitorAlgorithm::initialize();
   ATH_CHECK( m_matchTool.retrieve() );
-  ATH_CHECK( m_MuonRoIContainerKey.initialize() );
 
   // Pairing HLT and L1
   unsigned int nchains = m_monitored_chains.size();
@@ -61,17 +60,6 @@ StatusCode TrigMuonEfficiencyMonMT :: fillVariablesPerOfflineMuonPerChain(const
   auto muEta = Monitored::Scalar<float>(m_group+"_muEta");
   auto muPhi = Monitored::Scalar<float>(m_group+"_muPhi");
 
-
-  SG::ReadHandle<xAOD::MuonRoIContainer> rois(m_MuonRoIContainerKey, ctx);
-  if (! rois.isValid() ) {
-    ATH_MSG_ERROR("evtStore() does not contain xAOD::MuonRoI collection with name "<< m_MuonRoIContainerKey);
-    return StatusCode::FAILURE;
-  }
-  if(rois->getConstStore()==nullptr){
-    xAOD::MuonRoIContainer *ncptr = const_cast<xAOD::MuonRoIContainer*>(rois.get());
-    ncptr->setStore(DataLink<SG::IConstAuxStore>(m_MuonRoIContainerKey.key()+"Aux.", ctx));
-  }
-
   muPt = mu->pt()/1e3;
   muEta = mu->eta();
   muPhi = mu->phi();
@@ -79,12 +67,13 @@ StatusCode TrigMuonEfficiencyMonMT :: fillVariablesPerOfflineMuonPerChain(const
   auto L1pass = Monitored::Scalar<bool>(m_group+"_L1pass",false);
   auto L2SApass = Monitored::Scalar<bool>(m_group+"_L2SApass",false);
   auto L2CBpass = Monitored::Scalar<bool>(m_group+"_L2CBpass",false);
-  auto EFpass = Monitored::Scalar<bool>(m_group+"_EFpass",false);
+  auto EFSApass = Monitored::Scalar<bool>(m_group+"_EFSApass",false);
+  auto EFCBpass = Monitored::Scalar<bool>(m_group+"_EFCBpass",false);
 
 
   if(m_doL1){
     bool activestate = false;
-    ATH_CHECK( m_matchTool->matchL1(mu, rois, m_l1seeds.at(chain), activestate) );
+    m_matchTool->matchL1(mu, ctx, m_l1seeds.at(chain), activestate);
     L1pass = activestate;
   } else {
     L1pass = true;
@@ -94,7 +83,7 @@ StatusCode TrigMuonEfficiencyMonMT :: fillVariablesPerOfflineMuonPerChain(const
   if(L1pass){
     if(m_doL2SA){
       bool activestate = false;
-      ATH_CHECK( m_matchTool->matchSA(mu, chain, activestate) );
+      m_matchTool->matchSA(mu, chain, activestate);
       L2SApass = activestate;
     } else {
       L2SApass = true;
@@ -105,7 +94,7 @@ StatusCode TrigMuonEfficiencyMonMT :: fillVariablesPerOfflineMuonPerChain(const
   if(L2SApass){
     if(m_doL2CB){
       bool activestate = false;
-      ATH_CHECK( m_matchTool->matchCB(mu, chain, activestate) );
+      m_matchTool->matchCB(mu, chain, activestate);
       L2CBpass = activestate;
     } else {
       L2CBpass = true;
@@ -116,22 +105,34 @@ StatusCode TrigMuonEfficiencyMonMT :: fillVariablesPerOfflineMuonPerChain(const
   if(L2CBpass){
     if(m_doEF){
       bool activestate = false;
-      ATH_CHECK( m_matchTool->matchEF(mu, chain, activestate) );
-      EFpass = activestate;
+      m_matchTool->matchEFSA(mu, chain, activestate);
+      EFSApass = activestate;
     } else {
-      EFpass = true;
+      EFSApass = true;
     }
   }
-  ATH_MSG_DEBUG("L1pass:" << L1pass << " L2SAPass:" << L2SApass << " L2CBpass:" << L2CBpass << " EFpass:" << EFpass);
+
+
+  if(EFSApass){
+    if(m_doEF){
+      bool activestate = false;
+      m_matchTool->matchEF(mu, chain, activestate);
+      EFCBpass = activestate;
+    } else {
+      EFCBpass = true;
+    }
+  }
+
+  ATH_MSG_DEBUG("L1pass:" << L1pass << " L2SAPass:" << L2SApass << " L2CBpass:" << L2CBpass << " EFSApass:" << EFSApass <<  " EFCBpass:" << EFCBpass);
 
 
   //// Cuts based on the offline muon's features ////
   // Inclusive
-  fill(m_group, muPt, L1pass, L2SApass, L2CBpass, EFpass);
+  fill(m_group, muPt, L1pass, L2SApass, L2CBpass, EFSApass, EFCBpass);
 
   // Plateau
   if(muPt>m_thresholds.at(chain)){
-    fill(m_group, muEta, muPhi,  L1pass, L2SApass, L2CBpass, EFpass);
+    fill(m_group, muEta, muPhi, L1pass, L2SApass, L2CBpass, EFSApass, EFCBpass);
   }
 
 
@@ -189,8 +190,8 @@ StatusCode TrigMuonEfficiencyMonMT :: selectMuonsTagAndProbe(SG::ReadHandle<xAOD
     bool pass1 = false;
     bool pass2 = false;
 
-    ATH_CHECK(m_matchTool->matchEF(dimu.first, m_tag_trig, pass1));
-    ATH_CHECK(m_matchTool->matchEF(dimu.second, m_tag_trig, pass2));
+    m_matchTool->matchEF(dimu.first, m_tag_trig, pass1);
+    m_matchTool->matchEF(dimu.second, m_tag_trig, pass2);
     
     if(pass1){
       if(std::find(probes.begin(), probes.end(), dimu.second)==probes.end()){
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.h b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.h
index 1a33fd0b962..d654241d349 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.h
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonEfficiencyMonMT.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMUONMONITORINGMT_TRIGMUONEFFICIENCYMONMT_H
@@ -33,9 +33,6 @@ class TrigMuonEfficiencyMonMT : public TrigMuonMonitorAlgorithm{
   // tools
   ToolHandle<MuonMatchingTool> m_matchTool {this, "MuonMatchingTool", "MuonMatchingTool", "Tool for matching offline and online objects"};
 
-  // ReadHandles
-  SG::ReadHandleKey<xAOD::MuonRoIContainer> m_MuonRoIContainerKey {this, "MuonRoIContainerName", "LVL1MuonRoIs", "Level 1 muon container"};
-
   // properties
   Gaudi::Property<std::string> m_eff_method {this, "Method", "", "Method to measure efficiency e.g. \"TagAndProbe\", \"Bootstrap\""};
   Gaudi::Property<std::string> m_event_trigger {this, "EventTrigger", "", "Trigger used to select events"};
diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonMonitorAlgorithm.h b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonMonitorAlgorithm.h
index b89fca720f2..1297ec895dd 100644
--- a/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonMonitorAlgorithm.h
+++ b/Trigger/TrigMonitoring/TrigMuonMonitoringMT/src/TrigMuonMonitorAlgorithm.h
@@ -42,7 +42,7 @@ class TrigMuonMonitorAlgorithm : public AthMonitorAlgorithm {
   // Properties
   Gaudi::Property<std::vector<std::string> > m_monitored_chains {this, "MonitoredChains", {}, "Trigger chains that are monitored"};
   Gaudi::Property<int> m_muontype {this, "MuonType", xAOD::Muon::MuonType::Combined, "MuonType used for monitoring"};
-  
+
 
 };
 
-- 
GitLab