From 0500cff2e17f29e58be091ab840398ae5d33321c Mon Sep 17 00:00:00 2001
From: Jannik Geisen <jannik.geisen@cern.ch>
Date: Fri, 26 Mar 2021 11:55:18 +0000
Subject: [PATCH] Implement L1 jet matching to JetMonitoring

---
 .../JetMonitoring/JetMatcherAlg.h             |  38 +++-
 .../JetMonitoring/JetMonitoringAlg.h          |   2 +-
 .../src/JetHistoMatchedFiller.cxx             |   1 -
 .../Jet/JetMonitoring/src/JetMatcherAlg.cxx   | 207 +++++++++++++-----
 .../JetMonitoring/src/JetMonitoringAlg.cxx    |   2 +-
 .../python/L1JetMonitoringConfig.py           |  26 ++-
 .../python/TrigJetMonitorAlgorithm.py         |  49 +++--
 .../src/TrigL1JetMonitorAlgorithm.cxx         | 124 +++++++++++
 .../src/TrigL1JetMonitorAlgorithm.h           |  30 ++-
 9 files changed, 389 insertions(+), 90 deletions(-)

diff --git a/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMatcherAlg.h b/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMatcherAlg.h
index 542ae3231f1a..0ae36b412ce0 100644
--- a/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMatcherAlg.h
+++ b/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMatcherAlg.h
@@ -17,6 +17,7 @@
 #include "StoreGate/ReadHandleKey.h"
 #include "AsgDataHandles/WriteDecorHandleKey.h"
 #include "xAODJet/JetContainer.h"
