From c2652398fd0b077bfbc50c24e90a551700057893 Mon Sep 17 00:00:00 2001
From: Joergen Sjoelin <sjolin@fysik.su.se>
Date: Fri, 7 Oct 2016 22:39:12 +0200
Subject: [PATCH] cmx/topo matching with cpu id, fix timing ratio
 (TrigT1Monitoring-00-05-26)

        * L1CaloL1TopoMon:
	  - CMX<->Topo matching plots include FPGA
	* Tag as TrigT1Monitoring-00-05-26

2016-09-27 Kate Whalen <kate.whalen@cern.ch>
        * L1CaloCTPMon:
	  - Fix compilation warnings
	* Tag as TrigT1Monitoring-00-05-25

2016-09-26 Kate Whalen <kate.whalen@cern.ch>
        * L1CaloL1TopoMon:
	  - New EM, Tau, Jet TOB matching plots
	* CalorimeterL1CaloMon:
	  - Coverity bugfix #111085
	* Tag as TrigT1Monitoring-00-05-24
---
 .../TrigT1Monitoring_forRecExCommission.py    |   2 +-
 .../src/CalorimeterL1CaloMon.cxx              |  12 +-
 .../TrigT1Monitoring/src/L1CaloCTPMon.cxx     |  18 +-
 .../TrigT1Monitoring/src/L1CaloCTPMon.h       |   9 +-
 .../TrigT1Monitoring/src/L1CaloL1TopoMon.cxx  | 332 ++++++++++++++----
 .../TrigT1Monitoring/src/L1CaloL1TopoMon.h    |  29 +-
 6 files changed, 307 insertions(+), 95 deletions(-)

diff --git a/Trigger/TrigT1/TrigT1Monitoring/share/TrigT1Monitoring_forRecExCommission.py b/Trigger/TrigT1/TrigT1Monitoring/share/TrigT1Monitoring_forRecExCommission.py
index b584179b420..9be51b2a57a 100644
--- a/Trigger/TrigT1/TrigT1Monitoring/share/TrigT1Monitoring_forRecExCommission.py
+++ b/Trigger/TrigT1/TrigT1Monitoring/share/TrigT1Monitoring_forRecExCommission.py
@@ -106,7 +106,7 @@ if l1caloRawMon:
         ToolSvc += L1CaloPMTScoresMonTool
         L1Man.AthenaMonTools += [ L1CaloPMTScoresMonTool ]
 
