diff --git a/InnerDetector/InDetExample/InDetRecExample/share/InDetMonitoringPixel.py b/InnerDetector/InDetExample/InDetRecExample/share/InDetMonitoringPixel.py
index 12e28bd78ac5140ace0ccfef1a6e75ea21f9e724..5e12c1b905164a80d25333378cb19d2b34f59a0c 100644
--- a/InnerDetector/InDetExample/InDetRecExample/share/InDetMonitoringPixel.py
+++ b/InnerDetector/InDetExample/InDetRecExample/share/InDetMonitoringPixel.py
@@ -23,27 +23,25 @@ from PixelMonitoring.PixelAthErrorMonAlgCfg import PixelAthErrorMonAlgCfg
 from InDetRecExample.InDetKeys import InDetKeys                                                                                     
 
 kwargsHitMonAlg = { 'doOnline'        : True if athenaCommonFlags.isOnline() else False,      #Histograms for online (athenaPT) running
-                     'doModules'       : True if athenaCommonFlags.isOnline() else False, #Turn on/off the sets of 1744 module histograms (for dqmf)
                      'doLumiBlock'     : False if athenaCommonFlags.isOnline() else True,       #Turn on/off histograms stored for each lumi block
                      'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam                    
                      'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
                      'doHeavyIonMon'   : InDetFlags.doHeavyIon(),   # Histogram modification for heavy ion monitoring
+                     'doFEPlots'       : False,       #Turn on/off histograms with FE Status information
                      'RDOName'         : InDetKeys.PixelRDOs()
 }
 
 kwargsClusMonAlg = { 'doOnline'        : True if athenaCommonFlags.isOnline() else False,      #Histograms for online (athenaPT) running
-                      'doModules'       : True if athenaCommonFlags.isOnline() else False, #Turn on/off the sets of 1744 module histograms (for dqmf)
                       'doLumiBlock'     : False if athenaCommonFlags.isOnline() else True,       #Turn on/off histograms stored for each lumi block
                       'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam
                       'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
                       'doHeavyIonMon'   : InDetFlags.doHeavyIon(),   # Histogram modification for heavy ion monitoring
-                      #                  'doStatus'        : True,       #Turn on/off histograms with Module Status information
+                      'doFEPlots'       : False,       #Turn on/off histograms with FE Status information
                       'ClusterName'     : InDetKeys.PixelClusters(),
                       'TrackName'       : InDetKeys.Tracks()
 }
 
 kwargsErrMonAlg = { 'doOnline'        : True if athenaCommonFlags.isOnline() else False,      #Histograms for online (athenaPT) running
-                     'doModules'       : True if athenaCommonFlags.isOnline() else False, #Turn on/off the sets of 1744 module histograms (for dqmf)
                      'doLumiBlock'     : False if athenaCommonFlags.isOnline() else True,       #Turn on/off histograms stored for each lumi block
                      'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam                    
                      'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthClusterMonAlgCfg.py b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthClusterMonAlgCfg.py
index e36e202417a2b5b83724f25a3a4c7ee8dd638467..63e2f31534a0944b6bf8234b9b54809cf7391ffe 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthClusterMonAlgCfg.py
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthClusterMonAlgCfg.py
@@ -7,7 +7,7 @@
 @brief Configuration of Pixel Monitoring Clusters, Tracks and Status Histograms for Run 3
 '''
 
-from PixelMonitoring.PixelAthMonitoringBase import define2DProfHist, definePP0Histos
+from PixelMonitoring.PixelAthMonitoringBase import define2DProfHist, define2DProfPerFEHist, definePP0Histos
 from PixelMonitoring.PixelAthMonitoringBase import define1DLayers, defineMapVsLumiLayers
 from PixelMonitoring.PixelAthMonitoringBase import define1DProfLumiLayers
 from PixelMonitoring.PixelAthMonitoringBase import layers, totcuts, xbinsem, xminsem, lumibinsx, ztotbinsy, ztotminsy
@@ -19,6 +19,7 @@ def PixelAthClusterMonAlgCfg(helper, alg, **kwargs):
 
     doOnline  = kwargs.get('doOnline',  False)
     doLumiBlock = kwargs.get('doLumiBlock', False)
+    doFEPlots  = kwargs.get('doFEPlots',  False)
 
 ### begin status histograms
 
@@ -36,6 +37,11 @@ def PixelAthClusterMonAlgCfg(helper, alg, **kwargs):
         title = 'Modules Status (0=Active+Good, 1=Active+Bad, 2=Inactive)'
         define2DProfHist(helper, alg, histoGroupName, title, pathLowStat, type='TProfile2D', lifecycle='lumiblock', histname='MapOfModulesStatusLB')
 
+    if doFEPlots:
+        histoGroupName = 'MapOfFEsStatus' 
+        title = 'FEs Status (0=Active+Good, 1=Active+Bad, 2=Inactive)'
+        define2DProfPerFEHist(helper, alg, histoGroupName, title, path, type='TProfile2D')
+
     histoGroupName = 'BadModulesPerLumi'
     title          = 'Number of bad modules (bad+active) per event per LB'
     yaxistext      = ';# modules/event'
@@ -110,7 +116,8 @@ def PixelAthClusterMonAlgCfg(helper, alg, **kwargs):
 
     varName = 'pixclusmontool_lb,ntrks_per_event'
     title = fullDressTitle('Number of tracks per event per LB', False, ';lumi block', ';tracks/event')
-    varName += ';tracksPerEvtPerLumi'
+
+    varName += ';TracksPerEvtPerLumi'
     trackGroup.defineHistogram(varName,
                                 type='TProfile', path=path, title=title,
                                 xbins=lumibinsx, xmin=-0.5, xmax=-0.5+lumibinsx)
@@ -260,6 +267,10 @@ def PixelAthClusterMonAlgCfg(helper, alg, **kwargs):
             title = addOnTrackTxt('Average per module(FE) cluster occupancy reset every 5 min', ontrack, True)
             definePP0Histos(helper, alg, histoGroupName, title, pathGroup, opt='kLBNHistoryDepth=5')
 
+        if not ontrack and doFEPlots:
+            histoGroupName = 'ClusterFEOccupancy' 
+            title = 'Cluster occupancy per FE'
+            define2DProfPerFEHist(helper, alg, histoGroupName, title, pathGroup, type='TH2F')
 
         if doLumiBlock:
             pathGroup = addOnTrackToPath(pathLowStat, ontrack)
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthHitMonAlgCfg.py b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthHitMonAlgCfg.py
index cfa7f401ddbf19609a3881c35728326f76ef8cd3..80ebdf7936c51e0a3864ec060522795b0d8df8ba 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthHitMonAlgCfg.py
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthHitMonAlgCfg.py
@@ -8,7 +8,8 @@
 '''
 
 from PixelMonitoring.PixelAthMonitoringBase import define2DProfHist, definePP0Histos, getLayerGroup
-from PixelMonitoring.PixelAthMonitoringBase import define1DProfLumiLayers
+from PixelMonitoring.PixelAthMonitoringBase import define1DProfLumiLayers, define2DProfPerFEHist
+from PixelMonitoring.PixelAthMonitoringBase import define1DLayers
 from PixelMonitoring.PixelAthMonitoringBase import layers, lumibinsx, bcidbinsx
 from PixelMonitoring.PixelAthMonitoringBase import addOnTrackTxt, addOnTrackToPath, fullDressTitle
 from PixelMonitoring.PixelAthMonitoringBase import runtext
@@ -22,6 +23,7 @@ def PixelAthHitMonAlgCfg(helper, alg, **kwargs):
     '''
     doOnline  = kwargs.get('doOnline',  False)
     doLumiBlock = kwargs.get('doLumiBlock', False)
+    doFEPlots  = kwargs.get('doFEPlots',  False)
 
     ontrack = False
 
@@ -59,12 +61,21 @@ def PixelAthHitMonAlgCfg(helper, alg, **kwargs):
         yaxistext      = ';occ. ratio to IBL'
         define1DProfLumiLayers(helper, alg, histoGroupName, title, pathGroup, yaxistext, type='TProfile')
 
+    histoGroupName = 'HitToT'
+    title = 'Hit ToT'
+    define1DLayers(helper, alg, histoGroupName, title, pathGroup, ';ToT [BC]', ';# hits', xbins=[300]*5+[20]*3, xmins=[-0.5]*8, binsizes=[1.0]*8)
+
     histoGroupName = 'HitMap' 
     title = 'hit map'
     define2DProfHist(helper, alg, histoGroupName, title, path, type='TH2F')
     if doLumiBlock:
         define2DProfHist(helper, alg, histoGroupName, title, pathLowStat, type='TH2F', lifecycle='lowStat', histname='HitMapLB')
 
+    if doFEPlots:
+        histoGroupName = 'HitFEMap' 
+        title = 'hit map per FE'
+        define2DProfPerFEHist(helper, alg, histoGroupName, title, path, type='TH2F')
+
     histoname = 'AvgOccPerBCID'
     for layer in layers:
         title      = 'Average pixel occupancy per BCID, {0}'.format(layer) + runtext + ';BCID;# hits/pixel/event'
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthMonitoringBase.py b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthMonitoringBase.py
index 398c9669edbd2b467f268e7d19d6688bc5b5e2d7..4c26d5721f83f94d2d000a7983e07d273b883d8a 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthMonitoringBase.py
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelAthMonitoringBase.py
@@ -6,17 +6,7 @@
 @file PixelAthMonitoringBase.py
 @brief Helper functions for Run 3 Pixel monitoring algorithm configuration
 '''
-# hack to deal with global variables in this module
-# check if we are in "old-" or "new-style" configuration
-#from AthenaConfiguration.AllConfigFlags import ConfigFlags
-#from RecExConfig.AutoConfiguration import GetRunNumber
-#if ConfigFlags.DQ.isReallyOldStyle:
 runtext = ''
-#    if GetRunNumber() is not None:
-#        runtext = ' (Run %d)' % GetRunNumber()
-#else:
-#    runtext = ' (Run %d)' % ConfigFlags.Input.RunNumber[0]
-
 
 NumLayersDisk = 3
 NumLayersDBM  = 3
@@ -43,6 +33,10 @@ xminsl   = [ -0.5, -0.5,-6.5,-6.5,-6.5,-16.5,  -0.5,  -0.5]
 ybinsl   = [   48,   48,  22,  38,  52,   14,     4,     4]
 etatxt   = [ditxt,ditxt,btxt,btxt,btxt,sbtxt,dbmtxt,dbmtxt]
 phitext  = ";phi index of module"
+xbinsfel = [   24,   24, 104, 104, 104,   32,     3,     3]
+xminsfel = [ -0.5, -0.5, -52, -52, -52,-16.5,  -0.5,  -0.5]
+ybinsfel = [   96,   96,  44,  76, 104,   14,     4,     4]
+
 totcuts  = [   15,   15,  15,  15,  15,    4,     4,     4] 
 xbinsem  = [    3,    3,  13,  13,  13,   20,     3,     3]
 xminsem  = [  0.5,  0.5,-6.5,-6.5,-6.5,  -10,   0.5,   0.5]
@@ -81,6 +75,26 @@ LayersDBM = ["Layer 0", "Layer 1", "Layer 2"] #xDBM
 
 LabelX = [LayersDisk, LayersDisk, ModulesBarrel, ModulesBarrel, ModulesBarrel, ModulesIBL, LayersDBM, LayersDBM]
 
+#same for FE
+LayersDiskFE = [" ", " ", " ", "Disk 1", " ", " ", " ", " ",
+              " ", " ", " ", "Disk 2", " ", " ", " ", " ",
+              " ", " ", " ", "Disk 3", " ", " ", " ", " "]
+ModulesBarrelFE = [
+    " ", " ", " ", "M6C", " ", " ", " ", " ",
+    " ", " ", " ", "M5C", " ", " ", " ", " ",
+    " ", " ", " ", "M4C", " ", " ", " ", " ",
+    " ", " ", " ", "M3C", " ", " ", " ", " ",
+    " ", " ", " ", "M2C", " ", " ", " ", " ",
+    " ", " ", " ", "M1C", " ", " ", " ", " ",
+    " ", " ", " ", "M0", " ", " ", " ", " ",
+    " ", " ", " ", "M1A", " ", " ", " ", " ",
+    " ", " ", " ", "M2A", " ", " ", " ", " ",
+    " ", " ", " ", "M3A", " ", " ", " ", " ",
+    " ", " ", " ", "M4A", " ", " ", " ", " ",
+    " ", " ", " ", "M5A", " ", " ", " ", " ",
+    " ", " ", " ", "M6A", " ", " ", " ", " "]
+LabelFEX = [LayersDiskFE, LayersDiskFE, ModulesBarrelFE, ModulesBarrelFE, ModulesBarrelFE, ModulesIBL, LayersDBM, LayersDBM]
+
 ModulesECA = [
     "B01_S2_M1", "B01_S2_M6", "B01_S2_M2", "B01_S2_M5", "B01_S2_M3",
     "B01_S2_M4", "B02_S1_M1", "B02_S1_M6", "B02_S1_M2", "B02_S1_M5",
@@ -139,6 +153,24 @@ StavesIBL = [
 
 LabelY = [ModulesECA, ModulesECC, StavesL0, StavesL1, StavesL2, StavesIBL, ModulesDBM, ModulesDBM]
 
+#same for per-FE
+ModulesFEECA = []
+for i in ModulesECA: 
+    ModulesFEECA.extend([i, ' '])
+ModulesFEECC = []
+for i in ModulesECC: 
+    ModulesFEECC.extend([i, ' '])
+StavesFEL0 = []
+for i in StavesL0:
+    StavesFEL0.extend([i, ' '])
+StavesFEL1 = []
+for i in StavesL1:
+    StavesFEL1.extend([i, ' '])
+StavesFEL2 = []
+for i in StavesL2:
+    StavesFEL2.extend([i, ' '])
+LabelFEY = [ModulesFEECA, ModulesFEECC, StavesFEL0, StavesFEL1, StavesFEL2, StavesIBL, ModulesDBM, ModulesDBM]
+
 #PP0
 PP0sEC = [
     "D1_B01_S2", "D1_B02_S1", "D1_B02_S2", "D1_B03_S1", "D1_B03_S2", "D1_B04_S1", "D1_B04_S2", "D1_B01_S1",
@@ -281,6 +313,49 @@ def define2DProfHist(helper, alg, name, title, path, type='TProfile2D', doWeight
                                     duration=lifecycle,
                                     opt=opt, xlabels=LabelX[i], ylabels=LabelY[i])
 
+def define2DProfPerFEHist(helper, alg, name, title, path, type='TProfile2D', doWeight=False, lifecycle='run', zmin=None, zmax=None, opt='', histname=None, onlylayers=layers):
+    '''
+    This function configures 2D (Profile) histograms (or maps) for Pixel layers per FE.
+
+    Arguments:
+         helper     -- AthMonitorCfgHelper(Old) instance
+         alg        -- algorithm - Configurable object returned from addAlgorithm
+         name       -- Name of histogram (Name = name_layer)
+         title      -- Title of histogram (Title = title +' '+layer)
+         path       -- Path in output file for histogram
+         type       -- Type of histogram (TH2D, TProfile2D)
+         lifecycle  -- global life duration of histograms (run, lowstat [i.e. 20 LB], lumiblock) - APPLIES to MonGroup only
+         zmin(zmax) -- fix the displayed range - simply chopping the range!!!
+         opt        -- history depth of a histogram e.g. 'kLBNHistoryDepth=10'
+         histname   -- another way of naming the histogram(s), useful when multiple histograms are filled from exactly the same variables, but in a different way
+         onlylayers -- sublist of layers 
+    '''
+    assert(set(onlylayers).issubset(layers))
+    if histname is None:
+        histname = name
+    for i, layer in enumerate(layers):
+        if layer not in onlylayers: 
+            continue
+        fulltitle   = title + ', {0}'.format(layer) + runtext + etatxt[i] + phitext
+        layerGroup = getLayerGroup(helper, alg, layer)
+
+        fullvarstring = '{0}_{1},{0}_{2}'.format(name, 'em', 'pm')
+        weightvar = ''
+        if 'Profile' in type: 
+            fullvarstring += ',{0}_{1}'.format(name, 'val')
+        elif doWeight:
+            weightvar = '{0}_{1}'.format(name, 'val') # re-use the same variable for TH2 for now.
+            
+        fullvarstring += ';' + histname + '_{0}'.format(layer)
+        layerGroup.defineHistogram(fullvarstring, 
+                                    type=type, path=path, title=fulltitle, weight=weightvar,
+                                    xbins=xbinsfel[i], xmin=xminsfel[i], xmax=xminsfel[i]+xbinsfel[i], 
+                                    ybins=ybinsfel[i], ymin=-0.5, ymax=-0.5+ybinsfel[i],
+                                    zmin=zmin, zmax=zmax,
+                                    duration=lifecycle,
+                                    opt=opt, xlabels=LabelFEX[i], ylabels=LabelFEY[i])
+
+
 def definePP0Histos(helper, alg, name, title, path, opt=''):
     '''
     This function configures TProfile histograms for Pixel layers per pp0 or ROD.
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelMonitoringConfig.py b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelMonitoringConfig.py
index 64331dad8eff2214ac9cfa5b9f49186049cc99ca..b07a05f5dec3c5648d47661c5e16a8aba6f9ce49 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelMonitoringConfig.py
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/python/PixelMonitoringConfig.py
@@ -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
 #
 
 def PixelMonitoringConfig(flags):
@@ -9,24 +9,23 @@ def PixelMonitoringConfig(flags):
     # run on RAW only
     if flags.DQ.Environment in ('online', 'tier0', 'tier0Raw'):
         kwargsHitMonAlg = { 'doOnline'        : flags.Common.isOnline,      #Histograms for online (athenaPT) running
-                            'doModules'       : flags.Common.isOnline, #Turn on/off the sets of 1744 module histograms (for dqmf)
                             'doLumiBlock'     : not flags.Common.isOnline,       #Turn on/off histograms stored for each lumi block
                             'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam                    
                             'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
                             #'doHeavyIonMon'   : InDetFlags.doHeavyIon(),   # Histogram modification for heavy ion monitoring
                             #'RDOName'         : InDetKeys.PixelRDOs()
                             'doHeavyIonMon'   : False,      #Until new config ready
+                            'doFEPlots'       : False,       #Turn on/off histograms with FE Status information
                             'RDOName'         : 'PixelRDOs',#Until new config ready
         }
 
         kwargsClusMonAlg = { 'doOnline'        : flags.Common.isOnline,      #Histograms for online (athenaPT) running
-                             'doModules'       : flags.Common.isOnline, #Turn on/off the sets of 1744 module histograms (for dqmf)
                              'doLumiBlock'     : not flags.Common.isOnline,       #Turn on/off histograms stored for each lumi block
                              'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam
                              'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
                              #'doHeavyIonMon'   : InDetFlags.doHeavyIon(),   # Histogram modification for heavy ion monitoring
                              'doHeavyIonMon'   : False,   #Until new config ready
-                             #                  'doStatus'        : True,       #Turn on/off histograms with Module Status information
+                             'doFEPlots'       : False,       #Turn on/off histograms with FE Status information
                              #'ClusterName'     : InDetKeys.PixelClusters(),
                              'ClusterName'     : 'PixelClusters', #Until new config ready
                              #'TrackName'       : InDetKeys.Tracks()
@@ -34,7 +33,6 @@ def PixelMonitoringConfig(flags):
         }
 
         kwargsErrMonAlg = { 'doOnline'        : flags.Common.isOnline,      #Histograms for online (athenaPT) running
-                            'doModules'       : flags.Common.isOnline, #Turn on/off the sets of 1744 module histograms (for dqmf)
                             'doLumiBlock'     : not flags.Common.isOnline,       #Turn on/off histograms stored for each lumi block
                             'doLowOccupancy'  : False,      #Turn on/off histograms with binning for cosmics/single beam                    
                             'doHighOccupancy' : True,       #Turn on/off histograms with binning for collisions
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.cxx b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.cxx
index d7015683e82e1f816a584e84078232a955fad682..e04de719c682e6796bca653afb5f789afa8ebb38 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.cxx
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.cxx
@@ -6,6 +6,7 @@
 
 PixelAthClusterMonAlg::PixelAthClusterMonAlg( const std::string& name, ISvcLocator* pSvcLocator ) : 
   AthMonitorAlgorithm(name, pSvcLocator),
+  m_pixelCablingSvc("PixelCablingSvc", name),
   m_holeSearchTool("InDet::InDetTrackHoleSearchTool/InDetHoleSearchTool", this),
   m_trackSelTool("InDet::InDetTrackSelectionTool/TrackSelectionTool", this),
   m_atlasid(nullptr),
@@ -16,11 +17,11 @@ PixelAthClusterMonAlg::PixelAthClusterMonAlg( const std::string& name, ISvcLocat
   declareProperty("TrackSelectionTool", m_trackSelTool); //needed for cfg in python jo
 
   declareProperty("doOnline", m_doOnline = false);
-  declareProperty("doModules", m_doModules = false);
   declareProperty("doLumiBlock", m_doLumiBlock = false);
   declareProperty("doLowOccupancy", m_doLowOccupancy = false);
   declareProperty("doHighOccupancy", m_doHighOccupancy = true);
   declareProperty("doHeavyIonMon", m_doHeavyIonMon = false);
+  declareProperty("doFEPlots", m_doFEPlots = false);
 }
 
 
@@ -32,6 +33,7 @@ StatusCode PixelAthClusterMonAlg::initialize() {
   ATH_CHECK( detStore()->retrieve(m_atlasid, "AtlasID") );
   ATH_CHECK( detStore()->retrieve(m_pixelid, "PixelID") );
   ATH_CHECK( m_pixelCondSummaryTool.retrieve() );
+  ATH_CHECK( m_pixelCablingSvc.retrieve() );
   if ( !m_holeSearchTool.empty() ) ATH_CHECK( m_holeSearchTool.retrieve() );
   if ( !m_trackSelTool.empty() ) ATH_CHECK( m_trackSelTool.retrieve() );
 
@@ -60,7 +62,9 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
   bool copyFEval(false);
   AccumulatorArrays clusPerEventArray = { {{0}}, {{0}}, {{0}}, {{0}}, {{0}}, {{0}} };
   VecAccumulator2DMap Map_Of_Modules_Status("MapOfModulesStatus", true);
-  
+
+  VecAccumulator2DMap Map_Of_FEs_Status("MapOfFEsStatus"); 
+
   for (auto idIt = m_pixelid->wafer_begin(); idIt!=m_pixelid->wafer_end(); ++idIt) {
     Identifier     waferID = *idIt;
     IdentifierHash id_hash = m_pixelid->wafer_hash(waferID);
@@ -102,12 +106,31 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
     }
     
     Map_Of_Modules_Status.add(pixlayer, waferID, m_pixelid, index);
+
+    // Per FE Status
+    //
+    if (m_doFEPlots && !m_doOnline) {
+      int nFE = getNumberOfFEs(pixlayer, m_pixelid->eta_module(waferID));
+      for (int iFE=0; iFE<nFE; iFE++) {
+	Identifier pixelID = m_pixelCablingSvc->getPixelIdfromHash(id_hash, iFE, 1, 1);
+	if (m_pixelCondSummaryTool->isActive(id_hash, pixelID) == true && m_pixelCondSummaryTool->isGood(id_hash, pixelID) == true) {
+	  index = 0;  // active and good FE
+	} else if (m_pixelCondSummaryTool->isActive(id_hash, pixelID) == false) {
+	  index = 2;  // inactive or bad FE
+	} else {
+	  index = 1;  // active and bad FE
+	}
+	Map_Of_FEs_Status.add(pixlayer, waferID, m_pixelid, iFE, index);
+      }
+    }
   }  // end of pixelid wafer loop
 
   fill2DProfLayerAccum( Map_Of_Modules_Status );
   fill1DProfLumiLayers("BadModulesPerLumi", lb, nBadMod);
   fill1DProfLumiLayers("DisabledModulesPerLumi", lb, nDisabledMod);
 
+  if (m_doFEPlots && !m_doOnline) fill2DProfLayerAccum( Map_Of_FEs_Status );
+
   //*******************************************************************************
   //*************************** End of filling Status Histograms ******************
   //*******************************************************************************
@@ -307,7 +330,8 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
 
   ATH_MSG_DEBUG("Filling Cluster Monitoring Histograms");
 
-  auto clToTcosAlphaLB = Monitored::Scalar<float>( "Cluster_ToTxCosAlpha_OnTrack_lb", lb);
+
+  auto clToTcosAlphaLB = Monitored::Scalar<float>( "ClusterToTxCosAlpha_OnTrack_lb", lb);
 
   VecAccumulator2DMap Cluster_LVL1A_Mod("ClusterLVL1AMod");
   VecAccumulator2DMap Cluster_LVL1A_SizeCut("ClusterLVL1ASizeCut");
@@ -320,6 +344,8 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
   VecAccumulator2DMap Cluster_Occupancy_OnTrack("ClusterOccupancyOnTrack");
   VecAccumulator2DMap Clus_Occ_SizeCut("ClusOccSizeCut");
   VecAccumulator2DMap Clus_Occ_SizeCut_OnTrack("ClusOccSizeCutOnTrack");
+  VecAccumulator2DMap Cluster_FE_Occupancy("ClusterFEOccupancy");
+
   auto clusterGroup = getGroup("Cluster");
   auto clusterGroup_OnTrack = getGroup("Cluster_OnTrack");
 
@@ -378,6 +404,9 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
       // begin cluster occupancy
       //
       Cluster_Occupancy.add(pixlayer, clusID, m_pixelid);
+      if (m_doFEPlots && !m_doOnline) {
+	Cluster_FE_Occupancy.add(pixlayer, clusID, m_pixelid, m_pixelCablingSvc->getFE(&clusID, clusID), 1.0);
+      }
       if (cluster.rdoList().size() > 1) Clus_Occ_SizeCut.add(pixlayer, clusID, m_pixelid);
       // end cluster occupancy
 
@@ -438,12 +467,11 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
 	// begin cluster ToT and charge
 	//
 	auto clToTcosAlpha = Monitored::Scalar<float>( "ClusterToTxCosAlphaOnTrack_val", cluster.totalToT() * cosalpha );
-	fill( pixLayersLabel[pixlayer], clToTcosAlpha);
+	fill( pixLayersLabel[pixlayer], clToTcosAlphaLB, clToTcosAlpha);
+
 	if (!m_doOnline) {
 	  auto clQcosAlpha   = Monitored::Scalar<float>( "ClusterQxCosAlphaOnTrack_val", cluster.totalCharge() * cosalpha);
 	  fill( pixLayersLabel[pixlayer], clQcosAlpha);
-	} else {
-	  fill( pixLayersLabel[pixlayer], clToTcosAlphaLB, clToTcosAlpha);
 	}
 	// 
 	// end cluster ToT and charge   
@@ -464,7 +492,7 @@ StatusCode PixelAthClusterMonAlg::fillHistograms( const EventContext& ctx ) cons
   fill2DProfLayerAccum(Cluster_Occupancy_OnTrack);
   fill2DProfLayerAccum(Clus_Occ_SizeCut);
   fill2DProfLayerAccum(Clus_Occ_SizeCut_OnTrack);
-  
+  if (m_doFEPlots && !m_doOnline) fill2DProfLayerAccum(Cluster_FE_Occupancy);
   // begin cluster rates
   //
   auto nCls   = Monitored::Scalar<int>( "ncls_per_event", nclusters );
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.h b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.h
index 7e2e3783e5c371691767d91c9ec558ff4e5709af..9d51e018b101a226a83e38db9d56aad382150262 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.h
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthClusterMonAlg.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 PIXELATHCLUSTERMONTOOL_H
@@ -9,6 +9,7 @@
 
 #include "AtlasDetDescr/AtlasDetectorID.h"
 #include "InDetConditionsSummaryService/IInDetConditionsTool.h"
+#include "PixelCabling/IPixelCablingSvc.h"
 
 #include "InDetPrepRawData/PixelClusterContainer.h"
 
@@ -51,7 +52,7 @@ class PixelAthClusterMonAlg : public PixelAthMonitoringBase {
   std::string findComponentString(int bec, int ld) const;
 
  private:
-
+  ServiceHandle<IPixelCablingSvc> m_pixelCablingSvc; //FE info
   ToolHandle<Trk::ITrackHoleSearchTool> m_holeSearchTool;
   ToolHandle<InDet::IInDetTrackSelectionTool> m_trackSelTool;
   ToolHandle<IInDetConditionsTool> m_pixelCondSummaryTool{this, "PixelConditionsSummaryTool", "PixelConditionsSummaryTool", "Tool to retrieve Pixel Conditions summary"};
@@ -63,11 +64,10 @@ class PixelAthClusterMonAlg : public PixelAthMonitoringBase {
   SG::ReadHandleKey<TrackCollection> m_tracksKey{this, "TrackName", "CombinedInDetTracks", "track data key"};
  
   bool m_doOnline;
-  bool m_doModules;
   bool m_doLumiBlock;
   bool m_doLowOccupancy;
   bool m_doHighOccupancy;
   bool m_doHeavyIonMon; 
-
+  bool m_doFEPlots;
 };
 #endif
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.cxx b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.cxx
index 3bb258cad486ec102fb19c44a59dc6644299779c..8842509f559b3156936081980652f780ce16824f 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.cxx
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.cxx
@@ -6,11 +6,11 @@
 
 PixelAthErrorMonAlg::PixelAthErrorMonAlg( const std::string& name, ISvcLocator* pSvcLocator ) : 
   AthMonitorAlgorithm(name, pSvcLocator),
+  m_pixelCablingSvc("PixelCablingSvc", name),
   m_pixelid(nullptr)
 {
   // jo flags
   declareProperty("doOnline", m_doOnline = false);
-  declareProperty("doModules", m_doModules = false);
   declareProperty("doLumiBlock", m_doLumiBlock = false);
   declareProperty("doLowOccupancy", m_doLowOccupancy = false);
   declareProperty("doHighOccupancy", m_doHighOccupancy = false);
@@ -25,6 +25,7 @@ StatusCode PixelAthErrorMonAlg::initialize() {
 
   ATH_CHECK( detStore()->retrieve(m_pixelid, "PixelID") );
   ATH_CHECK( m_pixelCondSummaryTool.retrieve() );
+  ATH_CHECK( m_pixelCablingSvc.retrieve() );
 
   return AthMonitorAlgorithm::initialize();
 }
@@ -42,20 +43,20 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
   std::vector<VecAccumulator2DMap> error_maps_per_state;
   error_maps_per_state.reserve(kNumErrorStatesFEI3 + kNumErrorStatesFEI4);
   for (const auto& state : error_names_stateFEI3) {
-    error_maps_per_state.emplace_back( state + std::string("Map"), true );
+    error_maps_per_state.emplace_back( state + std::string("Map") );
   }
   for (const auto& state : error_names_stateFEI4) {
-    error_maps_per_state.emplace_back( state + std::string("Map"), true );
+    error_maps_per_state.emplace_back( state + std::string("Map") );
   }
   std::vector<VecAccumulator2DMap> error_maps_per_cat_rodmod; 
   // only first four rodmod histos are unique, others are covered by 
   // the overall, rod/mod-agnostic categories below
   for (unsigned int cat = 0; cat < ErrorCategoryRODMOD::kTruncROD+1; ++cat) {
-    error_maps_per_cat_rodmod.emplace_back( error_names_cat_rodmod[cat], true );
+    error_maps_per_cat_rodmod.emplace_back( error_names_cat_rodmod[cat] );
   }
   std::vector<VecAccumulator2DMap> error_maps_per_cat;
   for (unsigned int cat = 0; cat < ErrorCategory::COUNT; ++cat) {
-    error_maps_per_cat.emplace_back( error_names_cat[cat], true );
+    error_maps_per_cat.emplace_back( error_names_cat[cat] );
   }
 
   // containers to keep IBL service records info
@@ -74,10 +75,10 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
   float num_errormodules_per_cat_rodmod[ErrorCategoryRODMOD::COUNT][PixLayers::COUNT] = {{0}};
 
   // Generate femcc_errwords and per LB maps, all _per module_, including IBL.
-  VecAccumulator2DMap femcc_errwords_maps("FEMCCErrorwords", true);
-  VecAccumulator2DMap all_errors_maps("ErrorsLB", true);
-  VecAccumulator2DMap modsync_errors_maps("ErrorsModSyncLB", true);
-  VecAccumulator2DMap rodsync_errors_maps("ErrorsRODSyncLB", true);
+  VecAccumulator2DMap femcc_errwords_maps("FEMCCErrorwords");
+  VecAccumulator2DMap all_errors_maps("ErrorsLB");
+  VecAccumulator2DMap modsync_errors_maps("ErrorsModSyncLB");
+  VecAccumulator2DMap rodsync_errors_maps("ErrorsRODSyncLB");
 
   //====================================================================================
   // This is an example how to read the Error informaiton.
@@ -123,18 +124,19 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
     int nFE;
     bool is_fei4;
     if (pixlayer == PixLayers::kDBMC || pixlayer == PixLayers::kDBMA) {
-      nFE = 2;  
+      nFE = 1;  
       is_fei4 = true;
     } else if (pixlayer == PixLayers::kIBL) {
-      nFE = 2;  
+      nFE = 1; // IBL 3D
+      if (m_pixelid->eta_module(waferID)>-7 && m_pixelid->eta_module(waferID)<6) nFE = 2; //IBL Planar
       is_fei4 = true;
     } else { // for fei3 Pixel layers
       nFE = 16;
       is_fei4 = false;
     }
     // flagging/counting categorized errors per module.
-    bool has_err_cat[ErrorCategory::COUNT] = {false};
-    int nerrors_cat_rodmod[ErrorCategoryRODMOD::COUNT] = {0};
+    bool has_err_cat[ErrorCategory::COUNT][nFEIBL2D] = {false};
+    int nerrors_cat_rodmod[ErrorCategoryRODMOD::COUNT][nFEIBL2D] = {0};
 
     // count number of words w/ MCC/FE flags per module
     unsigned int num_femcc_errwords = 0;
@@ -161,7 +163,7 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
       int offsetFE = (1+iFE)*maxHash + modHash;    // (FE index+1)*2048 + moduleHash
       uint64_t fe_errorword = m_pixelCondSummaryTool->getBSErrorWord(offsetFE, ctx);
 
-      fillErrorCatRODmod(fe_errorword, is_fei4, nerrors_cat_rodmod);
+      fillErrorCatRODmod(fe_errorword, is_fei4, nerrors_cat_rodmod, iFE);
 
       if (!is_fei4) {
 	std::bitset<kNumErrorStatesFEI3> stateFEI3 = getErrorStateFE(fe_errorword, is_fei4);  
@@ -176,10 +178,11 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
       } else {
 	std::bitset<kNumErrorStatesFEI3> stateFEI4 = getErrorStateFE(fe_errorword, is_fei4);  
 	num_errors[pixlayer]+=stateFEI4.count();
+	Identifier pixelIDperFEI4 = m_pixelCablingSvc->getPixelIdfromHash(modHash, iFE, 1, 1);
 	for (unsigned int state = 0; state < stateFEI4.size(); ++state) {
 	  if (stateFEI4[state]) {
 	    num_errors_per_state[state][pixlayer]++;
-	    error_maps_per_state[state+kNumErrorStatesFEI3].add(pixlayer, waferID, m_pixelid, 1.0);
+	    error_maps_per_state[state+kNumErrorStatesFEI3].add(pixlayer, pixelIDperFEI4, m_pixelid, 1.0);
 	  }
 	}
       }
@@ -201,6 +204,7 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
 	}
 	int serviceCodeOffset = serviceCode*280*nFE;
 	for (int iFE=0; iFE<nFE; iFE++) {
+	  Identifier pixelIDperFEI4 = m_pixelCablingSvc->getPixelIdfromHash(modHash, iFE, 1, 1);
 	  // index = offset + (serviceCode)*(#IBL*nFE) + (moduleHash-156)*nFE + FE
           int serviceCodeCounterIndex = serviceRecordFieldOffset + serviceCodeOffset + moduleOffset + iFE;
           uint64_t serviceCodeCounter = m_pixelCondSummaryTool->getBSErrorWord(serviceCodeCounterIndex, ctx);
@@ -213,9 +217,9 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
 	    int state = serviceCode + state_offset;
 	    num_errors[pixlayer] += payload;
 	    num_errors_per_state[state][pixlayer] += payload;
-	    error_maps_per_state[state+kNumErrorStatesFEI3].add(pixlayer, waferID, m_pixelid, payload);
+	    error_maps_per_state[state+kNumErrorStatesFEI3].add(pixlayer, pixelIDperFEI4, m_pixelid, payload);
 	   
-	    fillErrorCatRODmod(serviceCode, payload, nerrors_cat_rodmod);
+	    fillErrorCatRODmod(serviceCode, payload, nerrors_cat_rodmod, iFE);
 	  }
 
         } // over FE
@@ -223,37 +227,46 @@ StatusCode PixelAthErrorMonAlg::fillHistograms( const EventContext& ctx ) const
     } // IBL modules
 
     // access categorized error information per module
+    // access categorized error information per module (for IBL - FE)
     // it is only flagged - the actual number of errors per category is not tracked
-    for (int i = 0; i < ErrorCategoryRODMOD::COUNT; i++) {
-      if (nerrors_cat_rodmod[i]) {
-	if (getErrorCategory(i+1)!=99) has_err_cat[getErrorCategory(i+1)] = true;
-	num_errormodules_per_cat_rodmod[i][pixlayer]++;
-	if (!m_doOnline) {
-	  all_errors_maps.add(pixlayer, waferID, m_pixelid, nerrors_cat_rodmod[i]);
-	  if (i<ErrorCategoryRODMOD::kTruncROD+1) {
-	    error_maps_per_cat_rodmod[i].add(pixlayer, waferID, m_pixelid, 1.0);
-	    if (i==0) modsync_errors_maps.add(pixlayer, waferID, m_pixelid, 1.0);
-	    if (i==1) rodsync_errors_maps.add(pixlayer, waferID, m_pixelid, 1.0);
+    for (int iFE=0; iFE<nFE; iFE++) {
+
+      if (pixlayer != PixLayers::kIBL && iFE>0) continue;
+      Identifier pixID = waferID;
+      if (pixlayer == PixLayers::kIBL) {
+	pixID = m_pixelCablingSvc->getPixelIdfromHash(modHash, iFE, 1, 1);
+      }
+
+      for (int i = 0; i < ErrorCategoryRODMOD::COUNT; i++) {
+	if (nerrors_cat_rodmod[i][iFE]) {
+	  if (getErrorCategory(i+1)!=99) has_err_cat[getErrorCategory(i+1)][iFE] = true;
+	  num_errormodules_per_cat_rodmod[i][pixlayer]++;
+	  if (!m_doOnline) {
+	    all_errors_maps.add(pixlayer, pixID, m_pixelid, nerrors_cat_rodmod[i][iFE]);
+	    if (i<ErrorCategoryRODMOD::kTruncROD+1) {
+	      error_maps_per_cat_rodmod[i].add(pixlayer, pixID, m_pixelid, 1.0);
+	      if (i==0) modsync_errors_maps.add(pixlayer, pixID, m_pixelid, 1.0);
+	      if (i==1) rodsync_errors_maps.add(pixlayer, pixID, m_pixelid, 1.0);
+	    }
 	  }
 	}
       }
-    }
-    for (int i = 0; i < ErrorCategory::COUNT; i++) {
-      if (has_err_cat[i]) {
-	num_errormodules_per_cat[i][pixlayer]++;
-	if (!m_doOnline) {
-	  error_maps_per_cat[i].add(pixlayer, waferID, m_pixelid, 1.0);
+      for (int i = 0; i < ErrorCategory::COUNT; i++) {
+	if (has_err_cat[i][iFE]) {
+	  num_errormodules_per_cat[i][pixlayer]++;
+	  if (!m_doOnline) {
+	    error_maps_per_cat[i].add(pixlayer, pixID, m_pixelid, 1.0);
+	  }
 	}
       }
-    }
+
     // filling nActive modules per layer for later normalization
-    // for IBL (and DBM) normalization is effectively done by number of FEI4 
-    // REVIEW once per-FE active info is available
-    //
-    if (m_pixelCondSummaryTool->isActive(modHash) == true) {
-      if (pixlayer == PixLayers::kIBL && m_pixelid->eta_module(waferID)>-7 && m_pixelid->eta_module(waferID)<6) nActive_layer[pixlayer]+=2;
-      else nActive_layer[pixlayer]++;
-    }
+    // for IBL (and DBM) normalization isdone by number of FEI4 
+      if ( (pixlayer != PixLayers::kIBL && m_pixelCondSummaryTool->isActive(modHash) == true) ||
+	   (pixlayer == PixLayers::kIBL && m_pixelCondSummaryTool->isActive(modHash, pixID) == true) ) {
+	nActive_layer[pixlayer]++;
+      }
+    } // loop over FEs
 
   } // loop over modules
 
@@ -366,44 +379,46 @@ std::bitset<kNumErrorStatesFEI3> PixelAthErrorMonAlg::getErrorStateFE(uint64_t e
   return result;
 }
 
-void PixelAthErrorMonAlg::fillErrorCatRODmod(uint64_t errorword, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const {
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::TimeOut) )            nerrors_cat_rodmod[6]++; // timeout errors
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::BCID) )               nerrors_cat_rodmod[1]++; // ROD synchronization
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::LVL1ID) )             nerrors_cat_rodmod[1]++; // ROD synchronization
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Preamble) )           nerrors_cat_rodmod[4]++; // optical errors
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::RODHeaderLimit) )     nerrors_cat_rodmod[3]++; // ROD truncation
-  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::RODDataOVerflow) )    nerrors_cat_rodmod[3]++; // ROD truncation
+void PixelAthErrorMonAlg::fillErrorCatRODmod(uint64_t errorword, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D]) const {
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::TimeOut) )            nerrors_cat_rodmod[6][0]++; // timeout errors
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::BCID) )               nerrors_cat_rodmod[1][0]++; // ROD synchronization
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::LVL1ID) )             nerrors_cat_rodmod[1][0]++; // ROD synchronization
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Preamble) )           nerrors_cat_rodmod[4][0]++; // optical errors
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::RODHeaderLimit) )     nerrors_cat_rodmod[3][0]++; // ROD truncation
+  if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::RODDataOVerflow) )    nerrors_cat_rodmod[3][0]++; // ROD truncation
 }
 
-void PixelAthErrorMonAlg::fillErrorCatRODmod(uint64_t errorword, bool is_fei4, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const {
+void PixelAthErrorMonAlg::fillErrorCatRODmod(uint64_t errorword, bool is_fei4, 
+					     int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D], int ife) const {
   if (!is_fei4) {
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCLVL1IDEoECheck) ) nerrors_cat_rodmod[0]++;  // module synchronization
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCBCIDEoECheck) )   nerrors_cat_rodmod[0]++;  // ---
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCLVL1IDCheck) )    nerrors_cat_rodmod[0]++;  // ---
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCEoEOverflow) )    nerrors_cat_rodmod[2]++;  // module truncation
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCHitOverflow) )    nerrors_cat_rodmod[2]++;  // ---
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEEoCOverflow) )     nerrors_cat_rodmod[2]++;  // ---
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEHitParity) )       nerrors_cat_rodmod[5]++;  // SEU (single event upset)
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FERegisterParity) )  nerrors_cat_rodmod[5]++;  // ---
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEHammingCode) )     nerrors_cat_rodmod[5]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCLVL1IDEoECheck) ) nerrors_cat_rodmod[0][0]++;  // module synchronization
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCBCIDEoECheck) )   nerrors_cat_rodmod[0][0]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCLVL1IDCheck) )    nerrors_cat_rodmod[0][0]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCEoEOverflow) )    nerrors_cat_rodmod[2][0]++;  // module truncation
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::MCCHitOverflow) )    nerrors_cat_rodmod[2][0]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEEoCOverflow) )     nerrors_cat_rodmod[2][0]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEHitParity) )       nerrors_cat_rodmod[5][0]++;  // SEU (single event upset)
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FERegisterParity) )  nerrors_cat_rodmod[5][0]++;  // ---
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::FEHammingCode) )     nerrors_cat_rodmod[5][0]++;  // ---
   } else {
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::TimeOut) )           nerrors_cat_rodmod[6]++; // timeout errors
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::BCID) )              nerrors_cat_rodmod[1]++; // ROD synchronization
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::LVL1ID) )            nerrors_cat_rodmod[1]++; // ROD synchronization
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Preamble) )          nerrors_cat_rodmod[4]++; // optical errors
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Trailer) )           nerrors_cat_rodmod[6]++; // timeout errors
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Invalid) )           nerrors_cat_rodmod[3]++; // ROD truncation
-    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Limit) )             nerrors_cat_rodmod[3]++; // ROD truncation
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::TimeOut) )           nerrors_cat_rodmod[6][ife]++; // timeout errors
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::BCID) )              nerrors_cat_rodmod[1][ife]++; // ROD synchronization
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::LVL1ID) )            nerrors_cat_rodmod[1][ife]++; // ROD synchronization
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Preamble) )          nerrors_cat_rodmod[4][ife]++; // optical errors
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Trailer) )           nerrors_cat_rodmod[6][ife]++; // timeout errors
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Invalid) )           nerrors_cat_rodmod[3][ife]++; // ROD truncation
+    if ( PixelByteStreamErrors::hasError(errorword, PixelByteStreamErrors::Limit) )             nerrors_cat_rodmod[3][ife]++; // ROD truncation
   }
 }
 
-void PixelAthErrorMonAlg::fillErrorCatRODmod(int sc, int payload, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const {
+void PixelAthErrorMonAlg::fillErrorCatRODmod(int sc, int payload, 
+					     int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D], int ife) const {
 
-  if (sc == 0)                  nerrors_cat_rodmod[0]+=payload;  // synchronization error   (SR0:BCID counter)
-  if (sc == 16)                 nerrors_cat_rodmod[2]+=payload;  // truncation error        (SR16:Truncated event)
+  if (sc == 0)                  nerrors_cat_rodmod[0][ife]+=payload;  // synchronization error   (SR0:BCID counter)
+  if (sc == 16)                 nerrors_cat_rodmod[2][ife]+=payload;  // truncation error        (SR16:Truncated event)
   if (sc == 1 || sc == 2 ||                                      // (SR1:Hamming code 0, SR2:Hamming code 1,
       sc == 3 || sc == 24 ||                                     // SR3:Hamming code 2, SR24:Triple redundant CNFGMEM,
       sc == 28 || sc == 29 ||                                    // SR28:Bit flip in CMD, SR29:Triple redundant CMD,
       sc == 31)                                                  // SR31:Triple redundant EFUSE)
-    nerrors_cat_rodmod[5]+=payload;                              // SEU error
+    nerrors_cat_rodmod[5][ife]+=payload;                              // SEU error
 }
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.h b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.h
index dfbdcc492348d4e01e7c4d1ed0b7eb0e37556c2b..ee7d3d6e15baa062855d9a8db2da99cee9c8d01a 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.h
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthErrorMonAlg.h
@@ -8,6 +8,7 @@
 #include "PixelAthMonitoringBase.h"
 #include "InDetConditionsSummaryService/IInDetConditionsTool.h"
 #include "PixelConditionsData/PixelByteStreamErrors.h"
+#include "PixelCabling/IPixelCablingSvc.h"
 
 class PixelID;
 
@@ -119,6 +120,8 @@ static const int numErrorCatRODModsLayer[PixLayers::COUNT] = {
   kNumErrorCatRODMods, kNumErrorCatRODMods, kNumErrorCatRODMods, kNumErrorCatRODMods
 };
 
+static const int nFEIBL2D{2};
+
 class PixelAthErrorMonAlg : public PixelAthMonitoringBase {
 
  public:
@@ -131,21 +134,26 @@ class PixelAthErrorMonAlg : public PixelAthMonitoringBase {
   int getErrorCategory(int error_cat_rodmod) const;
   std::bitset<kNumErrorStatesFEI3> getErrorStateFEI3Mod(uint64_t errorword) const;
   std::bitset<kNumErrorStatesFEI3> getErrorStateFE(uint64_t errorword, bool isibl) const;
-  void fillErrorCatRODmod(uint64_t mod_errorword, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const;
-  void fillErrorCatRODmod(uint64_t fe_errorword, bool is_fei4, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const;
-  void fillErrorCatRODmod(int servicecode, int payload, int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT]) const;
+  void fillErrorCatRODmod(uint64_t mod_errorword, 
+			    int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D]) const;
+  void fillErrorCatRODmod(uint64_t fe_errorword, bool is_fei4, 
+			    int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D], int ife) const;
+  void fillErrorCatRODmod(int servicecode, int payload, 
+			    int (&nerrors_cat_rodmod)[ErrorCategoryRODMOD::COUNT][nFEIBL2D], int ife) const;
 
  private:
 
-  ToolHandle<IInDetConditionsTool> m_pixelCondSummaryTool{this, "PixelConditionsSummaryTool", "PixelConditionsSummaryTool", "Tool to retrieve Pixel Conditions summary"};
+  ServiceHandle<IPixelCablingSvc> m_pixelCablingSvc; //FE info
+  ToolHandle<IInDetConditionsTool> m_pixelCondSummaryTool{this, "PixelConditionsSummaryTool", 
+							    "PixelConditionsSummaryTool", "Tool to retrieve Pixel Conditions summary"};
 
   const PixelID* m_pixelid;
 
   bool m_doOnline;
-  bool m_doModules;
   bool m_doLumiBlock;
   bool m_doLowOccupancy;
   bool m_doHighOccupancy;
   bool m_doHeavyIonMon;
+
 };
 #endif
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.cxx b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.cxx
index 810662d94a34a50c544b839cc7fb9ac70b14e154..2e7b5209e883868c5d2e4b3818c5dcb4ec4bb72c 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.cxx
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.cxx
@@ -3,20 +3,19 @@
 */
 
 #include "PixelAthHitMonAlg.h"
-#include "PixelCabling/IPixelCablingSvc.h"
 
 PixelAthHitMonAlg::PixelAthHitMonAlg( const std::string& name, ISvcLocator* pSvcLocator ) : 
   AthMonitorAlgorithm(name, pSvcLocator),
-  m_pixelCableSvc("PixelCablingSvc", name),
+  m_pixelCablingSvc("PixelCablingSvc", name),
   m_pixelid(nullptr)
 {
   //jo flags
   declareProperty("doOnline", m_doOnline = false);
-  declareProperty("doModules", m_doModules = false);
   declareProperty("doLumiBlock", m_doLumiBlock = false);
   declareProperty("doLowOccupancy", m_doLowOccupancy = false);
   declareProperty("doHighOccupancy", m_doHighOccupancy = false);
   declareProperty("doHeavyIonMon", m_doHeavyIonMon = false);
+  declareProperty("doFEPlots", m_doFEPlots = false);
 }
 
 
@@ -27,7 +26,7 @@ StatusCode PixelAthHitMonAlg::initialize() {
 
   ATH_CHECK( detStore()->retrieve(m_pixelid, "PixelID") );
   ATH_CHECK( m_pixelCondSummaryTool.retrieve() );
-  ATH_CHECK( m_pixelCableSvc.retrieve() );
+  ATH_CHECK( m_pixelCablingSvc.retrieve() );
   ATH_CHECK( m_pixelRDOName.initialize() );
 
   return AthMonitorAlgorithm::initialize();
@@ -134,9 +133,10 @@ StatusCode PixelAthHitMonAlg::fillHistograms( const EventContext& ctx ) const {
 
 
   VecAccumulator2DMap HitMap("HitMap");
+  VecAccumulator2DMap HitFEMap("HitFEMap");
   std::vector<int> hitLvl1a;
   std::unordered_map<int, std::vector<int>> hitLvl1aLayer;
-
+  std::unordered_map<int, std::vector<int>> hitToTLayer;
 
   Identifier rdoID;
   PixelRDO_Container::const_iterator colNext = rdocontainer->begin();
@@ -156,10 +156,12 @@ StatusCode PixelAthHitMonAlg::fillHistograms( const EventContext& ctx ) const {
       int pixlayer = getPixLayersID(m_pixelid->barrel_ec(rdoID), m_pixelid->layer_disk(rdoID) );
       if (pixlayer == 99) continue;
       HitMap.add(pixlayer, rdoID, m_pixelid, 1.0);
+      if (m_doFEPlots && !m_doOnline) HitFEMap.add(pixlayer, rdoID, m_pixelid, m_pixelCablingSvc->getFE(&rdoID, rdoID), 1.0);
       nhits++;
       nhits_layer[pixlayer]++;
       hitLvl1a.push_back( (*p_rdo)->getLVL1A() );
       hitLvl1aLayer[pixlayer].push_back( (*p_rdo)->getLVL1A() );
+      hitToTLayer[pixlayer].push_back( (*p_rdo)->getToT() );
       getPhiEtaMod(m_pixelid, rdoID, phiMod, etaMod, copyFEval);
       switch (pixlayer) {
       case PixLayers::kECA : 
@@ -185,6 +187,7 @@ StatusCode PixelAthHitMonAlg::fillHistograms( const EventContext& ctx ) const {
   }
 
   fill2DProfLayerAccum( HitMap );
+  if (m_doFEPlots && !m_doOnline) fill2DProfLayerAccum( HitFEMap );
 
   auto vals = Monitored::Collection( "Hit_LVL1A_pixel", hitLvl1a );
   fill( hitGroup, vals);
@@ -193,6 +196,11 @@ StatusCode PixelAthHitMonAlg::fillHistograms( const EventContext& ctx ) const {
     auto vals = Monitored::Collection( "Hit_LVL1A_layer", hitLvl1aLayer.at(layer) );
     fill( pixLayersLabel[layer], vals);
   }
+  for ( const auto& itr : hitToTLayer ) {
+    int layer = itr.first;
+    auto vals = Monitored::Collection( "HitToT_val", hitToTLayer.at(layer) );
+    fill( pixLayersLabel[layer], vals);
+  }
 
 
   auto nhitsval = Monitored::Scalar<int>( "nhits_per_event", nhits );
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.h b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.h
index 8e2fd5a7764cea68de910d08cd5bbb1476b42fc5..4e6f294fbc3bbaf29e27cd3e8e6d340d6e55ce1a 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.h
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthHitMonAlg.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 PIXELATHHITMONTOOL_H
@@ -8,13 +8,13 @@
 #include "PixelAthMonitoringBase.h"
 #include "InDetConditionsSummaryService/IInDetConditionsTool.h"
 //#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+#include "PixelCabling/IPixelCablingSvc.h"
 
 #include "InDetRawData/InDetRawDataCLASS_DEF.h"
 #include "InDetRawData/InDetRawDataContainer.h"
 #include "InDetRawData/InDetTimeCollection.h"
 
 class PixelID;
-class IPixelCablingSvc;
 class PixelRDORawData;
 
 class PixelAthHitMonAlg : public PixelAthMonitoringBase {
@@ -29,7 +29,7 @@ class PixelAthHitMonAlg : public PixelAthMonitoringBase {
 
  private:
 
-  ServiceHandle<IPixelCablingSvc> m_pixelCableSvc; //FE info
+  ServiceHandle<IPixelCablingSvc> m_pixelCablingSvc; //FE info
   ToolHandle<IInDetConditionsTool> m_pixelCondSummaryTool{this, "PixelConditionsSummaryTool", "PixelConditionsSummaryTool", "Tool to retrieve Pixel Conditions summary"};
 
   const PixelID* m_pixelid;
@@ -37,10 +37,10 @@ class PixelAthHitMonAlg : public PixelAthMonitoringBase {
   SG::ReadHandleKey<PixelRDO_Container> m_pixelRDOName{this, "RDOName", "PixelRDOs", "rdo data key"};
 
   bool m_doOnline;
-  bool m_doModules;
   bool m_doLumiBlock;
   bool m_doLowOccupancy;
   bool m_doHighOccupancy;
   bool m_doHeavyIonMon;
+  bool m_doFEPlots;
 };
 #endif
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.cxx b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.cxx
index 5bce360ba810c324390d0012117e806e2ad1f48d..6f510323aa81262c699d5e39a1b34c11fad5ff6f 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.cxx
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.cxx
@@ -7,7 +7,7 @@
 
 //////////////////////////////////////////////
 ///
-/// helper class to accumulate points to fill a 2D plot with
+/// helper class to accumulate points to fill a 2D per-module plot with
 ///
 void PixelAthMonitoringBase::VecAccumulator2DMap::add( const int layer, const Identifier& id,
 						  const PixelID* pid, float value ) {
@@ -44,6 +44,62 @@ void PixelAthMonitoringBase::VecAccumulator2DMap::add( const int layer, const Id
   }   
 }
 
+//////////////////////////////////////////////
+///
+/// helper class to accumulate points to fill a 2D per-FE plot with
+///
+void PixelAthMonitoringBase::VecAccumulator2DMap::add( const int layer, const Identifier& id,
+						       const PixelID* pid, int iFE, float value ) {
+
+  // value
+  m_val[layer].push_back(value);
+
+  // for old pixel see https://twiki.cern.ch/twiki/pub/Atlas/PixelCOOLoffline/pixel_modules_sketch.png
+  // 
+  // phi (Y) coordinate
+  if ( layer == PixLayers::kIBL || layer == PixLayers::kDBMC || layer == PixLayers::kDBMA )
+    m_pm[layer].push_back( pid->phi_module(id) );
+  else {
+    if ( (layer == PixLayers::kECA || layer == PixLayers::kECC) && ( pid->phi_module(id) % 2 == 0 ) ) {
+      // even disk modules
+      m_pm[layer].push_back( pid->phi_module(id)*2 + iFE/8 );
+    } else { 
+      m_pm[layer].push_back( pid->phi_module(id)*2 + 1 - iFE/8 );
+    }
+  }
+  // eta (X) coordinate
+  int ld = pid->layer_disk(id);
+  int em(0);
+  // endcaps/DBM
+  if ( layer == PixLayers::kDBMC || layer == PixLayers::kDBMA ) em = ld;
+  else {
+    em = ld * 8;
+    if (iFE<8) em+= ( 7 - iFE%8 ); 
+    else em+= iFE%8; 
+  } 
+  // barrel
+  //
+  if (pid->barrel_ec(id) == 0) { 
+    if (ld == 0) {  //ibl
+      em = pid->eta_module(id);
+      int emf;
+      if (em < -6) {
+	emf = em - 6;
+      } else if (em > -7 && em < 6) {
+	emf = 2 * em + iFE;
+      } else {
+	emf = em + 6;
+      }
+      em = emf;
+    } else {
+      em = pid->eta_module(id) * 8 - 4;
+      if (iFE<8) em+= ( 7 - iFE%8 );
+      else em+= iFE%8; 
+    }
+  } // end barrel
+  m_em[layer].push_back(em);
+}
+
 //////////////////////////////////////////////
 ///
 /// take VecAccumulator2DMap and fill the corresponding group
@@ -230,6 +286,20 @@ int PixelAthMonitoringBase::getPixLayersID(int ec, int ld) const {
 }
 //////////////////////////////////////////////
 
+///
+/// helper function to get number of FEs per module
+///
+int PixelAthMonitoringBase::getNumberOfFEs(int pixlayer, int etaMod) const {
+  int nFE(16);
+  if (pixlayer == PixLayers::kIBL || pixlayer == PixLayers::kDBMC || pixlayer == PixLayers::kDBMA) {
+    nFE = 1;
+    if (etaMod>-7 && etaMod<6) nFE = 2; //IBL Planar
+  } 
+  return nFE;
+}
+//////////////////////////////////////////////
+
+
 ///
 /// helper function to get eta phi coordinates of per-layer arrays
 ///
diff --git a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.h b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.h
index 11283f3c0a129c5c9a81b425949491c9ceedcf42..9ce1939caff92d9d00830f95f1e3d766468ca49c 100644
--- a/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.h
+++ b/InnerDetector/InDetMonitoring/PixelMonitoring/src/PixelAthMonitoringBase.h
@@ -45,6 +45,7 @@ class PixelAthMonitoringBase : public virtual AthMonitorAlgorithm {
   void fill2DProfLumiLayers( const std::string& prof2Dname, int lb, float (*weights)[PixLayers::COUNT], const int* nCategories ) const;
 
   int getPixLayersID(int ec, int ld) const;
+  int getNumberOfFEs(int pixlayer, int etaMod) const;
   void getPhiEtaMod(const PixelID* pid, Identifier& id, int& phiMod, int& etaMod, bool& copyFE) const;
   bool isHitOnTrack(Identifier id, std::vector<Identifier> const &RDOIDs) const;
   bool isClusterOnTrack(Identifier id, std::vector<std::pair<Identifier, double> > const &ClusterIDs) const;
@@ -64,6 +65,8 @@ class PixelAthMonitoringBase : public virtual AthMonitorAlgorithm {
     
     void add( const int layer, const Identifier& id,
 	      const PixelID* pid, float value=1.0 );
+    void add( const int layer, const Identifier& id,
+	      const PixelID* pid, int iFE, float value);
   };
   void fill2DProfLayerAccum( const VecAccumulator2DMap& accumulator ) const;