+#include "xAODTrigger/JetRoIContainer.h"
 
 class JetMatcherAlg : public AthReentrantAlgorithm {
 
@@ -29,24 +30,45 @@ class JetMatcherAlg : public AthReentrantAlgorithm {
   StatusCode initialize() override;
   StatusCode execute(const EventContext& ctx) const override;
   StatusCode finalize() override;
+  TLorentzVector GetTLV(const xAOD::Jet* jet) const;
+  TLorentzVector GetTLV(const xAOD::JetRoI* jet) const;
+  template <typename T>
+  void jetMatching(SG::ReadHandle<DataVector<T>> jets1, SG::ReadHandle<xAOD::JetContainer> jets2, SG::WriteDecorHandleKey<DataVector<T>> matchedHandleKey, std::vector<SG::WriteDecorHandleKey<DataVector<T>>> varHandleKeys, const EventContext& ctx) const;
 
  private:
 
-  // input jet containers
-  SG::ReadHandleKey<xAOD::JetContainer> m_jetContainerKey1, m_jetContainerKey2;
-  // R matching property
+  // dR matching property
   Gaudi::Property<float> m_Rmatch           {this, "Rmatch", 0.3, "R matching"};
-  Gaudi::Property<std::string> m_calibScale {this, "calibScale", "", "Calibration Scale at which to evaluate jet pT"};
-  // decorations
+  // calibration scale of reference jet container
+  Gaudi::Property<std::string> m_calibScale {this, "JetCalibScale", "", "Calibration Scale at which to evaluate jet pT"};
+  // check if matching LVL1JetRoIs or not
+  Gaudi::Property<bool> m_matchL1           {this, "MatchL1", false, "Whether to match an L1 jet collection or actual online/offline jets"};
+  // input jet containers
+  SG::ReadHandleKey<xAOD::JetContainer>    m_jetContainerKey1, m_jetContainerKey2;
+  SG::ReadHandleKey<xAOD::JetRoIContainer> m_l1jetContainerKey1;
+
+  // set up decorations
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_matchedKey{this, "matched", "matched", "SG key for output matched decoration"};
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_ptDiffKey{this, "ptdiff", "ptdiff", "SG key for output pt difference decoration"};
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_energyDiffKey{this, "energydiff", "energydiff", "SG key for output energy difference decoration"};
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_massDiffKey{this, "massdiff", "massdiff", "SG key for output mass difference decoration"};
-  SG::WriteDecorHandleKey<xAOD::JetContainer> m_ptRespKey{this, "ptdiff", "ptdiff", "SG key for output pt response decoration"};
-  SG::WriteDecorHandleKey<xAOD::JetContainer> m_energyRespKey{this, "energydiff", "energydiff", "SG key for output energy response decoration"};
-  SG::WriteDecorHandleKey<xAOD::JetContainer> m_massRespKey{this, "massdiff", "massdiff", "SG key for output mass response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_ptRespKey{this, "ptresp", "ptresp", "SG key for output pt response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_energyRespKey{this, "energyresp", "energyresp", "SG key for output energy response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetContainer> m_massRespKey{this, "massresp", "massresp", "SG key for output mass response decoration"};
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_ptRefKey{this, "ptRef", "ptRef", "SG key for output pt reference decoration"};
   SG::WriteDecorHandleKey<xAOD::JetContainer> m_etaRefKey{this, "etaRef", "etaRef", "SG key for output eta reference decoration"};
+  std::vector<SG::WriteDecorHandleKey<xAOD::JetContainer>> m_jetVarHandleKeys;
+
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1matchedKey{this, "l1matched", "l1matched", "SG key for output matched decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1ptDiffKey{this, "l1ptdiff", "l1ptdiff", "SG key for output pt difference decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1energyDiffKey{this, "l1energydiff", "l1energydiff", "SG key for output energy difference decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1massDiffKey{this, "l1massdiff", "l1massdiff", "SG key for output mass difference decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1ptRespKey{this, "l1ptresp", "l1ptresp", "SG key for output pt response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1energyRespKey{this, "l1energyresp", "l1energyresp", "SG key for output energy response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1massRespKey{this, "l1massresp", "l1massresp", "SG key for output mass response decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1ptRefKey{this, "l1ptRef", "l1ptRef", "SG key for output pt reference decoration"};
+  SG::WriteDecorHandleKey<xAOD::JetRoIContainer> m_l1etaRefKey{this, "l1etaRef", "l1etaRef", "SG key for output eta reference decoration"};
+  std::vector<SG::WriteDecorHandleKey<xAOD::JetRoIContainer>> m_l1JetVarHandleKeys;
 
 };
 
diff --git a/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMonitoringAlg.h b/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMonitoringAlg.h
index 1b4e52c5ccf6..40f08ee25db4 100644
--- a/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMonitoringAlg.h
+++ b/Reconstruction/Jet/JetMonitoring/JetMonitoring/JetMonitoringAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETMONITORALGORITHM_H
diff --git a/Reconstruction/Jet/JetMonitoring/src/JetHistoMatchedFiller.cxx b/Reconstruction/Jet/JetMonitoring/src/JetHistoMatchedFiller.cxx
index fb5581133730..a5ef7dab1be0 100644
--- a/Reconstruction/Jet/JetMonitoring/src/JetHistoMatchedFiller.cxx
+++ b/Reconstruction/Jet/JetMonitoring/src/JetHistoMatchedFiller.cxx
@@ -76,7 +76,6 @@ StatusCode JetHistoMatchedFiller::processJetContainer(const JetMonitoringAlg& pa
         parentAlg.fill(m_group, dPt, dEnergy, dMass, rPt, rEnergy, rMass, ptRef, etaRef);
     } 
   }
- 
   parentAlg.fill(m_group,matched);
   
   return StatusCode::SUCCESS;
diff --git a/Reconstruction/Jet/JetMonitoring/src/JetMatcherAlg.cxx b/Reconstruction/Jet/JetMonitoring/src/JetMatcherAlg.cxx
index c6be5471fdba..babe5d250203 100644
--- a/Reconstruction/Jet/JetMonitoring/src/JetMatcherAlg.cxx
+++ b/Reconstruction/Jet/JetMonitoring/src/JetMatcherAlg.cxx
@@ -9,9 +9,9 @@
 
 JetMatcherAlg::JetMatcherAlg( const std::string& name, ISvcLocator* pSvcLocator ) : AthReentrantAlgorithm(name,pSvcLocator)
 {
-  declareProperty("JetContainerName1",m_jetContainerKey1="NONE");
-  declareProperty("JetContainerName2",m_jetContainerKey2="NONE");
-  declareProperty("JetCalibScale",    m_calibScale="");
+  declareProperty("JetContainerName1"  ,m_jetContainerKey1="NONE");
+  declareProperty("L1JetContainerName1",m_l1jetContainerKey1="NONE");
+  declareProperty("JetContainerName2"  ,m_jetContainerKey2="NONE");
 }
 
 //**********************************************************************
@@ -21,29 +21,82 @@ StatusCode JetMatcherAlg::initialize() {
   ATH_MSG_INFO(" Initializing " << name());
 
   ATH_CHECK( m_jetContainerKey1.initialize() );
+  ATH_CHECK( m_l1jetContainerKey1.initialize() );
   ATH_CHECK( m_jetContainerKey2.initialize() );
 
-  std::string keyAppendix = m_jetContainerKey2.key();
-  if (m_calibScale != "") keyAppendix = m_calibScale + "_" + m_jetContainerKey2.key();
-  m_ptDiffKey = m_jetContainerKey1.key()+".ptdiff_" + keyAppendix;
-  ATH_CHECK( m_ptDiffKey.initialize() );
-  m_energyDiffKey = m_jetContainerKey1.key()+".energydiff_" + keyAppendix;
-  ATH_CHECK( m_energyDiffKey.initialize() );
-  m_massDiffKey = m_jetContainerKey1.key()+".massdiff_" + keyAppendix;
-  ATH_CHECK( m_massDiffKey.initialize() );
-  m_ptRespKey = m_jetContainerKey1.key()+".ptresp_" + keyAppendix;
-  ATH_CHECK( m_ptRespKey.initialize() );
-  m_energyRespKey = m_jetContainerKey1.key()+".energyresp_" + keyAppendix;
-  ATH_CHECK( m_energyRespKey.initialize() );
-  m_massRespKey = m_jetContainerKey1.key()+".massresp_" + keyAppendix;
-  ATH_CHECK( m_massRespKey.initialize() );
-  m_ptRefKey = m_jetContainerKey1.key()+".ptRef_" + keyAppendix;
-  ATH_CHECK( m_ptRefKey.initialize() );
-  m_etaRefKey = m_jetContainerKey1.key()+".etaRef_" + keyAppendix;
-  ATH_CHECK( m_etaRefKey.initialize() );
-  m_matchedKey = m_jetContainerKey1.key()+".matched_" + keyAppendix;
-  ATH_CHECK( m_matchedKey.initialize() );
-  
+  if (m_jetContainerKey1.key() != "NONE" && m_l1jetContainerKey1.key() != "NONE") {
+    ATH_MSG_ERROR(" Both JetContainerKey1 and L1JetContainerKey1 were set, but we can only use one of them for jet matching. Fix your settings!");
+    return StatusCode::FAILURE;
+  }
+
+  std::string prepend, keyAppendix = m_jetContainerKey2.key();
+  if (!m_matchL1) {
+    if (m_calibScale != "") keyAppendix = m_calibScale + "_" + m_jetContainerKey2.key();
+    prepend = m_jetContainerKey1.key();
+    
+    m_ptDiffKey = prepend+".ptdiff_" + keyAppendix;
+    m_energyDiffKey = prepend+".energydiff_" + keyAppendix;
+    m_massDiffKey = prepend+".massdiff_" + keyAppendix;
+    m_ptRespKey = prepend+".ptresp_" + keyAppendix;
+    m_energyRespKey = prepend+".energyresp_" + keyAppendix;
+    m_massRespKey = prepend+".massresp_" + keyAppendix;
+    m_ptRefKey = prepend+".ptRef_" + keyAppendix;
+    m_etaRefKey = prepend+".etaRef_" + keyAppendix;
+    m_matchedKey = prepend+".matched_" + keyAppendix;
+
+    ATH_CHECK( m_ptDiffKey.initialize() );
+    ATH_CHECK( m_energyDiffKey.initialize() );
+    ATH_CHECK( m_massDiffKey.initialize() );
+    ATH_CHECK( m_ptRespKey.initialize() );
+    ATH_CHECK( m_energyRespKey.initialize() );
+    ATH_CHECK( m_massRespKey.initialize() );
+    ATH_CHECK( m_ptRefKey.initialize() );
+    ATH_CHECK( m_etaRefKey.initialize() );
+    ATH_CHECK( m_matchedKey.initialize() );
+
+    m_jetVarHandleKeys.push_back(m_ptDiffKey);
+    m_jetVarHandleKeys.push_back(m_energyDiffKey);
+    m_jetVarHandleKeys.push_back(m_massDiffKey);
+    m_jetVarHandleKeys.push_back(m_ptRespKey);
+    m_jetVarHandleKeys.push_back(m_energyRespKey);
+    m_jetVarHandleKeys.push_back(m_massRespKey);
+    m_jetVarHandleKeys.push_back(m_ptRefKey);
+    m_jetVarHandleKeys.push_back(m_etaRefKey);
+
+  } else {
+    prepend = m_l1jetContainerKey1.key();
+
+    m_l1ptDiffKey = prepend+".ptdiff_" + keyAppendix;
+    m_l1energyDiffKey = prepend+".energydiff_" + keyAppendix;
+    m_l1massDiffKey = prepend+".massdiff_" + keyAppendix;
+    m_l1ptRespKey = prepend+".ptresp_" + keyAppendix;
+    m_l1energyRespKey = prepend+".energyresp_" + keyAppendix;
+    m_l1massRespKey = prepend+".massresp_" + keyAppendix;
+    m_l1ptRefKey = prepend+".ptRef_" + keyAppendix;
+    m_l1etaRefKey = prepend+".etaRef_" + keyAppendix;
+    m_l1matchedKey = prepend+".matched_" + keyAppendix;
+
+    ATH_CHECK( m_l1ptDiffKey.initialize() );
+    ATH_CHECK( m_l1energyDiffKey.initialize() );
+    ATH_CHECK( m_l1massDiffKey.initialize() );
+    ATH_CHECK( m_l1ptRespKey.initialize() );
+    ATH_CHECK( m_l1energyRespKey.initialize() );
+    ATH_CHECK( m_l1massRespKey.initialize() );
+    ATH_CHECK( m_l1ptRefKey.initialize() );
+    ATH_CHECK( m_l1etaRefKey.initialize() );
+    ATH_CHECK( m_l1matchedKey.initialize() );
+
+    m_l1JetVarHandleKeys.push_back(m_l1ptDiffKey);
+    m_l1JetVarHandleKeys.push_back(m_l1energyDiffKey);
+    m_l1JetVarHandleKeys.push_back(m_l1massDiffKey);
+    m_l1JetVarHandleKeys.push_back(m_l1ptRespKey);
+    m_l1JetVarHandleKeys.push_back(m_l1energyRespKey);
+    m_l1JetVarHandleKeys.push_back(m_l1massRespKey);
+    m_l1JetVarHandleKeys.push_back(m_l1ptRefKey);
+    m_l1JetVarHandleKeys.push_back(m_l1etaRefKey);
+
+  }
+
   return StatusCode::SUCCESS;
 }
 
@@ -56,57 +109,61 @@ StatusCode JetMatcherAlg::finalize() {
 
 //**********************************************************************
 
-StatusCode JetMatcherAlg::execute(const EventContext& ctx) const {
-
-  // Retrieve jet containers
-  SG::ReadHandle<xAOD::JetContainer> jets1(m_jetContainerKey1, ctx);
-  if (!jets1.isValid() ) {
-    ATH_MSG_ERROR("evtStore() does not contain jet Collection with name "<< m_jetContainerKey1);
-    return StatusCode::FAILURE;
-  }
-  SG::ReadHandle<xAOD::JetContainer> jets2(m_jetContainerKey2, ctx);
-  if (!jets2.isValid() ) {
-    ATH_MSG_ERROR("evtStore() does not contain jet Collection with name "<< m_jetContainerKey2);
-    return StatusCode::FAILURE;
+TLorentzVector JetMatcherAlg::GetTLV(const xAOD::Jet* jet) const {
+
+  TLorentzVector tlv = TLorentzVector(0.,0.,0.,0.);
+  if (m_calibScale == "" ) {
+    tlv.SetPtEtaPhiE(jet->pt(),jet->eta(),jet->phi(),jet->e());
+  } else { //retrieve fourmomentum at specified calibration scale
+    xAOD::JetFourMom_t fourVec;
+    bool status = jet->getAttribute<xAOD::JetFourMom_t>( "Jet"+m_calibScale+"Momentum", fourVec );
+    if(!status) {
+      ATH_MSG_ERROR("evtStore() cannot retrieve JetFourMomentum at " << m_calibScale);
+      return tlv;
+    }
+    tlv.SetPtEtaPhiE(fourVec.Pt(),fourVec.Eta(),fourVec.Phi(),fourVec.E());
   }
+  return tlv;
+}
+
+TLorentzVector JetMatcherAlg::GetTLV(const xAOD::JetRoI* jet) const {
+
+  TLorentzVector tlv = TLorentzVector(0.,0.,0.,0.);
+  tlv.SetPtEtaPhiM(jet->et8x8(),jet->eta(),jet->phi(),0.);
+  return tlv;
+}
+
+//**********************************************************************
 
-  SG::WriteDecorHandle<xAOD::JetContainer, double> ptDiffHandle(m_ptDiffKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> energyDiffHandle(m_energyDiffKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> massDiffHandle(m_massDiffKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> ptRespHandle(m_ptRespKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> energyRespHandle(m_energyRespKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> massRespHandle(m_massRespKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> ptRefHandle(m_ptRefKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, double> etaRefHandle(m_etaRefKey, ctx);
-  SG::WriteDecorHandle<xAOD::JetContainer, char> matchedHandle(m_matchedKey, ctx);
+template <typename T>
+void JetMatcherAlg::jetMatching(SG::ReadHandle<DataVector<T>> jets1, SG::ReadHandle<xAOD::JetContainer> jets2, SG::WriteDecorHandleKey<DataVector<T>> matchedHandleKey, std::vector<SG::WriteDecorHandleKey<DataVector<T>>> varHandleKeys, const EventContext& ctx) const{
 
+  SG::WriteDecorHandle<DataVector<T>, double> ptDiffHandle(varHandleKeys[0], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> energyDiffHandle(varHandleKeys[1], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> massDiffHandle(varHandleKeys[2], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> ptRespHandle(varHandleKeys[3], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> energyRespHandle(varHandleKeys[4], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> massRespHandle(varHandleKeys[5], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> ptRefHandle(varHandleKeys[6], ctx);
+  SG::WriteDecorHandle<DataVector<T>, double> etaRefHandle(varHandleKeys[7], ctx);
+  SG::WriteDecorHandle<DataVector<T>, char> matchedHandle(matchedHandleKey, ctx);
 
   std::vector<int> matchedIndices; //remembers which jets in jets2 are already matched, so they are not considered in future matching
   // Loop over first jet collection
-  for(const xAOD::Jet* j1 : *jets1){
+  for (const T *j1 : *jets1) {
+    TLorentzVector tlvjet1 = GetTLV(j1);
     bool j1matched = false;
     double ptDiff  = 0., energyDiff = 0., massDiff = 0., ptResp = 0., energyResp = 0., massResp = 0., ptRef = 0., etaRef = 0.;
-    auto tlvjet1 = TLorentzVector();
-    if (m_calibScale == "" ) tlvjet1.SetPtEtaPhiE(j1->pt(),j1->eta(),j1->phi(),j1->e());
-    else { //retrieve fourmomentum at specified calibration scale
-      xAOD::JetFourMom_t fourVec;
-      bool status = j1->getAttribute<xAOD::JetFourMom_t>( "Jet"+m_calibScale+"Momentum", fourVec );
-      if(!status) {
-        ATH_MSG_ERROR("evtStore() cannot retrieve JetFourMomentum at " << m_calibScale);
-        return StatusCode::FAILURE;
-      }
-      tlvjet1.SetPtEtaPhiE(fourVec.Pt(),fourVec.Eta(),fourVec.Phi(),fourVec.E());
-    }
-    // Loop over second jet collectoin
     double Rmin = 1E8;
     int jetIndex = 0, jetMatchIndex = 0;
+    // Loop over second jet collection
     for(const xAOD::Jet* j2 : *jets2){
       bool alreadymatched = false;
       for (int jetIndexIterator : matchedIndices) { //Loop over indices of already matched jets to skip them
         if (jetIndex == jetIndexIterator) { alreadymatched = true; break; }
       }
       if (alreadymatched) { jetIndex++; continue; }
-      auto tlvjet2 = TLorentzVector();
+      TLorentzVector tlvjet2 = TLorentzVector();
       tlvjet2.SetPtEtaPhiE(j2->pt(),j2->eta(),j2->phi(),j2->e());
       // calculate DeltaR(jet1,jet2)
       double dr = tlvjet1.DeltaR(tlvjet2);
@@ -135,7 +192,37 @@ StatusCode JetMatcherAlg::execute(const EventContext& ctx) const {
     ptRefHandle(*j1)      = ptRef;
     etaRefHandle(*j1)     = etaRef;
     if (j1matched) matchedIndices.push_back(jetMatchIndex);
-  }//End Loop over first jet collection
+  }
+  return;
+
+}
+
+//**********************************************************************
+
+
+StatusCode JetMatcherAlg::execute(const EventContext& ctx) const {
+
+  // Retrieve jet containers and call appropriate matching function
+  SG::ReadHandle<xAOD::JetContainer> jets2(m_jetContainerKey2, ctx);
+  if (!jets2.isValid() ) {
+    ATH_MSG_ERROR("evtStore() does not contain jet Collection with name "<< m_jetContainerKey2);
+    return StatusCode::FAILURE;
+  }
+  if (!m_matchL1) { // perform jet matching for online/offline jets
+    SG::ReadHandle<xAOD::JetContainer> jets1(m_jetContainerKey1, ctx);
+    if (!jets1.isValid() ) {
+      ATH_MSG_ERROR("evtStore() does not contain jet Collection with name "<< m_jetContainerKey1);
+      return StatusCode::FAILURE;
+    }
+    jetMatching(jets1, jets2, m_matchedKey, m_jetVarHandleKeys, ctx);
+  } else { // perform jet matching for L1 jets
+    SG::ReadHandle<xAOD::JetRoIContainer> jets1(m_l1jetContainerKey1, ctx);
+    if (!jets1.isValid() ) {
+      ATH_MSG_ERROR("evtStore() does not contain L1 jet Collection with name "<< m_l1jetContainerKey1);
+      return StatusCode::FAILURE;
+    }
+    jetMatching(jets1, jets2, m_l1matchedKey, m_l1JetVarHandleKeys, ctx);
+  }
 
   return StatusCode::SUCCESS;
 
diff --git a/Reconstruction/Jet/JetMonitoring/src/JetMonitoringAlg.cxx b/Reconstruction/Jet/JetMonitoring/src/JetMonitoringAlg.cxx
index aa7f07482a89..4dbf3e80535a 100644
--- a/Reconstruction/Jet/JetMonitoring/src/JetMonitoringAlg.cxx
+++ b/Reconstruction/Jet/JetMonitoring/src/JetMonitoringAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetMonitoring/JetMonitoringAlg.h"
diff --git a/Trigger/TrigMonitoring/TrigJetMonitoring/python/L1JetMonitoringConfig.py b/Trigger/TrigMonitoring/TrigJetMonitoring/python/L1JetMonitoringConfig.py
index 6d711a8fc05a..1fb432010de7 100644
--- a/Trigger/TrigMonitoring/TrigJetMonitoring/python/L1JetMonitoringConfig.py
+++ b/Trigger/TrigMonitoring/TrigJetMonitoring/python/L1JetMonitoringConfig.py
@@ -1,18 +1,23 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
 class L1JetMonAlg():
-  def __init__(self,name,jetcoll,triggerChain=''):
+  def __init__(self,name,jetcoll,triggerChain='',matched=False,matchedOfflineJets='',matchedHLTJets=''):
     self.name           = name
     self.L1JetContainer = jetcoll
     self.TriggerChain   = triggerChain
+    self.Matched        = matched
+    self.MatchedOJ      = matchedOfflineJets
+    self.MatchedHLTJ    = matchedHLTJets
 
   def toAlg(self,monhelper):
     from AthenaConfiguration.ComponentFactory import CompFactory
     alg = monhelper.addAlgorithm(CompFactory.TrigL1JetMonitorAlgorithm, self.name)
     jetcontainer       = self.L1JetContainer
     triggerChain       = self.TriggerChain
+    ismatched          = self.Matched
     alg.L1JetContainer = jetcontainer
     alg.TriggerChain   = triggerChain
+    alg.IsMatched      = ismatched
     # Add a generic monitoring tool (a "group" in old language). The returned 
     # object here is the standard GenericMonitoringTool
     myGroup = monhelper.addGroup(alg,'TrigL1JetMonitor','HLT/JetMon/L1/')
@@ -22,4 +27,21 @@ class L1JetMonAlg():
     myGroup.defineHistogram('et8x8',title='et8x8',path=Path,xbins=400,xmin=0.0,xmax=400.0)
     myGroup.defineHistogram('eta',title='eta',path=Path,xbins=50,xmin=-5,xmax=5)
     myGroup.defineHistogram('phi',title='phi',path=Path,xbins=50,xmin=-3.3,xmax=3.3)
+
+    # Add histograms for L1 jets matched to offline/online jets
+    if ismatched:
+      matchedOJ   = self.MatchedOJ
+      matchedHLTJ = self.MatchedHLTJ
+      alg.MatchedOfflineJets = matchedOJ
+      alg.MatchedHLTJets     = matchedHLTJ
+      for matchcoll,tag in [ [matchedOJ, 'off'], [matchedHLTJ, 'hlt'] ]:
+        Path = jetcontainer + '/NoTriggerSelection/MatchedJets_' + matchcoll + '/'
+        for histname in [ 'ptdiff', 'energydiff' ]: #defines which variable difference will be plotted, mass difference makes no sense for L1 as m=0
+          myGroup.defineHistogram(tag+histname+';'+histname,title=histname, type="TH1F", path=Path, xbins=140 , xmin=-120000., xmax=20000. ,)
+        for histname in [ 'ptresp', 'energyresp' ]:
+          myGroup.defineHistogram(tag+histname+';'+histname,title=histname, type="TH1F", path=Path, xbins=100 , xmin=-1., xmax=1. ,)
+        myGroup.defineHistogram(tag+'ptresp,'+tag+'ptref;ptresp_vs_ptRef',title='ptresponse vs ptRef', type="TH2F", path=Path, xbins=10 , xmin=-1., xmax=1., ybins=10, ymin=0., ymax=500000.,)
+        myGroup.defineHistogram(tag+'ptresp,'+tag+'etaref;ptresp_vs_etaRef',title='ptresponse vs etaRef', type="TH2F", path=Path, xbins=10 , xmin=-1., xmax=1., ybins=10, ymin=-5., ymax=5.,)
+
+
     return alg
diff --git a/Trigger/TrigMonitoring/TrigJetMonitoring/python/TrigJetMonitorAlgorithm.py b/Trigger/TrigMonitoring/TrigJetMonitoring/python/TrigJetMonitorAlgorithm.py
index f25a8b77e4e1..5bb1e4deb638 100644
--- a/Trigger/TrigMonitoring/TrigJetMonitoring/python/TrigJetMonitorAlgorithm.py
+++ b/Trigger/TrigMonitoring/TrigJetMonitoring/python/TrigJetMonitorAlgorithm.py
@@ -23,7 +23,10 @@ OfflineJetCollections = {
 # L1 jet collections and chains to monitor
 ###########################################
 
-L1JetCollections = ['LVL1JetRoIs']
+L1JetCollections = dict()
+L1JetCollections = {
+  'LVL1JetRoIs'  : { 'MatchTo' : ['AntiKt4EMPFlowJets','HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf'] },
+}
 Chain2L1JetCollDict = { # set L1 jet collection name for L1 jet chains
   'L1_J15'  : 'LVL1JetRoIs',
   'L1_J20'  : 'LVL1JetRoIs',
@@ -193,8 +196,8 @@ def TrigJetMonConfig(inputFlags):
   for hltColl,collDict in JetCollections[InputType].items():
     if collDict['MatchTo'] != 'NONE':
       for jetcalibscale in OnlineScaleMomenta:
-        scalestring = jetcalibscale if jetcalibscale == "" else "_"+jetcalibscale
-        name = 'Matching_{}_{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
+        scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
+        name = 'Matching_{}{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
         alg = CompFactory.JetMatcherAlg(name, JetContainerName1=hltColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
         cfg.addEventAlgo(alg)
 
@@ -202,11 +205,19 @@ def TrigJetMonConfig(inputFlags):
   for offjetColl,collDict in OfflineJetCollections.items():
     if collDict['MatchTo'] != 'NONE':
       for jetcalibscale in OfflineScaleMomenta:
-        scalestring = jetcalibscale if jetcalibscale == "" else "_"+jetcalibscale
-        name = 'Matching_{}_{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
+        scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
+        name = 'Matching_{}{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
         alg = CompFactory.JetMatcherAlg(name, JetContainerName1=offjetColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
         cfg.addEventAlgo(alg)
 
+  # Match L1 to offline as well as HLT jets
+  for l1jetColl,collDict in L1JetCollections.items():
+    for matchjetcoll in collDict['MatchTo']:
+      if matchjetcoll != 'NONE':
+        name = 'Matching_{}_{}'.format(l1jetColl,matchjetcoll)
+        alg = CompFactory.JetMatcherAlg(name, L1JetContainerName1=l1jetColl,JetContainerName2=matchjetcoll,MatchL1=True)
+        cfg.addEventAlgo(alg)
+
   # The following class will make a sequence, configure algorithms, and link
   # them to GenericMonitoringTools
   from AthenaMonitoring import AthMonitorCfgHelper
@@ -214,7 +225,7 @@ def TrigJetMonConfig(inputFlags):
 
   # Loop over L1 jet collectoins
   for jetcoll in L1JetCollections:
-    l1jetconf = l1JetMonitoringConfig(ConfigFlags,jetcoll)
+    l1jetconf = l1JetMonitoringConfig(ConfigFlags,jetcoll,'',True)
     l1jetconf.toAlg(helper)
 
   # Loop over L1 jet chains
@@ -419,10 +430,10 @@ def jetMonitoringConfig(inputFlags,jetcoll,athenaMT):
 
    return conf
 
-def l1JetMonitoringConfig(inputFlags,jetcoll,chain=''):
+def l1JetMonitoringConfig(inputFlags,jetcoll,chain='',matched=False):
   from TrigJetMonitoring.L1JetMonitoringConfig import L1JetMonAlg
   name = jetcoll if chain=='' else jetcoll+'_'+chain
-  conf = L1JetMonAlg(name,jetcoll,chain)
+  conf = L1JetMonAlg(name,jetcoll,chain,matched,L1JetCollections[jetcoll]['MatchTo'][0],L1JetCollections[jetcoll]['MatchTo'][1])
   return conf
 
 def jetChainMonitoringConfig(inputFlags,jetcoll,chain,athenaMT,onlyUsePassingJets=True):
@@ -684,8 +695,8 @@ if __name__=='__main__':
   for hltColl,collDict in JetCollections[InputType].items():
     if collDict['MatchTo'] != 'NONE':
       for jetcalibscale in OnlineScaleMomenta:
-        scalestring = jetcalibscale if jetcalibscale == "" else "_"+jetcalibscale
-        name = 'Matching_{}_{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
+        scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
+        name = 'Matching_{}{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
         alg = CompFactory.JetMatcherAlg(name, JetContainerName1=hltColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
         cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm') # Add matchers to monitoring alg sequence
 
@@ -693,14 +704,22 @@ if __name__=='__main__':
   for offjetColl,collDict in OfflineJetCollections.items():
     if collDict['MatchTo'] != 'NONE':
       for jetcalibscale in OfflineScaleMomenta:
-        scalestring = jetcalibscale if jetcalibscale == "" else "_"+jetcalibscale
-        name = 'Matching_{}_{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
+        scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
+        name = 'Matching_{}{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
         alg = CompFactory.JetMatcherAlg(name, JetContainerName1=offjetColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
-        cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm') # Add matchers to monitoring alg sequence
-
+        cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm')
+
+  # Match L1 to offline as well as HLT jets
+  for l1jetColl,collDict in L1JetCollections.items():
+    for matchjetcoll in collDict['MatchTo']:
+      if matchjetcoll != 'NONE':
+        name = 'Matching_{}_{}'.format(l1jetColl,matchjetcoll)
+        alg = CompFactory.JetMatcherAlg(name, L1JetContainerName1=l1jetColl,JetContainerName2=matchjetcoll,MatchL1=True)
+        cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm')
+  
   # Loop over L1 jet collectoins
   for jetcoll in L1JetCollections:
-    l1jetconf = l1JetMonitoringConfig(ConfigFlags,jetcoll)
+    l1jetconf = l1JetMonitoringConfig(ConfigFlags,jetcoll,'',True)
     l1jetconf.toAlg(helper)
 
   # Loop over L1 jet chains
diff --git a/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.cxx b/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.cxx
index 37046c78952e..a1b9a77006bd 100644
--- a/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.cxx
@@ -3,6 +3,7 @@
 */
 
 #include "TrigL1JetMonitorAlgorithm.h"
+#include "AsgDataHandles/ReadDecorHandle.h"
 
 TrigL1JetMonitorAlgorithm::TrigL1JetMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
   : AthMonitorAlgorithm(name,pSvcLocator)
@@ -14,9 +15,124 @@ TrigL1JetMonitorAlgorithm::~TrigL1JetMonitorAlgorithm() {}
 
 StatusCode TrigL1JetMonitorAlgorithm::initialize() {
   ATH_CHECK(m_l1jetContainerkey.initialize());
+  if (m_isMatched) {
+    m_offmatchedKey = m_l1jetContainerkey.key() + ".matched_" + m_matchedOfflineJetContainer;
+    m_offptdiffKey = m_l1jetContainerkey.key() + ".ptdiff_" + m_matchedOfflineJetContainer;
+    m_offenergydiffKey = m_l1jetContainerkey.key() + ".energydiff_" + m_matchedOfflineJetContainer;
+    m_offmassdiffKey = m_l1jetContainerkey.key() + ".massdiff_" + m_matchedOfflineJetContainer;
+    m_offptrespKey = m_l1jetContainerkey.key() + ".ptresp_" + m_matchedOfflineJetContainer;
+    m_offenergyrespKey = m_l1jetContainerkey.key() + ".energyresp_" + m_matchedOfflineJetContainer;
+    m_offmassrespKey = m_l1jetContainerkey.key() + ".massresp_" + m_matchedOfflineJetContainer;
+    m_offptrefKey = m_l1jetContainerkey.key() + ".ptRef_" + m_matchedOfflineJetContainer;
+    m_offetarefKey = m_l1jetContainerkey.key() + ".etaRef_" + m_matchedOfflineJetContainer;
+    ATH_CHECK( m_offmatchedKey.initialize() );
+    ATH_CHECK( m_offptdiffKey.initialize() );
+    ATH_CHECK( m_offenergydiffKey.initialize() );
+    ATH_CHECK( m_offmassdiffKey.initialize() );
+    ATH_CHECK( m_offptrespKey.initialize() );
+    ATH_CHECK( m_offenergyrespKey.initialize() );
+    ATH_CHECK( m_offmassrespKey.initialize() );
+    ATH_CHECK( m_offptrefKey.initialize() );
+    ATH_CHECK( m_offetarefKey.initialize() );
+
+    m_hltmatchedKey = m_l1jetContainerkey.key() + ".matched_" + m_matchedHLTJetContainer;
+    m_hltptdiffKey = m_l1jetContainerkey.key() + ".ptdiff_" + m_matchedHLTJetContainer;
+    m_hltenergydiffKey = m_l1jetContainerkey.key() + ".energydiff_" + m_matchedHLTJetContainer;
+    m_hltmassdiffKey = m_l1jetContainerkey.key() + ".massdiff_" + m_matchedHLTJetContainer;
+    m_hltptrespKey = m_l1jetContainerkey.key() + ".ptresp_" + m_matchedHLTJetContainer;
+    m_hltenergyrespKey = m_l1jetContainerkey.key() + ".energyresp_" + m_matchedHLTJetContainer;
+    m_hltmassrespKey = m_l1jetContainerkey.key() + ".massresp_" + m_matchedHLTJetContainer;
+    m_hltptrefKey = m_l1jetContainerkey.key() + ".ptRef_" + m_matchedHLTJetContainer;
+    m_hltetarefKey = m_l1jetContainerkey.key() + ".etaRef_" + m_matchedHLTJetContainer;
+    ATH_CHECK( m_hltmatchedKey.initialize() );
+    ATH_CHECK( m_hltptdiffKey.initialize() );
+    ATH_CHECK( m_hltenergydiffKey.initialize() );
+    ATH_CHECK( m_hltmassdiffKey.initialize() );
+    ATH_CHECK( m_hltptrespKey.initialize() );
+    ATH_CHECK( m_hltenergyrespKey.initialize() );
+    ATH_CHECK( m_hltmassrespKey.initialize() );
+    ATH_CHECK( m_hltptrefKey.initialize() );
+    ATH_CHECK( m_hltetarefKey.initialize() );
+  }
   return AthMonitorAlgorithm::initialize();
 }
 
+void TrigL1JetMonitorAlgorithm::fillMatchedHistograms(const xAOD::JetRoIContainer & jets, const EventContext& ctx) const {
+
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, char>  offmatchedHandle(m_offmatchedKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offptdiffHandle(m_offptdiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offenergydiffHandle(m_offenergydiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offmassdiffHandle(m_offmassdiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offptrespHandle(m_offptrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offenergyrespHandle(m_offenergyrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offmassrespHandle(m_offmassrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offptrefHandle(m_offptrefKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> offetarefHandle(m_offetarefKey, ctx);
+
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, char>  hltmatchedHandle(m_hltmatchedKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltptdiffHandle(m_hltptdiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltenergydiffHandle(m_hltenergydiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltmassdiffHandle(m_hltmassdiffKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltptrespHandle(m_hltptrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltenergyrespHandle(m_hltenergyrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltmassrespHandle(m_hltmassrespKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltptrefHandle(m_hltptrefKey, ctx);
+  SG::ReadDecorHandle<xAOD::JetRoIContainer, double> hltetarefHandle(m_hltetarefKey, ctx);
+
+  auto offmatched = Monitored::Collection("offmatched", jets, [offmatchedHandle](const xAOD::JetRoI * jet) {return offmatchedHandle(*jet);}); 
+  auto offdPt = Monitored::Scalar("offptdiff",0.0);
+  auto offdEnergy = Monitored::Scalar("offenergydiff",0.0);
+  auto offdMass = Monitored::Scalar("offmassdiff",0.0);
+  auto offrPt = Monitored::Scalar("offptresp",0.0);
+  auto offrEnergy = Monitored::Scalar("offenergyresp",0.0);
+  auto offrMass = Monitored::Scalar("offmassresp",0.0);
+  auto offptRef = Monitored::Scalar("offptref",0.0);
+  auto offetaRef = Monitored::Scalar("offetaref",0.0);
+
+  auto hltmatched = Monitored::Collection("hltmatched", jets, [hltmatchedHandle](const xAOD::JetRoI * jet) {return hltmatchedHandle(*jet);}); 
+  auto hltdPt = Monitored::Scalar("hltptdiff",0.0);
+  auto hltdEnergy = Monitored::Scalar("hltenergydiff",0.0);
+  auto hltdMass = Monitored::Scalar("hltmassdiff",0.0);
+  auto hltrPt = Monitored::Scalar("hltptresp",0.0);
+  auto hltrEnergy = Monitored::Scalar("hltenergyresp",0.0);
+  auto hltrMass = Monitored::Scalar("hltmassresp",0.0);
+  auto hltptRef = Monitored::Scalar("hltptref",0.0);
+  auto hltetaRef = Monitored::Scalar("hltetaref",0.0);
+
+  // Loop over L1 jets and fill pt, energy, mass differences and responses between matched jets, plus reference pT and eta
+  auto tool = getGroup("TrigL1JetMonitor");
+  for(const xAOD::JetRoI* jet : jets){
+    bool offmatched = offmatchedHandle(*jet);
+    bool hltmatched = hltmatchedHandle(*jet);
+    if(offmatched){
+      offdPt = offptdiffHandle(*jet);
+      offdEnergy = offenergydiffHandle(*jet);
+      offdMass = offmassdiffHandle(*jet);
+      offrPt = offptrespHandle(*jet);
+      offrEnergy = offenergyrespHandle(*jet);
+      offrMass = offmassrespHandle(*jet);
+      offptRef = offptrefHandle(*jet);
+      offetaRef = offetarefHandle(*jet);
+      fill(tool, offdPt, offdEnergy, offdMass, offrPt, offrEnergy, offrMass, offptRef, offetaRef);
+    } 
+    if(hltmatched){
+      hltdPt = hltptdiffHandle(*jet);
+      hltdEnergy = hltenergydiffHandle(*jet);
+      hltdMass = hltmassdiffHandle(*jet);
+      hltrPt = hltptrespHandle(*jet);
+      hltrEnergy = hltenergyrespHandle(*jet);
+      hltrMass = hltmassrespHandle(*jet);
+      hltptRef = hltptrefHandle(*jet);
+      hltetaRef = hltetarefHandle(*jet);
+      fill(tool, hltdPt, hltdEnergy, hltdMass, hltrPt, hltrEnergy, hltrMass, hltptRef, hltetaRef);
+    } 
+  }
+  fill(tool,offmatched);
+  fill(tool,hltmatched);
+
+  return;
+}
+
 StatusCode TrigL1JetMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
   using namespace Monitored;
 
@@ -43,6 +159,14 @@ StatusCode TrigL1JetMonitorAlgorithm::fillHistograms( const EventContext& ctx )
     auto tool = getGroup("TrigL1JetMonitor");
     fill(tool,et8x8,eta,phi);
   }
+  // Adding histograms for L1 jets matched to offline/online jets
+  if (m_isMatched) {
+    // turn SG::ReadHandle<xAOD::JetRoIContainer> into xAOD::JetRoIContainer to be able to use Monitored::Collection on the L1 jet collection
+    ConstDataVector< xAOD::JetRoIContainer > tmpCont(SG::VIEW_ELEMENTS);
+    for(const xAOD::JetRoI* l1jet : *jets ) tmpCont.push_back(l1jet);
+    const xAOD::JetRoIContainer *l1JetContainer = tmpCont.asDataVector();
+    fillMatchedHistograms(*l1JetContainer, ctx);
+  }
 
   return StatusCode::SUCCESS;
 }
diff --git a/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.h b/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.h
index a5e049789c45..b24c0ff6b8bc 100644
--- a/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.h
+++ b/Trigger/TrigMonitoring/TrigJetMonitoring/src/TrigL1JetMonitorAlgorithm.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGJETMONITORING_TRIGL1JETMONITORALGORITHM_H
@@ -8,7 +8,7 @@
 #include "AthenaMonitoring/AthMonitorAlgorithm.h"
 #include "AthenaMonitoringKernel/Monitored.h"
 #include "xAODTrigger/JetRoIContainer.h"
-
+#include "AsgDataHandles/ReadDecorHandleKey.h"
 
 class TrigL1JetMonitorAlgorithm : public AthMonitorAlgorithm {
  public:
@@ -16,8 +16,34 @@ class TrigL1JetMonitorAlgorithm : public AthMonitorAlgorithm {
   virtual ~TrigL1JetMonitorAlgorithm();
   virtual StatusCode initialize() override;
   virtual StatusCode fillHistograms( const EventContext& ctx ) const override;
+  void fillMatchedHistograms(const xAOD::JetRoIContainer & jets, const EventContext& ctx) const ;
 
   // Name of the L1 jet collection to be monitored
   SG::ReadHandleKey<xAOD::JetRoIContainer> m_l1jetContainerkey;
+  // Variables to add matched histograms
+  Gaudi::Property<bool> m_isMatched {this, "IsMatched", false, "Plotting response histograms for L1 jets matched to online/offline jets"};
+  Gaudi::Property<std::string> m_matchedOfflineJetContainer {this, "MatchedOfflineJets", "", "Name of matched offline jet collection"};
+  Gaudi::Property<std::string> m_matchedHLTJetContainer {this, "MatchedHLTJets", "", "Name of matched HLT jet collection"};
+
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offmatchedKey{this, "offmatched", "offmatched", "SG key for input matched decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offptdiffKey{this, "offptdiff", "offptdiff", "SG key for input matched ptdiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offenergydiffKey{this, "offenergydiff", "offenergydiff", "SG key for input matched energydiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offmassdiffKey{this, "offmassdiff", "offmassdiff", "SG key for input matched massdiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offptrespKey{this, "offptresp", "offptresp", "SG key for input matched ptresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offenergyrespKey{this, "offenergyresp", "offenergyresp", "SG key for input matched energyresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offmassrespKey{this, "offmassresp", "offmassresp", "SG key for input matched massresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offptrefKey{this, "offptref", "offptref", "SG key for input matched ptref decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_offetarefKey{this, "offetaref", "offetaref", "SG key for input matched etaref decoration"};
+
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltmatchedKey{this, "hltmatched", "hltmatched", "SG key for input matched decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltptdiffKey{this, "hltptdiff", "hltptdiff", "SG key for input matched ptdiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltenergydiffKey{this, "hltenergydiff", "hltenergydiff", "SG key for input matched energydiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltmassdiffKey{this, "hltmassdiff", "hltmassdiff", "SG key for input matched massdiff decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltptrespKey{this, "hltptresp", "hltptresp", "SG key for input matched ptresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltenergyrespKey{this, "hltenergyresp", "hltenergyresp", "SG key for input matched energyresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltmassrespKey{this, "hltmassresp", "hltmassresp", "SG key for input matched massresp decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltptrefKey{this, "hltptref", "hltptref", "SG key for input matched ptref decoration"};
+  SG::ReadDecorHandleKey<xAOD::JetRoIContainer> m_hltetarefKey{this, "hltetaref", "hltetaref", "SG key for input matched etaref decoration"};
+
 };
 #endif
-- 
GitLab