-    if isData and DQMonFlags.doCTPMon():
+    if isData and DQMonFlags.doCTPMon(): # KW this is not set in online environment!  Investigate!
 
         ####################### L1Calo->CTP ################################
         from IOVDbSvc.CondDB import conddb
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/CalorimeterL1CaloMon.cxx b/Trigger/TrigT1/TrigT1Monitoring/src/CalorimeterL1CaloMon.cxx
index 3d19c8de43e..7a03f561ad9 100644
--- a/Trigger/TrigT1/TrigT1Monitoring/src/CalorimeterL1CaloMon.cxx
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/CalorimeterL1CaloMon.cxx
@@ -1014,10 +1014,10 @@ StatusCode CalorimeterL1CaloMon::fillHistograms()
           }
 
           /*if (had_L1CaloE == 0 && had_caloE > 5) {           // KW commenting out for now... will never be filled with new ET cut
-            m_histTool->fillPPMEmEtaVsPhi(m_h_had_Mismatch_etaphi, eta, phi);
+            m_histTool->fillPPMHadEtaVsPhi(m_h_had_Mismatch_etaphi, eta, phi);
           }
           if (had_L1CaloE > 5 && had_caloE == 0) {
-            m_histTool->fillPPMEmEtaVsPhi(m_h_had_Mismatch_etaphi_alt, eta, phi);
+            m_histTool->fillPPMHadEtaVsPhi(m_h_had_Mismatch_etaphi_alt, eta, phi);
           }*/
 
           if (absEta < 0.9) {
@@ -1068,14 +1068,14 @@ StatusCode CalorimeterL1CaloMon::fillHistograms()
               m_h_had_profile_Match_CP->Fill(had_L1CaloE_CP, hadRelDiffE_CP);
               m_h_had_profile_etaRegion_CP->Fill(eta, hadRelDiffE_CP);
               m_histTool->fillPPMPhi(m_h_had_profile_phiRegion_CP, eta, phi, hadRelDiffE_CP);
-	      m_histTool->fillPPMEmEtaVsPhi(m_h_average_hadDE_map_CP, eta, phi, hadRelDiffE_CP);
+	      m_histTool->fillPPMHadEtaVsPhi(m_h_average_hadDE_map_CP, eta, phi, hadRelDiffE_CP);
            // }
 	  }  
           /*if (had_L1CaloE_CP == 0 && had_caloE > 5) {     // KW commenting out for now... will never be filled with new ET cut
-            m_histTool->fillPPMEmEtaVsPhi(m_h_had_Mismatch_etaphi_CP, eta, phi);
+            m_histTool->fillPPMHadEtaVsPhi(m_h_had_Mismatch_etaphi_CP, eta, phi);
           }
           if (had_L1CaloE_CP > 5 && had_caloE == 0) {
-            m_histTool->fillPPMEmEtaVsPhi(m_h_had_Mismatch_etaphi_alt_CP, eta, phi);
+            m_histTool->fillPPMHadEtaVsPhi(m_h_had_Mismatch_etaphi_alt_CP, eta, phi);
           }*/
 
           if (absEta < 0.9) {
@@ -1166,7 +1166,7 @@ StatusCode CalorimeterL1CaloMon::fillHistograms()
     m_histTool->fillPPMEmEtaVsPhi(m_h_emTTME_etaphi_CP, eta_max_em_CP, phi_max_em_CP);
   }
   if (eta_max_had_CP != -10) {
-    m_histTool->fillPPMEmEtaVsPhi(m_h_hadTTME_etaphi_CP, eta_max_had_CP, phi_max_had_CP);
+    m_histTool->fillPPMHadEtaVsPhi(m_h_hadTTME_etaphi_CP, eta_max_had_CP, phi_max_had_CP);
   }
 
   return StatusCode::SUCCESS;     
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.cxx b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.cxx
index a1457ffb6c9..1c6fa4116d1 100755
--- a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.cxx
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.cxx
@@ -66,7 +66,13 @@ L1CaloCTPMon::L1CaloCTPMon( const std::string & type, const std::string & name,
     m_h_ctp_1d_TIPMatches(0),
     m_h_ctp_1d_HitNoTIPMismatch(0),
     m_h_ctp_1d_TIPNoHitMismatch(0),
-    m_h_ctp_2d_MismatchEvents(0)
+    m_h_ctp_2d_MismatchEvents(0),
+    m_h_ctp_1d_EM_HitNoTIPMismatch(0),
+    m_h_ctp_1d_TAU_HitNoTIPMismatch(0),
+    m_h_ctp_1d_JET_HitNoTIPMismatch(0),
+    m_h_ctp_1d_TE_HitNoTIPMismatch(0),
+    m_h_ctp_1d_XE_HitNoTIPMismatch(0),
+    m_h_ctp_1d_XS_HitNoTIPMismatch(0)
 /*---------------------------------------------------------*/
 {
   // This is how you declare the parameters to Gaudi so that
@@ -218,7 +224,7 @@ StatusCode L1CaloCTPMon::bookHistogramsRecurrent()
 
         while (true) {
           if ( (*it)->type() == def.emType() ) {
-            if (threshNumber >= def.max_EM_Threshold_Number()/2) {  // Cable EM2; else cable EM1
+            if (threshNumber >= (int)def.max_EM_Threshold_Number()/2) {  // Cable EM2; else cable EM1
               offset += nbits*def.max_EM_Threshold_Number()/2;
               fixedThreshNumber -= def.max_EM_Threshold_Number()/2;
             }
@@ -226,7 +232,7 @@ StatusCode L1CaloCTPMon::bookHistogramsRecurrent()
           }
           offset += nbits*def.max_EM_Threshold_Number(); 
           if ( (*it)->type() == def.tauType() ) {
-            if (threshNumber >= def.max_TAU_Threshold_Number()/2) { // Cable TAU2; else cable TAU1
+            if (threshNumber >= (int)def.max_TAU_Threshold_Number()/2) { // Cable TAU2; else cable TAU1
               offset += nbits*def.max_TAU_Threshold_Number()/2;
               fixedThreshNumber -= def.max_TAU_Threshold_Number()/2;
             }
@@ -234,7 +240,7 @@ StatusCode L1CaloCTPMon::bookHistogramsRecurrent()
           }
           offset += nbits*def.max_TAU_Threshold_Number(); 
           if ( (*it)->type() == def.jetType() ) {
-            if (threshNumber >= max_JET_3bit_Threshold_Number) {   // Cable JET2 (2-bit thresholds); else JET1 (3-bit)
+            if (threshNumber >= (int)max_JET_3bit_Threshold_Number) {   // Cable JET2 (2-bit thresholds); else JET1 (3-bit)
               offset += 3*max_JET_3bit_Threshold_Number;
               fixedThreshNumber -= max_JET_3bit_Threshold_Number;
               nbits--;
@@ -246,7 +252,7 @@ StatusCode L1CaloCTPMon::bookHistogramsRecurrent()
           offset += 2*max_JET_2bit_Threshold_Number;
           nbits--;
           if ( (*it)->type() == def.teType()) {
-            if (threshNumber >= def.max_TE_Threshold_Number()/2) {  // Restricted eta TE threshold: jump to cable EN2
+            if (threshNumber >= (int)def.max_TE_Threshold_Number()/2) {  // Restricted eta TE threshold: jump to cable EN2
               offset += nbits*def.max_TE_Threshold_Number()/2 + nbits*def.max_XE_Threshold_Number()/2 + nbits*def.max_XS_Threshold_Number(); // 8+8+8 bits on cable EN1
               fixedThreshNumber -= def.max_TE_Threshold_Number()/2;
             }
@@ -254,7 +260,7 @@ StatusCode L1CaloCTPMon::bookHistogramsRecurrent()
           }
           offset += nbits*def.max_TE_Threshold_Number()/2; 
           if ( (*it)->type() == def.xeType() ) {
-            if (threshNumber >= def.max_XE_Threshold_Number()/2) { // Restricted eta XE threshold: jump to cable EN2
+            if (threshNumber >= (int)def.max_XE_Threshold_Number()/2) { // Restricted eta XE threshold: jump to cable EN2
               offset += nbits*def.max_TE_Threshold_Number()/2 + nbits*def.max_XE_Threshold_Number()/2 + nbits*def.max_XS_Threshold_Number();
               fixedThreshNumber -= def.max_XE_Threshold_Number()/2;
             }
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.h b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.h
index cf1f1d325cf..12f620ef17c 100755
--- a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.h
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloCTPMon.h
@@ -186,7 +186,14 @@ private:
    TH1F_LW* m_h_ctp_1d_HitNoTIPMismatch;   ///< L1Calo Hit but no CTP TIP Mismatches
    TH1F_LW* m_h_ctp_1d_TIPNoHitMismatch;   ///< CTP TIP but no L1Calo Hit Mismatches
    TH2I_LW* m_h_ctp_2d_MismatchEvents;     ///< Transmission Errors between L1Calo and CTP Event Numbers
-
+   TH1F_LW* m_h_ctp_1d_EM_HitNoTIPMismatch;  ///< L1Calo hit but no CTP TIP mismatches (EM thresholds
+   TH1F_LW* m_h_ctp_1d_TAU_HitNoTIPMismatch; ///< L1Calo hit but no CTP TIP mismatches (TAU thresholds)
+   TH1F_LW* m_h_ctp_1d_JET_HitNoTIPMismatch; ///< L1Calo hit but no CTP TIP mismatches (JET thresholds)
+   TH1F_LW* m_h_ctp_1d_TE_HitNoTIPMismatch;  ///< L1Calo hit but no CTP TIP mismatches (TE thresholds)
+   TH1F_LW* m_h_ctp_1d_XE_HitNoTIPMismatch;  ///< L1Calo hit but no CTP TIP mismatches (XE thresholds)
+   TH1F_LW* m_h_ctp_1d_XS_HitNoTIPMismatch;  ///< L1Calo hit but no CTP TIP mismatches (XS thresholds)
+   
+   
 };
 // ============================================================================
 }  // end namespace
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
index 9442fbabbee..f1b73b88962 100755
--- a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.cxx
@@ -15,7 +15,8 @@
 
 #include <map>
 #include <utility>
-
+#include <set>
+#include <tuple>
 #include <algorithm>
 #include <vector>
 #include <iomanip>
@@ -35,8 +36,12 @@
 #include "TrigT1Interfaces/TrigT1CaloDefs.h"
 #include "TrigT1Interfaces/FrontPanelCTP.h"
 #include "TrigT1Interfaces/TrigT1StoreGateKeys.h"
+#include "TrigT1Interfaces/CoordinateRange.h"
+#include "TrigT1Interfaces/CPRoIDecoder.h"
+#include "TrigT1Interfaces/JEPRoIDecoder.h"
 
 #include "xAODTrigL1Calo/CMXJetTobContainer.h"
+#include "xAODTrigL1Calo/CMXCPTobContainer.h"
 #include "TrigT1Result/CTP_RDO.h"
 #include "TrigT1Result/CTP_Decoder.h"
 #include "TrigT1Result/RoIBResult.h"
@@ -88,8 +93,10 @@ L1CaloL1TopoMon::L1CaloL1TopoMon( const std::string & type,
     m_h_l1topo_1d_CMXTobs(0),
     m_h_l1topo_1d_Simulation(0),
     m_h_l1topo_1d_JetTobs_EnergyLg(0),
-    m_h_l1topo_2d_JetTobs_Hitmap_mismatch(0),
-    m_h_l1topo_2d_JetTobs_Hitmap_match(0),
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch{},
+    m_h_l1topo_2d_Tobs_Hitmap_match{},
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch{},
+    m_h_l1topo_2d_Tobs_etaPhi_match{},
     m_h_l1topo_1d_Errors(0),
     m_h_l1topo_1d_DAQTobs(0),
     m_h_l1topo_1d_DAQJetTobs(0),
@@ -99,8 +106,10 @@ L1CaloL1TopoMon::L1CaloL1TopoMon( const std::string & type,
     m_h_l1topo_1d_DAQTriggerBits(0),
     m_h_l1topo_1d_DAQMismatchTriggerBits(0),
     m_h_l1topo_1d_DAQOverflowBits(0),
-    m_h_l1topo_1d_ROITobs(0)
-
+    m_h_l1topo_1d_ROITobs(0),
+    m_h_l1topo_2d_ItemsBC{},
+    m_h_l1topo_2d_ItemsBC_ratio{}
+  
 
     /*---------------------------------------------------------*/
 {
@@ -112,6 +121,8 @@ L1CaloL1TopoMon::L1CaloL1TopoMon( const std::string & type,
 		   m_PathInRootFile= "LVL1_Interfaces/L1Topo");
   declareProperty( "CMXJetTobLocation", m_CMXJetTobLocation
 		   = LVL1::TrigT1CaloDefs::CMXJetTobLocation);
+  declareProperty( "CMXCPTobLocation", m_CMXCPTobLocation
+		   = LVL1::TrigT1CaloDefs::CMXCPTobLocation);
   declareProperty( "TopoCTPLocation", m_topoCTPLoc
 		   = LVL1::DEFAULT_L1TopoCTPLocation, 
 		   "StoreGate location of topo inputs" );
@@ -210,13 +221,74 @@ StatusCode L1CaloL1TopoMon::bookHistogramsRecurrent()
       m_histTool->book1F("l1topo_1d_Simulation",
 			 "Simulated L1Topo trigger bits", 128, 0, 128);
 
-    m_h_l1topo_2d_JetTobs_Hitmap_mismatch = m_histTool->
-      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetTobs_Hitmap_mismatch",
-				   "Mismatched L1Topo-Jet TOBs Hit Map");
-    m_h_l1topo_2d_JetTobs_Hitmap_match = m_histTool->
-      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetTobs_Hitmap_match",
-				   "CMX-matched L1Topo-Jet TOBs Hit Map");
-
+    //---- eta phi ----
+    
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch[JETS_TOB] = m_histTool->
+      bookJEMRoIEtaVsPhi("l1topo_2d_JetSTobs_etaPhi_mismatch",
+			 "CMX-L1Topo mismatched small jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_match[JETS_TOB] = m_histTool->
+      bookJEMRoIEtaVsPhi("l1topo_2d_JetSTobs_etaPhi_match",
+			 "CMX-L1Topo matched small jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch[JETL_TOB] = m_histTool->
+      bookJEMRoIEtaVsPhi("l1topo_2d_JetLTobs_etaPhi_mismatch",
+			 "CMX-L1Topo mismatched large jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_match[JETL_TOB] = m_histTool->
+      bookJEMRoIEtaVsPhi("l1topo_2d_JetLTobs_etaPhi_match",
+			 "CMX-L1Topo matched large jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch[TAU_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_TauTobs_etaPhi_mismatch",
+		      "CMX-L1Topo mismatched tau TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_match[TAU_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_TauTobs_etaPhi_match",
+		      "CMX-L1Topo matched tau TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch[EM_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_EMTobs_etaPhi_mismatch",
+		      "CMX-L1Topo mismatched EM TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_match[EM_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_EMTobs_etaPhi_match",
+		      "CMX-L1Topo matched EM TOBs hit map");    
+    m_h_l1topo_2d_Tobs_etaPhi_mismatch[MU_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_MuTobs_etaPhi_mismatch",
+		      "CMX-L1Topo mismatched muon TOBs hit map");
+    m_h_l1topo_2d_Tobs_etaPhi_match[MU_TOB] = m_histTool->
+      bookCPMEtaVsPhi("l1topo_2d_MuTobs_etaPhi_match",
+		      "CMX-L1Topo matched muon TOBs hit map");
+    
+    // ---- hardware coordinates ----
+
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch[JETS_TOB] = m_histTool->
+      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetSTobs_Hitmap_mismatch",
+				   "CMX-L1Topo mismatched small jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_match[JETS_TOB] = m_histTool->
+      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetSTobs_Hitmap_match",
+				   "CMX-L1Topo matched small jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch[JETL_TOB] = m_histTool->
+      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetLTobs_Hitmap_mismatch",
+				   "CMX-L1Topo mismatched large jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_match[JETL_TOB] = m_histTool->
+      bookJEMCrateModuleVsFrameLoc("l1topo_2d_JetLTobs_Hitmap_match",
+				   "CMX-L1Topo matched large jet TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch[TAU_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_TauTobs_Hitmap_mismatch",
+					    "CMX-L1Topo mismatched tau TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_match[TAU_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_TauTobs_Hitmap_match",
+					    "CMX-L1Topo matched tau TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch[EM_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_EMTobs_Hitmap_mismatch",
+					    "CMX-L1Topo mismatched EM TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_match[EM_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_EMTobs_Hitmap_match",
+					    "CMX-L1Topo matched EM TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_mismatch[MU_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_MuTobs_Hitmap_mismatch",
+					    "CMX-L1Topo mismatched muon TOBs hit map");
+    m_h_l1topo_2d_Tobs_Hitmap_match[MU_TOB] = m_histTool->
+      bookCPMCrateModuleVsTobChipLocalCoord("l1topo_2d_MuTobs_Hitmap_match",
+					    "CMX-L1Topo matched muon TOBs hit map");
+
+    // --------
+    
     m_h_l1topo_1d_JetTobs_EnergyLg = m_histTool->
       book1F("l1topo_1d_JetTobs_EnergyLg",
 	     "L1Topo-Jet TOB Energy Large Window Size", 256, 0., 1024);
@@ -267,7 +339,13 @@ StatusCode L1CaloL1TopoMon::bookHistogramsRecurrent()
 			     std::string("Timing vs "
 					 "Algorithm Number ")+textFPGA[i],
 			     32, i*32, (i+1)*32, 3, -1.5, 1.5);
-      m_h_l1topo_2d_ItemsBC_ratio[i] =
+      m_h_l1topo_2d_ItemsBC_ratio[i][0] =
+	m_histTool->bookTH2F(std::string("l1topo_2d_ItemsBC_online_ratio")+
+			     std::to_string(i),
+			     std::string("(online) Timing Ratio vs "
+					 "Algorithm Number ")+textFPGA[i],
+			     32, i*32, (i+1)*32, 3, -1.5, 1.5);
+      m_h_l1topo_2d_ItemsBC_ratio[i][1] =
 	m_histTool->bookTH2F(std::string("l1topo_2d_ItemsBC_ratio")+
 			     std::to_string(i),
 			     std::string("Timing Ratio vs "
@@ -336,8 +414,10 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 
   StatusCode sc = StatusCode::SUCCESS;
 
-  std::vector<xAOD::CMXJetTob*> cmxtobs;  
-
+  typedef std::tuple<int,int,int,int,int,int> TobKey;
+  std::set<TobKey> cmxKeys[TOB_TYPES],topoKeys[TOB_TYPES],
+    keyDiff[TOB_TYPES],keyIntersect[TOB_TYPES];
+    
   // Validate properly unpacked input from L1Calo
   if (m_errorTool->corrupt() || m_errorTool->robOrUnpackingError()) {
     if (m_debug) msg(MSG::DEBUG) << "Corrupt L1Calo event" << endreq;
@@ -393,8 +473,34 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
     }
   }
   
-  // Retrieve CMX tobs
-  bool cmx_ematch=true;
+  // Retrieve CMX CP tobs
+  const DataHandle<xAOD::CMXCPTobContainer> cmxcptob = 0;
+  sc = evtStore()->retrieve(cmxcptob);
+  if (sc.isFailure() || !cmxcptob) {
+    ATH_MSG_DEBUG ("No CMX CP tobs found in TES");
+    //m_h_l1topo_1d_Errors->Fill(NO_CMX_CP);
+  }   
+  else {
+    ATH_MSG_DEBUG( "Found CMXCPTobCollection, looping on TOBs ..." );
+    for (auto & t : *cmxcptob) {
+      if (t->energy()) {
+	for (int clone=0;clone<4;++clone) {
+	  if (t->cmx()==0)
+	    cmxKeys[TAU_TOB].insert(std::make_tuple(t->crate(),t->cpm(),
+						    t->chip(),t->location(),
+						    t->energy(),clone));
+	  else
+	    cmxKeys[EM_TOB].insert(std::make_tuple(t->crate(),t->cpm(),
+						    t->chip(),t->location(),
+						    t->energy(),clone));
+	}
+      }
+    }
+    //m_h_l1topo_1d_CMXCPTobs->Fill(std::min((int)cmxtobs.size(),MAXTOBS-1));
+  }
+  
+  std::vector<xAOD::CMXJetTob*> cmxtobs;  
+  // Retrieve CMX jet tobs
   const DataHandle<xAOD::CMXJetTobContainer> cmxtob = 0;
   sc = evtStore()->retrieve(cmxtob);
   if (sc.isFailure() || !cmxtob) {
@@ -403,15 +509,22 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
   }   
   else {
     ATH_MSG_DEBUG( "Found CMXJetTobCollection, looping on TOBs ..." );
-    for (auto & tob : *cmxtob) {
-      if (tob->energyLarge()) {
-	cmxtobs.push_back(tob);
+    for (auto & t : *cmxtob) {
+      if (t->energyLarge()) cmxtobs.push_back(t);
+      for (int clone=0;clone<4;++clone) {
+	if (t->energyLarge())
+	  cmxKeys[JETL_TOB].insert(std::make_tuple(t->crate(),t->jem(),
+						   t->frame(),t->location(),
+						   t->energyLarge(),clone));
+	if (t->energySmall())
+	  cmxKeys[JETS_TOB].insert(std::make_tuple(t->crate(),t->jem(),
+						   t->frame(),t->location(),
+						   t->energySmall(),clone));
       }
     }
     m_h_l1topo_1d_CMXTobs->Fill(std::min((int)cmxtobs.size(),MAXTOBS-1));
-    
   }
-
+  
   // Retrieve L1Topo CTP simulted decision if present
   if (!evtStore()->contains<LVL1::FrontPanelCTP>(m_topoCTPLoc.value())){
     ATH_MSG_INFO("Could not retrieve LVL1::FrontPanelCTP with key "
@@ -505,6 +618,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
       // initialise header: beware, this can make a valid-looking header
       //   set version 15, BCN -7, which is unlikely:
       L1Topo::Header header(0xf, 0, 0, 0, 0, 1, 0x7);
+      int i_fpga=-1;
       for (auto word : cDataWords){
 	switch (L1Topo::blockType(word)){
 	case L1Topo::BlockTypes::HEADER:
@@ -513,6 +627,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 	    if (header.payload_crc()!=0) {
 	      m_h_l1topo_1d_Errors->Fill(PAYL_CRC);
 	    }
+	    i_fpga=(((rdo->getSourceID())>>3)&2)+header.fpga();
 	    break;
 	  }
 	case L1Topo::BlockTypes::FIBRE:
@@ -554,59 +669,60 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 	case L1Topo::BlockTypes::JET1_TOB:
 	case L1Topo::BlockTypes::JET2_TOB:
 	  {
-	    if (header.bcn_offset()==0){
+	    if (header.bcn_offset()==0) {
 	      const int crate    = (word >> 28) & 0x1;
 	      const int jem      = (word >> 24) & 0xF;
 	      const int frame    = (word >> 21) & 0x7;
 	      const int location = (word >> 19) & 0x3;
-	      const int energyL  = (word & 0x3FF);
-	      const int x = crate*16 + jem;
-	      const int y = frame*4 + location;
-	      //auto tob = L1Topo::JetTOB(word);
-	      //daqJetTobs.push_back(tob);
-	      int tob = 1; // Fake object until defined
+	      const int energyS  = (word >> 10) & 0x1FF;
+	      const int energyL  = (word & 0x3FF);	      
 	      if (energyL) {
+		topoKeys[JETL_TOB].insert(std::make_tuple(crate,jem,frame,
+							  location,energyL,i_fpga));
+		//auto tob = L1Topo::JetTOB(word);
+		int tob = 1; // Fake object until defined
 		daqJetTobs.push_back(tob);
 		m_h_l1topo_1d_JetTobs_EnergyLg->Fill(energyL,1./NFPGA);
-		bool match=false;
-		bool ematch=false;
-		for (auto & t : cmxtobs) {
-		  const int cmx_x = t->crate()*16 + t->jem();
-		  const int cmx_y = t->frame()*4 + t->location();
-		  if (x==cmx_x && y==cmx_y && energyL==t->energyLarge())
-		    match=true;
-		  if (energyL==t->energyLarge())
-		    ematch=true;
-		}
-		if (!ematch) cmx_ematch=false;
-		if (match)
-		  m_h_l1topo_2d_JetTobs_Hitmap_match->Fill(x, y, 1./NFPGA);
-		else
-		  m_h_l1topo_2d_JetTobs_Hitmap_mismatch->Fill(x, y, 1./NFPGA);
+	      }
+	      if (energyS) {
+		topoKeys[JETS_TOB].insert(std::make_tuple(crate,jem,frame,
+							  location,energyS,i_fpga));
 	      }
 	    }
 	    break;
 	  }
-
-
 	case L1Topo::BlockTypes::TAU_TOB:
-    {
-      if (header.bcn_offset()==0){
-        int tob = 1; // Fake object until defined
-        daqTauTobs.push_back(tob);
-      }
-      break;
-    }
-
-  case L1Topo::BlockTypes::EM_TOB:
-    {
-      if (header.bcn_offset()==0){
-        int tob = 1; // Fake object until defined
-        daqEMTobs.push_back(tob);
-      }
-      break;
-    }
-
+	  {
+	    if (header.bcn_offset()==0) {
+	      int tob = 1; // Fake object until defined
+	      daqTauTobs.push_back(tob);
+	      const int crate    = (word >> 26) & 0x3;
+	      const int cpm      = (word >> 20) & 0xF;
+	      const int chip     = (word >> 15) & 0xF;
+	      const int location = (word >> 13) & 0x3;
+	      const int energy   = (word & 0xFF);	      
+	      if (energy)
+		topoKeys[TAU_TOB].insert(std::make_tuple(crate,cpm,chip,location,
+							 energy,i_fpga));
+	    }
+	    break;
+	  }	  
+	case L1Topo::BlockTypes::EM_TOB:
+	  {
+	    if (header.bcn_offset()==0) {
+	      int tob = 1; // Fake object until defined
+	      daqEMTobs.push_back(tob);
+	      const int crate    = (word >> 26) & 0x3;
+	      const int cpm      = (word >> 20) & 0xF;
+	      const int chip     = (word >> 15) & 0xF;
+	      const int location = (word >> 13) & 0x3;
+	      const int energy   = (word & 0xFF);
+	      if (energy)
+		topoKeys[EM_TOB].insert(std::make_tuple(crate,cpm,chip,
+							location,energy,i_fpga));
+	    }
+	    break;
+	  }
 	case L1Topo::BlockTypes::MUON_TOB:
 	  {
 	    if (header.bcn_offset()==0){
@@ -686,7 +802,7 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
     }
   }
   m_h_l1topo_1d_ROITobs->Fill(std::min((int)roiTobs.size(),19));
-
+  
   for (unsigned int i=1; i<=128;++i) {
     float diff=fabs(m_h_l1topo_1d_DAQTriggerBits->GetBinContent(i)-
 		    m_h_l1topo_1d_Simulation->GetBinContent(i));
@@ -694,8 +810,47 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
       m_h_l1topo_1d_DAQMismatchTriggerBits->SetBinContent(i,diff);
   }
 
-  if (!cmx_ematch) m_h_l1topo_1d_Errors->Fill(CMX_EMATCH);
-
+  // look in both directions for CMX and Topo TOBs (mis)matches
+  for (int t=0; t<TOB_TYPES; ++t) { 
+    set_symmetric_difference(cmxKeys[t].begin(),cmxKeys[t].end(),
+			     topoKeys[t].begin(),topoKeys[t].end(),
+			     inserter(keyDiff[t],keyDiff[t].begin()));
+    if (keyDiff[t].size()>0) m_h_l1topo_1d_Errors->Fill(CMX_MATCH);
+    for (auto& tob : keyDiff[t]) {
+      int x,y;
+      double eta,phi;
+      if (t==JETS_TOB || t==JETL_TOB) {
+	jem2Coord(std::get<0>(tob),std::get<1>(tob),std::get<2>(tob),std::get<3>(tob),
+		  x,y,eta,phi);
+	m_histTool->fillJEMRoIEtaVsPhi(m_h_l1topo_2d_Tobs_etaPhi_mismatch[t],eta,phi);
+      }
+      else {
+	cpm2Coord(std::get<0>(tob),std::get<1>(tob),std::get<2>(tob),std::get<3>(tob),
+		  x,y,eta,phi);
+	m_histTool->fillCPMRoIEtaVsPhi(m_h_l1topo_2d_Tobs_etaPhi_mismatch[t],eta,phi);
+      }
+      m_h_l1topo_2d_Tobs_Hitmap_mismatch[t]->Fill(x,y);
+    }
+    set_intersection(cmxKeys[t].begin(),cmxKeys[t].end(),
+		     topoKeys[t].begin(),topoKeys[t].end(),
+		     inserter(keyIntersect[t],keyIntersect[t].begin()));
+    for (auto& tob : keyIntersect[t]) {
+      int x,y;
+      double eta,phi;
+      if (t==JETS_TOB || t==JETL_TOB) {
+	jem2Coord(std::get<0>(tob),std::get<1>(tob),std::get<2>(tob),std::get<3>(tob),
+		  x,y,eta,phi);
+	m_histTool->fillJEMRoIEtaVsPhi(m_h_l1topo_2d_Tobs_etaPhi_match[t],eta,phi);
+      }
+      else {
+	cpm2Coord(std::get<0>(tob),std::get<1>(tob),std::get<2>(tob),std::get<3>(tob),
+		  x,y,eta,phi);
+	m_histTool->fillCPMRoIEtaVsPhi(m_h_l1topo_2d_Tobs_etaPhi_match[t],eta,phi);
+      }
+      m_h_l1topo_2d_Tobs_Hitmap_match[t]->Fill(x,y);
+    }
+  }
+  
   return StatusCode::SUCCESS;
 }
 
@@ -703,29 +858,31 @@ StatusCode L1CaloL1TopoMon::fillHistograms()
 StatusCode L1CaloL1TopoMon::procHistograms()
 /*---------------------------------------------------------*/
 {
-  if ( endOfLumiBlock ) {
+  if ( endOfLumiBlock ) { }  
+  if ( endOfRun ) { }
+  
+  if ( endOfLumiBlock || endOfRun ) {
+    int eor=(endOfRun ? 1 : 0);
     for (int cpu=0; cpu<=3; ++cpu) {
       for (int item=1; item<=32; ++item) {
 	for (int bc=1; bc<=3; ++bc) {
 	  if (m_h_l1topo_2d_ItemsBC[cpu]->GetBinContent(item,bc)<0);
-	    //m_h_l1topo_2d_ItemsBC_ratio[cpu]->SetBinContent(item,bc,-0.4);
+	  //m_h_l1topo_2d_ItemsBC_ratio[cpu]->SetBinContent(item,bc,-0.4);
 	  else if (m_h_l1topo_2d_ItemsBC[cpu]->GetBinContent(item,bc)==0)
-	    m_h_l1topo_2d_ItemsBC_ratio[cpu]->SetBinContent(item,bc,0.0001);
+	    m_h_l1topo_2d_ItemsBC_ratio[cpu][eor]->SetBinContent(item,bc,0.0001);
 	  else if (bc==2)
-	    m_h_l1topo_2d_ItemsBC_ratio[cpu]->SetBinContent(item,bc,1);
+	    m_h_l1topo_2d_ItemsBC_ratio[cpu][eor]->SetBinContent(item,bc,1);
 	  else {
 	    float ratio=m_h_l1topo_2d_ItemsBC[cpu]->
 	      GetBinContent(item,bc)/(float)
 	      m_h_l1topo_2d_ItemsBC[cpu]->GetBinContent(item,2);
-	    m_h_l1topo_2d_ItemsBC_ratio[cpu]->
+	    m_h_l1topo_2d_ItemsBC_ratio[cpu][eor]->
 	      SetBinContent(item,bc,fmax(0.05,ratio));
 	  }
 	}
       }
     }
   }
-  
-  if ( endOfRun ) { }
 
   return StatusCode::SUCCESS;
 }
@@ -734,4 +891,33 @@ StatusCode L1CaloL1TopoMon::procHistograms()
 // Private Methods
 // *********************************************************************
 
+void L1CaloL1TopoMon::jem2Coord(const int crate, const int jem,
+	       const int frame, const int location,
+	       int &x, int &y, double &eta, double &phi)
+{
+  x = crate*16 + jem;
+  y = frame*4 + location;
+  const uint32_t roiWord = // formula from JEPSimMon
+    ((((((crate << 4) + jem) << 3) + frame) << 2) + location) << 19;
+  LVL1::JEPRoIDecoder decoder;
+  const LVL1::CoordinateRange coord(decoder.coordinate(roiWord));
+  eta = coord.eta();
+  phi = coord.phi();
+}
+
+void L1CaloL1TopoMon::cpm2Coord(const int crate, const int cpm,
+	       const int chip, const int location,
+	       int &x, int &y, double &eta, double &phi)
+{
+  x = crate*14 + cpm - 1;
+  y = chip*4 + location;
+  const uint32_t roiWord = // formula from CPSimMon
+    ((((((crate << 4) + cpm) << 4) + chip) << 2)
+     + location) << 18;
+  LVL1::CPRoIDecoder decoder;
+    const LVL1::CoordinateRange coord(decoder.coordinate(roiWord));
+    eta = coord.eta();
+    phi = coord.phi();
+}    
+
 }
diff --git a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.h b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.h
index cac2d03b327..343e1ae8fa5 100755
--- a/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.h
+++ b/Trigger/TrigT1/TrigT1Monitoring/src/L1CaloL1TopoMon.h
@@ -59,15 +59,25 @@ class TrigT1CaloLWHistogramTool;
 
   enum ERROR_BIT {CALO_CONV=0, NO_CMX, DAQ_CONV, NO_DAQ, ROI_CONV,
 		  NO_ROI, F_OVERFLOW,
-		  F_CRC, PAYL_CRC, CMX_EMATCH, NUMBEROFBITS};
+		  F_CRC, PAYL_CRC, CMX_MATCH, NUMBEROFBITS};
+
+  enum TOB_TYPE {JETL_TOB=0, JETS_TOB, TAU_TOB, EM_TOB, MU_TOB};
   
   std::vector<std::string> ERROR_LABELS{"Calo conv","No CMX","DAQ conv",
       "No DAQ","ROI conv","No ROI","Fibre Overf","Fibre CRC",
-      "Payload CRC","CMX ematch"};
+      "Payload CRC","CMX-Topo match"};
   
  private:
   
-  const int MAXTOBS=30;
+  void jem2Coord(const int crate, const int jem,
+		 const int frame, const int location,
+		 int &x, int &y, double &eta, double &phi);
+  void cpm2Coord(const int crate, const int cpm,
+		 const int chip, const int location,
+		 int &x, int &y, double &eta, double &phi);
+  
+  static const int TOB_TYPES=5;
+  static const int MAXTOBS=30;
   /// Trigger configuration service
    ServiceHandle<TrigConf::ITrigConfigSvc> m_configSvc;
    /// Corrupt events tool
@@ -77,6 +87,7 @@ class TrigT1CaloLWHistogramTool;
    /// Output from L1Topo
    //const DataHandle< LVL1::FrontPanelCTP > m_topoCTP;
    StringProperty m_CMXJetTobLocation;
+   StringProperty m_CMXCPTobLocation;
    StringProperty m_topoCTPLoc;
 
    /// Root directory
@@ -92,8 +103,10 @@ class TrigT1CaloLWHistogramTool;
    TH1F_LW* m_h_l1topo_1d_CMXTobs;
    TH1F_LW* m_h_l1topo_1d_Simulation;
    TH1F_LW* m_h_l1topo_1d_JetTobs_EnergyLg;
-   TH2F_LW* m_h_l1topo_2d_JetTobs_Hitmap_mismatch;
-   TH2F_LW* m_h_l1topo_2d_JetTobs_Hitmap_match;
+   TH2F_LW* m_h_l1topo_2d_Tobs_Hitmap_mismatch[TOB_TYPES];
+   TH2F_LW* m_h_l1topo_2d_Tobs_Hitmap_match[TOB_TYPES];
+   TH2F_LW* m_h_l1topo_2d_Tobs_etaPhi_mismatch[TOB_TYPES];
+   TH2F_LW* m_h_l1topo_2d_Tobs_etaPhi_match[TOB_TYPES];
    TH1F_LW* m_h_l1topo_1d_Errors;
    TH1F_LW* m_h_l1topo_1d_DAQTobs;
    TH1F_LW* m_h_l1topo_1d_DAQJetTobs;
@@ -105,10 +118,10 @@ class TrigT1CaloLWHistogramTool;
    TH1F_LW* m_h_l1topo_1d_DAQOverflowBits;
    TH1F_LW* m_h_l1topo_1d_ROITobs;
    TH2F*    m_h_l1topo_2d_ItemsBC[4];
-   TH2F*    m_h_l1topo_2d_ItemsBC_ratio[4];
+   TH2F*    m_h_l1topo_2d_ItemsBC_ratio[4][2];
 };
-
-// ============================================================================
+ 
+ // ============================================================================
 }  // end namespace
 // ============================================================================
 
-- 
GitLab