From 28d722a40dd47746f88e8bf3970a41a3fd0b550e Mon Sep 17 00:00:00 2001
From: christos <christos@cern.ch>
Date: Mon, 10 Sep 2018 17:53:45 +0100
Subject: [PATCH] update from release 21.2

---
 .../CMakeLists.txt                            |   14 +-
 .../AsgElectronEfficiencyCorrectionTool.h     |    7 -
 .../ElectronChargeEfficiencyCorrectionTool.h  |   23 +-
 .../TElectronEfficiencyCorrectionTool.h       |  298 ++-
 .../AsgElectronEfficiencyCorrectionTool.cxx   |   38 +-
 ...ElectronChargeEfficiencyCorrectionTool.cxx |   91 +-
 .../TElectronEfficiencyCorrectionTool.cxx     | 1840 ++++++++---------
 .../src/EleChargeAlg.cxx                      |    3 +-
 .../src/EleChargeAlg.h                        |    7 +-
 .../util/EgEfficiencyCorr_mem_check.cxx       |   11 +-
 .../util/testEgEfficiencyCorrFwd.cxx          |  110 +
 .../util/testEgEfficiencyCorrWithoutFile.cxx  |    2 -
 12 files changed, 1191 insertions(+), 1253 deletions(-)
 create mode 100644 PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrFwd.cxx

diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/CMakeLists.txt b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/CMakeLists.txt
index 2fc8c91f9f91..1cbe18fd5810 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/CMakeLists.txt
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/CMakeLists.txt
@@ -37,7 +37,7 @@ atlas_depends_on_subdirs(
 
 # External dependencies:
 find_package( Boost )
-find_package( ROOT COMPONENTS Core MathCore Hist RIO MathMore )
+find_package( ROOT COMPONENTS Core Hist MathCore)
 
 # Component(s) in the package:
 atlas_add_library( ElectronEfficiencyCorrectionLib
@@ -52,8 +52,7 @@ atlas_add_library( ElectronEfficiencyCorrectionLib
 if( NOT XAOD_STANDALONE )
    atlas_add_component( ElectronEfficiencyCorrection
       src/*.h src/*.cxx src/components/*.cxx
-      LINK_LIBRARIES xAODEgamma PATInterfaces AthenaBaseComps xAODCore
-      xAODEventInfo GaudiKernel ElectronEfficiencyCorrectionLib )
+      LINK_LIBRARIES  AthenaBaseComps GaudiKernel ElectronEfficiencyCorrectionLib )
 endif()
 
 atlas_add_dictionary( ElectronEfficiencyCorrectionDict
@@ -64,7 +63,7 @@ atlas_add_dictionary( ElectronEfficiencyCorrectionDict
 # Utilities provided by the package:
 atlas_add_executable( EgEfficiencyCorr_mem_check
    util/EgEfficiencyCorr_mem_check.cxx
-   LINK_LIBRARIES AsgTools ElectronEfficiencyCorrectionLib CxxUtils )
+   LINK_LIBRARIES AsgTools ElectronEfficiencyCorrectionLib )
 
 #Test
 atlas_add_test(ut_SimpleInitTest
@@ -78,6 +77,12 @@ if( XAOD_STANDALONE )
       LINK_LIBRARIES ${ROOT_LIBRARIES} xAODRootAccess xAODEventInfo xAODEgamma
       xAODCore ElectronEfficiencyCorrectionLib )
 
+   atlas_add_executable( EgEfficiencyCorr_testEgEfficiencyCorrFwd
+      util/testEgEfficiencyCorrFwd.cxx util/SFHelpers.cxx
+      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+      LINK_LIBRARIES ${ROOT_LIBRARIES} xAODRootAccess xAODEventInfo xAODEgamma
+      xAODCore ElectronEfficiencyCorrectionLib )
+    
    atlas_add_executable( EgEfficiencyCorr_testEgEfficiencyCorrWithoutFile
       util/testEgEfficiencyCorrWithoutFile.cxx 
       util/CreateDummyEl.cxx util/SFHelpers.cxx
@@ -99,7 +104,6 @@ if( XAOD_STANDALONE )
  
 endif()
 
-
 # Install files from the package:
 atlas_install_joboptions( share/*.py)
 atlas_install_data( data/*.root data/*.txt )
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h
index 3cd56ab3ed7b..523dd353287e 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h
@@ -45,22 +45,15 @@ public:
         virtual ~AsgElectronEfficiencyCorrectionTool();
 
 
-public:
         /// Gaudi Service Interface method implementations
         virtual StatusCode initialize();
 
-        /// Gaudi Service Interface method implementations
-        virtual StatusCode finalize();
-
         /// Metadata methods
         virtual StatusCode beginInputFile();    
         virtual StatusCode beginEvent();
 
-public:
-
         int getNumberOfToys( ){return m_number_of_toys;} ;
 
-
         CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::Electron& inputObject, double& efficiencyScaleFactor) const;
         CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::Electron& inputObject) const;
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h
index cf8b5ddd9176..bff2eb709977 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h
@@ -7,7 +7,7 @@
 
 #include "AsgTools/AsgTool.h"
 //#include "ElectronChargeEfficiencyCorrectionTool/IElectronChargeEfficiencyCorrectionTool.h"
-#include "AsgAnalysisInterfaces/IEfficiencyScaleFactorTool.h"
+#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
 #include "PATInterfaces/ISystematicsTool.h"
 #include "TH2.h"
 // #include "xAODTruth/TruthParticle.h"
@@ -28,10 +28,10 @@ namespace xAOD {
 namespace CP {
 
   class ElectronChargeEfficiencyCorrectionTool
-    : virtual public CP::IEfficiencyScaleFactorTool,
+    : virtual public IAsgElectronEfficiencyCorrectionTool,
     public asg::AsgTool
   {
-    ASG_TOOL_CLASS2(ElectronChargeEfficiencyCorrectionTool, CP::IEfficiencyScaleFactorTool, CP:: ISystematicsTool)
+    ASG_TOOL_CLASS(ElectronChargeEfficiencyCorrectionTool, IAsgElectronEfficiencyCorrectionTool)
 
   public:
 
@@ -57,10 +57,13 @@ namespace CP {
     virtual StatusCode finalize();
 
     /// Retrieve the Scale factor
-    virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::IParticle& part, double& sf) const;
+    virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::Electron& part, double& sf) const;
 
     /// Decorate the electron
-    virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::IParticle& part) const;
+    virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::Electron& part) const;
+
+    /// The following method is not implemented properly in this tool
+    virtual int systUncorrVariationIndex( const xAOD::Electron &inputObject) const;
 
     /// Systematics
     //  void applySysVariation();
@@ -90,7 +93,7 @@ namespace CP {
   private:
 
     /// Get the charge flip rate rate given pt, eta, histogram
-    float getChargeFlipRate( double eta, double pt, TH2 *hrates, double& flipRate) const;
+    float getChargeFlipRate( double eta, double pt, TH2D *hrates, double& flipRate) const;
 
     /// Get the charge of the original electron
     CP::CorrectionCode getEleTruthCharge( const xAOD::Electron& ele, int& truthcharge) const;
@@ -106,8 +109,8 @@ namespace CP {
     std::string m_eventInfoCollectionName;
 
     /// Histogram that holds the correction rates for Monte Carlo
-    std::map<std::string, std::vector<TH2*> > m_SF_SS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
-    std::map<std::string, std::vector<TH2*> > m_SF_OS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
+    std::map<std::string, std::vector<TH2D*> > m_SF_SS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
+    std::map<std::string, std::vector<TH2D*> > m_SF_OS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
 
     //cuts // further variables to bin in
     std::vector<unsigned int> m_RunNumbers;
@@ -152,8 +155,8 @@ namespace CP {
     CP::SystematicSet m_mySysConf;
     CP::SystematicSet m_affectingSys;
 
-    /// Currently applied systematics
-    CP::SystematicSet* m_appliedSystematics;
+ /// Currently applied systematics
+   CP::SystematicSet* m_appliedSystematics;
  
     /// Decorator
     std::string m_sf_decoration_name;
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/TElectronEfficiencyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/TElectronEfficiencyCorrectionTool.h
index a2b1d5383681..d24ab74ecbc9 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/TElectronEfficiencyCorrectionTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/ElectronEfficiencyCorrection/TElectronEfficiencyCorrectionTool.h
@@ -1,6 +1,7 @@
+// Dear emacs, this is -*- c++ -*-
 /*
    Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
- */
+*/
 
 #ifndef __TELECTRONEFFICIENCYCORRECTIONTOOL__
 #define __TELECTRONEFFICIENCYCORRECTIONTOOL__
@@ -10,20 +11,21 @@
   @brief Calculate the egamma scale factors 
   Implementation class for the e/gamma Efficiency Scale Factors. This code implements
   the underlying logic of accessign the ROOT files containing the recommendations.
-
-  @author Kristin Lohwasser, Karsten Koeneke, Felix Buehrer
+  @authors Kristin Lohwasser, Karsten Koeneke, Felix Buehrer
   @date   January 2013
+  @updated by Christos Anastopoulos 2017-2018
   */
 
 // STL includes
 #include <vector>
 #include <string>
 #include <array>
+#include <unordered_map>
 #include <map>
 //Root fwd declares
 class TKey;
-class TH1D;
-class TH2D;
+class TH1;
+class TH2;
 // ROOT includes
 #include "TRandom3.h"
 #include "TObjArray.h"
@@ -32,157 +34,141 @@ class TH2D;
 #include "AsgTools/AsgMessaging.h"
 
 namespace Root {
-    class TElectronEfficiencyCorrectionTool : public asg::AsgMessaging
-    {
-    public: 
-        /**
-         * The position of each result
-         */
-        enum struct Position{
-            SF=0,
-            Total=1,
-            Stat=2,
-            NSys=3,
-            UnCorr=4,
-            GlobalBinNumber=5,
-            End=6
-        };
-
-        /** Standard constructor */
-        TElectronEfficiencyCorrectionTool( const char* name="TElectronEfficiencyCorrectionTool" );
-
-        /** Standard destructor */
-        ~TElectronEfficiencyCorrectionTool();
-
-        // Main methods
-        /** Initialize this class */
-        int initialize();
-
-        /** Finalize this class; everything that should be done after the event loop should go here */
-        inline int finalize() { return 1; }
-
-        /** The main salculate method: the actual cuts are applied here */
-        int calculate( const PATCore::ParticleDataType::DataType dataType,
-                const unsigned int runnumber,
-                const double cluster_eta,
-                const double et, /* in MeV */
-                std::vector<double>& result,
-                size_t& index_of_corr,
-                size_t& index_of_toys) const;
-
-        /// Add an input file
-        inline void addFileName ( const std::string& val ) { 
-            m_corrFileNameList.push_back(val); 
-        }
-        ///MC Toys Helper functions
-        inline void bookToyMCScaleFactors(const int nToyMC) {
-            m_doToyMC = true;
-            m_nToyMC = nToyMC;
-        }
-        inline void bookCombToyMCScaleFactors(const int nToyMC) {
-            m_doCombToyMC = true;
-            m_nToyMC = nToyMC;
-        }
-
-        ///Helpers to get the binning of the uncertainties
-        int getNbins(std::map<float, std::vector<float> >&) const; 
-        inline int getNSyst() const {
-            return m_nSysMax;
-        }
-        ///Detail Level
-        enum detailLevel{simple,medium,detailed,detailLevelEnd};
-        /// Set the detail level 
-        inline void setDetailLevel (const int input_detailLevel ) { 
-            m_detailLevel = input_detailLevel; 
-        }
-        ///Set the Random Seed
-        inline void setSeed( const unsigned long int seed) { 
-            m_seed = seed; 
-        }
-
-    private:
-        // Private methods
-        /// Load all histograms from the input file(s)
-        int getHistograms();
-
-        int setupHistogramsInFolder( const TObjArray& dirNameArray, 
-                int lastIdx );
-
-        void calcDetailLevels(const TH1D *eig,
-                std::array<int,detailLevelEnd>& sLevel,
-                int& nSys) const ;
-
-        std::vector<TObjArray> buildToyMCTable (const TObjArray &sf, 
-                const TObjArray &eig, 
-                const TObjArray& stat, 
-                const TObjArray& uncorr, 
-                const std::vector<TObjArray> &corr);
-
-        std::vector<TH2D*> buildSingleToyMC(const TH2D* sf, 
-                const TH2D* stat, 
-                const TH2D* uncorr, 
-                const TObjArray& corr,
-                const std::array<int,detailLevelEnd> sLevel,
-                int& randomCounter);
-
-        TH2D* buildSingleCombToyMC(const TH2D *sf, 
-                const TH2D* stat, 
-                const TH2D* uncorr, 
-                const TObjArray& corr,
-                const std::array<int,detailLevelEnd> sLevel,
-                const int nSys,
-                int& randomCounter);
-
-        /// Fill and interpret the setup, depending on which histograms are found in the input file(s)
-        int setup( const TObjArray& hist,
-                std::vector< TObjArray >& histList,
-                std::vector< unsigned int >& beginRunNumberList,
-                std::vector< unsigned int >& endRunNumberList,
-                const int runNumBegin,
-                const int runNumEnd) const ;
-
-    private :
-        ///Private data members
-        bool m_doToyMC;
-        bool m_doCombToyMC;
-        //// The detail level
-        int m_detailLevel;
-        //The number of toys
-        int m_nToyMC;
-        /// The Random seed
-        unsigned long int m_seed;
-        ///Maximum number of systematics
-        int m_nSysMax;
-        // The positions of the efficiency scale factor correlated sustematic uncertainties in the result
-        std::vector<int> m_position_corrSys; 
-        /// The positions of the toy MC scale factors
-        std::vector<int> m_position_uncorrToyMCSF; ///Uncorrelated toy systematics
-        ///The representation of the prepared toy SF tables
-        std::vector< std::vector<TObjArray>> m_uncorrToyMCSystFull;
-        std::vector< std::vector<TObjArray>> m_uncorrToyMCSystFast;
-        /// The list of file name(s)
-        std::vector< std::string > m_corrFileNameList;
-        /// List of run numbers where histograms become valid for full simulation
-        std::vector< unsigned int > m_begRunNumberList;
-        /// List of run numbers where histograms stop being valid for full simulation
-        std::vector< unsigned int > m_endRunNumberList;
-        /// List of run numbers where histograms become valid for fast simulation
-        std::vector< unsigned int > m_begRunNumberListFastSim;
-        /// List of run numbers where histograms stop being valid for fast simulation
-        std::vector< unsigned int > m_endRunNumberListFastSim;    
-        //The vector holding the keys
-        std::vector<int> m_keys;
-        /// List of histograms for full Geant4 simulation
-        std::map<int, std::vector< TObjArray > > m_histList;
-        std::vector< std::vector< TObjArray > > m_sysList;
-        /// List of histograms for fast simulation
-        std::map<int, std::vector< TObjArray > > m_fastHistList;
-        std::vector< std::vector< TObjArray > > m_fastSysList;
-        //The Random generator class   
-        TRandom3 m_Rndm;
-    }; // End: class definition
-
+class TElectronEfficiencyCorrectionTool : public asg::AsgMessaging
+{
+public: 
+  /**
+   * The position of each result
+   */
+  enum struct Position{
+    SF=0,
+    Total=1,
+    Stat=2,
+    NSys=3,
+    UnCorr=4,
+    GlobalBinNumber=5,
+    End=6
+  };
+
+  /** Standard constructor */
+  TElectronEfficiencyCorrectionTool( const char* name="TElectronEfficiencyCorrectionTool" );
+
+  /** Standard destructor */
+  ~TElectronEfficiencyCorrectionTool();
+
+  // Main methods
+  /** Initialize this class */
+  int initialize();
+
+  /** The main calculate method: the actual cuts are applied here */
+  int calculate( const PATCore::ParticleDataType::DataType dataType,
+                 const unsigned int runnumber,
+                 const double cluster_eta,
+                 const double et, /* in MeV */
+                 std::vector<double>& result,
+                 size_t& index_of_corr,
+                 size_t& index_of_toys) const;
+
+  /// Add an input file
+  inline void addFileName ( const std::string& val ) { 
+    m_corrFileNameList.push_back(val); 
+  }
+  ///MC Toys Helper functions
+  inline void bookToyMCScaleFactors(const int nToyMC) {
+    m_doToyMC = true;
+    m_nToyMC = nToyMC;
+  }
+  inline void bookCombToyMCScaleFactors(const int nToyMC) {
+    m_doCombToyMC = true;
+    m_nToyMC = nToyMC;
+  }
+
+  ///Helpers to get the binning of the uncertainties
+  int getNbins(std::map<float, std::vector<float> >&) const; 
+  inline int getNSyst() const {
+    return m_nSysMax;
+  }
+  
+  ///Set the Random Seed
+  inline void setSeed( const unsigned long int seed) { 
+    m_seed = seed; 
+  }
+
+private:
+  // Private methods
+  /// Load all histograms from the input file(s)
+  int getHistograms();
+
+  int setupHistogramsInFolder( const TObjArray& dirNameArray, 
+                               int lastIdx );
+
+  bool setupUncorrToySyst(std::unordered_map<int, TObjArray>& objs,
+                          std::vector<TObjArray>& sysObjs,
+                          std::vector< std::vector<TObjArray>>& uncorrToyMCSyst);
+
+   std::vector<TObjArray> buildToyMCTable (const TObjArray &sf, 
+                                          const TObjArray &eig, 
+                                          const TObjArray& stat, 
+                                          const TObjArray& uncorr, 
+                                          const std::vector<TObjArray> &corr);
+
+  std::vector<TH2*> buildSingleToyMC(const TH2* sf, 
+                                     const TH2* stat, 
+                                     const TH2* uncorr, 
+                                     const TObjArray& corr,
+                                     int& randomCounter);
+
+  TH2* buildSingleCombToyMC(const TH2 *sf, 
+                            const TH2* stat, 
+                            const TH2* uncorr, 
+                            const TObjArray& corr,
+                            const int nSys,
+                            int& randomCounter);
+
+  void setupTempMapsHelper(TObject* obj,
+                           std::unordered_map<int, TObjArray>& objs,
+                           std::vector<TObjArray >& sysObjs,int& seenSystematics) ;
+
+  /// Fill and interpret the setup, depending on which histograms are found in the input file(s)
+  int setup( const TObjArray& hist,
+             std::vector< TObjArray >& histList,
+             std::vector< unsigned int >& beginRunNumberList,
+             std::vector< unsigned int >& endRunNumberList,
+             const int runNumBegin,
+             const int runNumEnd) const ;
+
+private :
+  ///Flag to control Toys
+  bool m_doToyMC;
+  bool m_doCombToyMC;
+  ///The number of toys
+  int m_nToyMC;
+  /// The Random seed
+  unsigned long int m_seed;
+  ///Maximum number of systematics
+  int m_nSysMax;
+  //The representation of the prepared toy SF tables
+  std::vector< std::vector<TObjArray>> m_uncorrToyMCSystFull;
+  std::vector< std::vector<TObjArray>> m_uncorrToyMCSystFast;
+  /// The list of file name(s)
+  std::vector< std::string > m_corrFileNameList;
+  /// List of run numbers where histograms become valid for full simulation
+  std::vector< unsigned int > m_begRunNumberList;
+  /// List of run numbers where histograms stop being valid for full simulation
+  std::vector< unsigned int > m_endRunNumberList;
+  /// List of run numbers where histograms become valid for fast simulation
+  std::vector< unsigned int > m_begRunNumberListFastSim;
+  /// List of run numbers where histograms stop being valid for fast simulation
+  std::vector< unsigned int > m_endRunNumberListFastSim;    
+ /// List of histograms for full Geant4 simulation
+  std::unordered_map<int, std::vector< TObjArray > > m_histList;
+  std::vector< std::vector< TObjArray > > m_sysList;
+  /// List of histograms for fast simulation
+  std::unordered_map<int, std::vector< TObjArray > > m_fastHistList;
+  std::vector< std::vector< TObjArray > > m_fastSysList;
+  //The Random generator class   
+  TRandom3 m_Rndm;
+}; // End: class definition
 } // End: namespace Root
 
 #endif
-
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/AsgElectronEfficiencyCorrectionTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/AsgElectronEfficiencyCorrectionTool.cxx
index 63053c2bfa7f..3f00022264dd 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/AsgElectronEfficiencyCorrectionTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/AsgElectronEfficiencyCorrectionTool.cxx
@@ -58,7 +58,7 @@ AsgElectronEfficiencyCorrectionTool::AsgElectronEfficiencyCorrectionTool(std::st
         // Declare the needed properties
         declareProperty("CorrectionFileNameList", m_corrFileNameList,
                 "List of file names that store the correction factors for simulation.");
-        declareProperty("MapFilePath", m_mapFile = "ElectronEfficiencyCorrection/2015_2017/rel21.2/Moriond_February2018_v1/map0.txt" ,
+        declareProperty("MapFilePath", m_mapFile = "ElectronEfficiencyCorrection/2015_2017/rel21.2/Moriond_February2018_v2/map6.txt" ,
                 "Full path to the map file");
         declareProperty("RecoKey", m_recoKey = "" ,
                 "Key associated with reconstruction");
@@ -86,9 +86,6 @@ AsgElectronEfficiencyCorrectionTool::~AsgElectronEfficiencyCorrectionTool() {
     if (m_UncorrRegions) {
         delete m_UncorrRegions;
     }
-    if (finalize().isFailure()) {
-        ATH_MSG_ERROR("Failure in AsgElectronEfficiencyCorrectionTool finalize()");
-    }
     delete m_rootTool;
 }
 
@@ -148,6 +145,13 @@ AsgElectronEfficiencyCorrectionTool::initialize() {
         if (m_corrFileNameList.at(i).find("efficiencySF.offline.RecoTrk") != std::string::npos) {
             m_sysSubstring = "Reco_";
         }
+        if (m_corrFileNameList.at(i).find("efficiencySF.offline.Fwd") != std::string::npos) {
+            m_sysSubstring = "FwdID_";
+	    if ( m_correlation_model_name == "SIMPLIFIED" ) {
+	      ATH_MSG_ERROR("The SIMPLIFIED correlation model is not implemented for fwd electrons");
+	      return StatusCode::FAILURE;
+	    }
+        }
         if (m_corrFileNameList.at(i).find("efficiencySF.Isolation") != std::string::npos) {
             m_sysSubstring = "Iso_";
         }
@@ -241,18 +245,6 @@ AsgElectronEfficiencyCorrectionTool::initialize() {
     return StatusCode::SUCCESS;
 }
 
-/// =============================================================================
-// Athena finalize method
-// =============================================================================
-StatusCode
-AsgElectronEfficiencyCorrectionTool::finalize() {
-    if (!(m_rootTool->finalize())) {
-        ATH_MSG_ERROR("Something went wrong at finalize!");
-        return StatusCode::FAILURE;
-    }
-    return StatusCode::SUCCESS;
-}
-
 CP::CorrectionCode
 AsgElectronEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD::Electron &inputObject,
         double &efficiencyScaleFactor) const {
@@ -285,7 +277,14 @@ AsgElectronEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD::Electr
         ATH_MSG_ERROR("ERROR no cluster associated to the Electron \n"); 
         return CP::CorrectionCode::Error; 
     }
-    cluster_eta = cluster->etaBE(2);
+
+    // we need to use different variables for central and forward electrons
+    static const SG::AuxElement::ConstAccessor< uint16_t > accAuthor( "author" );
+    if( accAuthor.isAvailable(inputObject) && accAuthor(inputObject) == xAOD::EgammaParameters::AuthorFwdElectron ) { 
+      cluster_eta = cluster->eta();
+    } else {
+      cluster_eta = cluster->etaBE(2);
+    }
 
     size_t CorrIndex{0};
     size_t MCToysIndex{0};
@@ -628,9 +627,6 @@ StatusCode AsgElectronEfficiencyCorrectionTool::beginEvent(){
     return StatusCode::SUCCESS;
 }
 
-//===============================================================================
-// Get Simulation flavor (FastSim or FullSim) from METADATA
-//===============================================================================
 StatusCode
 AsgElectronEfficiencyCorrectionTool::get_simType_from_metadata(PATCore::ParticleDataType::DataType& result) const{
 
@@ -876,5 +872,3 @@ AsgElectronEfficiencyCorrectionTool::getValue(const std::string& strKey, std::st
     }
     return "";
 }
-
-
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/ElectronChargeEfficiencyCorrectionTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/ElectronChargeEfficiencyCorrectionTool.cxx
index cda599834d4f..5a808df757dc 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/ElectronChargeEfficiencyCorrectionTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/ElectronChargeEfficiencyCorrectionTool.cxx
@@ -10,6 +10,7 @@
    @date   September 2015
 */
 // Include this class's header
+// #include "ElectronChargeEfficiencyCorrectionTool/ElectronChargeEfficiencyCorrectionTool.h"
 #include "ElectronEfficiencyCorrection/ElectronChargeEfficiencyCorrectionTool.h"
 // xAOD includes
 #include "PathResolver/PathResolver.h"
@@ -50,7 +51,6 @@ CP::ElectronChargeEfficiencyCorrectionTool::ElectronChargeEfficiencyCorrectionTo
   m_filtered_sys_sets(),
   m_mySysConf(),
   m_affectingSys(),
-  m_appliedSystematics(0),
   m_sf_decoration_name("chargeIDEffiSF"),
   m_sfDec(0)
 {
@@ -115,8 +115,8 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
   // SFCentral_RunNumber<minRN>-<maxRN>_Nvtx<minNvtx>-<maxNvtx>
 
   //     Then can create a key that will dynamically give us access to a map:
-  //    std::map<std::string key, std::vector<TH2 *>> m_SF_SS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
-  //     std::map<std::string key, std::vector<TH2 *>> m_SF_OS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
+  //    std::map<std::string key, std::vector<TH2D *>> m_SF_SS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
+  //     std::map<std::string key, std::vector<TH2D *>> m_SF_OS;     // keys (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
   // TFile*         data/ChMisIDSF_TightLL_FixedCutTight.root
   //  KEY: TH2F     SFCentral_RunNumber296939_311481_SS;1   SFCentral_RunNumber296939_311481_SS
   //  KEY: TH2F     SFCentral_RunNumber296939_311481_OS;1   SFCentral_RunNumber296939_311481_OS
@@ -129,14 +129,14 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
   m_SF_SS.clear();
   m_SF_OS.clear();
   TList* keyListfolder = rootFile->GetListOfKeys();
-  std::vector<std::string> names;
+std::vector<std::string> names;
 
   for ( int j=0; j<keyListfolder->GetEntries(); j++ ){
-    names.push_back(( keyListfolder->At(j)->GetName() ));
-  }
-  std::sort(names.begin(), names.end());
+names.push_back(( keyListfolder->At(j)->GetName() ));
+}
+std::sort(names.begin(), names.end());
 
-  for ( unsigned int j=0; j<names.size(); j++ ){
+ for ( unsigned int j=0; j<names.size(); j++ ){
 
     std::string name = names.at(j);
     ATH_MSG_DEBUG("Got ROOT object with name: " << name);
@@ -166,14 +166,14 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
           m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runhigh.c_str())) );
         }
         ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
-        m_SF_OS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_OS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
       else {
         std::string histid = ( names.at(j) );
         histid.erase(0,10);
         histid.erase(histid.size()-3,3);// remove _SS, _OS
         ATH_MSG_VERBOSE("Using histid (do we this in ? SS): " << histid);
-        m_SF_SS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_SS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
     }///// if ( name.find(Form("SFCentral_") ) != std::string::npos)
 
@@ -197,14 +197,14 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
           std::string runlow = histid;
           runlow.erase(histid.find(Form("RunNumber") ),9);
           runlow.erase(runlow.find("_"),runlow.size() );
-	  //          m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runlow.c_str())) );
+//          m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runlow.c_str())) );
           std::string runhigh = histid;
           runhigh.erase(histid.find(Form("RunNumber") ),9);
           runhigh.erase(0,runhigh.find("_")+1);
-	  //          m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runhigh.c_str())) );
+//          m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runhigh.c_str())) );
         }
         ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
-        m_SF_OS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_OS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
       else {
         std::string histid = ( names.at(j) );
@@ -212,7 +212,7 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
         histid.erase(0,5);
         histid.erase(histid.size()-3,3);// remove _SS, _OS
         ATH_MSG_VERBOSE("Using histid (do we this in ? SS): " << histid);
-        m_SF_SS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_SS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
 
     }///// if ( name.find(Form("SYST") ) != std::string::npos)
@@ -242,14 +242,14 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
           std::string runlow = histid;
           runlow.erase(histid.find(Form("RunNumber") ),9);
           runlow.erase(runlow.find("_"),runlow.size() );
-	  //        m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runlow.c_str())) );
+  //        m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runlow.c_str())) );
           std::string runhigh = histid;
           runhigh.erase(histid.find(Form("RunNumber") ),9);
           runhigh.erase(0,runhigh.find("_")+1);
-	  //      m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runhigh.c_str())) );
+    //      m_RunNumbers.push_back( static_cast<unsigned int>(atoi(runhigh.c_str())) );
         }
         ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
-        m_SF_OS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_OS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
       else {
         std::string histid = ( names.at(j) );
@@ -257,7 +257,7 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
         histid.erase(histid.size()-3,3);// remove _SS, _OS
         histid.erase(0,histid.find("_")+1);// remove _SS, _OS
         ATH_MSG_VERBOSE("Using histid (sys ? SS): " << histid);
-        m_SF_SS[histid].push_back( (TH2*)rootFile->Get( names.at(j).c_str() ));
+        m_SF_SS[histid].push_back( (TH2D*)rootFile->Get( names.at(j).c_str() ));
       }
 
     }///end // if ( name.find(Form("SYST") ) != std::string::npos)
@@ -268,8 +268,8 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
 
   if ( m_SF_OS.size() <1 || m_SF_SS.size() <1 || m_SF_SS.size()!=m_SF_OS.size() ) {
     ATH_MSG_ERROR("OS/SS SF vectors not filled or of different size. -- Problem with files. -- Report to <hn-atlas-EGammaWG@cern.ch>");
-    return StatusCode(CP::CorrectionCode::Error);
-  }
+    return CP::CorrectionCode::Error;
+}
 
 
   std::sort(m_RunNumbers.begin(),m_RunNumbers.end());
@@ -282,7 +282,7 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::initialize()
 
   /// here: need to use iterator over map!!!
   ATH_MSG_DEBUG("Having m_SF_OS.size() = " << m_SF_OS.size());
-  std::map<std::string,std::vector<TH2*> >::iterator it = m_SF_OS.begin();
+  std::map<std::string,std::vector<TH2D*> >::iterator it = m_SF_OS.begin();
 
   // Get the kinematic limits
   m_eta_lowlimit   = (*it).second.at(0)->GetYaxis()->GetXmin();
@@ -328,7 +328,7 @@ StatusCode CP::ElectronChargeEfficiencyCorrectionTool::finalize()
 //
 
 CP::CorrectionCode
-CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD::IParticle& part, double& sf) const {
+CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD::Electron& part, double& sf) const {
   ATH_MSG_DEBUG("In CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD::IParticle& part, double& sf) const");
   if ( part.type() != xAOD::Type::Electron ){
     ATH_MSG_ERROR("This function requires an electron to be passed. Failing!");
@@ -359,7 +359,7 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
   const double ele_pt  = ele.pt()*m_gevmev;
   const double ele_eta = std::abs( ele.caloCluster()->etaBE(2)   );
 
-  // getting the truth charge
+   // getting the truth charge
   int truth_ele_charge = 9999;
   CP::CorrectionCode charge_result = this->getEleTruthCharge( ele, truth_ele_charge); //// ## Giulia: second function to change
   if ( charge_result != CP::CorrectionCode::Ok ) {
@@ -402,9 +402,9 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
     }
     ATH_MSG_DEBUG("Number of RunNumbers: " << m_RunNumbers.size() );
     for ( std::size_t r=0; r<m_RunNumbers.size(); r++ ){
-      ATH_MSG_DEBUG(  m_RunNumbers.at(r) );
-    }
-    ATH_MSG_VERBOSE("DONE");
+ATH_MSG_DEBUG(  m_RunNumbers.at(r) );
+	}
+ATH_MSG_VERBOSE("DONE");
 
     for ( std::size_t r=0; r<m_RunNumbers.size()-1; r++ ){
       ATH_MSG_VERBOSE(m_RunNumbers.size()-1 << "  " << m_RunNumbers.at(r) << "  " << m_RunNumbers.at(r+1) << "  " << runnumber);
@@ -416,16 +416,16 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
     }
 
     if (runnumber<m_RunNumbers.at(0) || (runnumber>m_RunNumbers.at(m_RunNumbers.size()-1) )) {
-      ATH_MSG_DEBUG("RunNumber not in valid RunNumber Range ");
-      sf = -9999.0;
-      return CP::CorrectionCode::OutOfValidityRange;
-    }
+    ATH_MSG_DEBUG("RunNumber not in valid RunNumber Range ");
+    sf = -9999.0;
+    return CP::CorrectionCode::OutOfValidityRange;
+      }
 
   }
 
-  // Determine WHICH histograms to use here
-  const std::vector<TH2*>& SShistograms = m_SF_SS.at(cutRunNumber.c_str());
-  const std::vector<TH2*>& OShistograms = m_SF_OS.at(cutRunNumber.c_str());
+   // Determine WHICH histograms to use here
+  const std::vector<TH2D*>& SShistograms = m_SF_SS.at(cutRunNumber.c_str());
+  const std::vector<TH2D*>& OShistograms = m_SF_OS.at(cutRunNumber.c_str());
 
 
   // here check OS or SS
@@ -449,14 +449,14 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
     }
   }
 
-  ATH_MSG_DEBUG("eta: " << ele_eta << "  pt: "<< ele_pt );
-  ATH_MSG_DEBUG("SF Rates---- . SF: " << sf );
+   ATH_MSG_DEBUG("eta: " << ele_eta << "  pt: "<< ele_pt );
+   ATH_MSG_DEBUG("SF Rates---- . SF: " << sf );
 
 
   // Systematics ------------------------------------------------------------------------------------------------------
   double val_stat;
 
-  /// STAT
+   /// STAT
   if (isOS) {
     retVal = this->getChargeFlipRate( ele_eta, ele_pt,OShistograms.at(1), val_stat);
     if ( retVal != 0 ) {
@@ -475,7 +475,7 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
 
   std::vector<float> systs;
   double val_sys{0.0};
-  /// STAT
+   /// STAT
   for (unsigned int s=2;s<OShistograms.size();s++){
     if (isOS) {
       retVal = this->getChargeFlipRate( ele_eta, ele_pt,OShistograms.at(s), val_sys);
@@ -495,7 +495,7 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
     systs.push_back(static_cast<float>(val_sys));
   }
 
-  ATH_MSG_DEBUG(" ... nominal SF: "   << sf);
+    ATH_MSG_DEBUG(" ... nominal SF: "   << sf);
 
 
   if ( m_mySysConf.size()==0 ) {
@@ -527,7 +527,7 @@ CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor(const xAOD:
 
 
 CP::CorrectionCode
-CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor(const xAOD::IParticle& part) const {
+CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor(const xAOD::Electron& part) const {
   ATH_MSG_DEBUG("In CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor(const xAOD::IParticle& part) const");
   double sf = 0.0;
   CP::CorrectionCode result = this->getEfficiencyScaleFactor(part,sf);
@@ -537,6 +537,11 @@ CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor(const xAO
 
 }
 
+int CP::ElectronChargeEfficiencyCorrectionTool::systUncorrVariationIndex( const xAOD::Electron&) const {
+  ATH_MSG_WARNING("systUncorrVariationIndex is not implemented in ElectronChargeEfficiencyCorrectionTool");
+  return 0;
+}
+
 
 //// Giulia: This one won't exist!! ################################################ Kristin: But ok to just comment out for the moment
 
@@ -622,7 +627,7 @@ CP::CorrectionCode CP::ElectronChargeEfficiencyCorrectionTool::getEleTruthCharge
 CP::CorrectionCode CP::ElectronChargeEfficiencyCorrectionTool::isGoodEle( const xAOD::Electron& ele, bool& goodele) const
 {
 
-  // good ele => (firstEgMotherPdgId) == 11 ## valid for both iso and conversion ele
+   // good ele => (firstEgMotherPdgId) == 11 ## valid for both iso and conversion ele
 
   goodele = false;
   int firstEgPdgId = -9999;
@@ -655,9 +660,9 @@ CP::CorrectionCode CP::ElectronChargeEfficiencyCorrectionTool::isGoodEle( const
 
 
 // Get the correction rate given pt (E), eta, histogram
-float CP::ElectronChargeEfficiencyCorrectionTool::getChargeFlipRate( double eta, double pt, TH2 *hrates, double& flipRate) const
+float CP::ElectronChargeEfficiencyCorrectionTool::getChargeFlipRate( double eta, double pt, TH2D *hrates, double& flipRate) const
 {
-  ATH_MSG_VERBOSE(" -> in: getChargeFlipRate(" << pt <<", " << eta << " TH2, double&)");
+  ATH_MSG_VERBOSE(" -> in: getChargeFlipRate(" << pt <<", " << eta << " TH2D, double&)");
 
   if ( eta < m_eta_lowlimit || eta > m_eta_uplimit ) {
 
@@ -702,7 +707,7 @@ CP::SystematicSet CP::ElectronChargeEfficiencyCorrectionTool::affectingSystemati
     result.insert (SystematicVariation (Form("EL_CHARGEID_SYS%s",m_systematics.at(i).c_str()), 1));
     result.insert (SystematicVariation (Form("EL_CHARGEID_SYS%s",m_systematics.at(i).c_str()), -1));
   }
-  return result;
+   return result;
 }
 
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/TElectronEfficiencyCorrectionTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/TElectronEfficiencyCorrectionTool.cxx
index 761ccfb56d84..1fd6b01d3555 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/TElectronEfficiencyCorrectionTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/Root/TElectronEfficiencyCorrectionTool.cxx
@@ -9,7 +9,6 @@
   @date   July 2012
   */
 
-
 // This class header
 #include "ElectronEfficiencyCorrection/TElectronEfficiencyCorrectionTool.h"
 // STL includes
@@ -29,1065 +28,922 @@
 #include "TObjString.h"
 #include "TMD5.h"
 
-namespace{
-    template <class T>
-        inline std::string toString(const T& in){
-            std::stringstream stream;
-            stream << in;
-            return stream.str();
-        }
-    const std::string LowPt_string("LowPt");
+namespace mapkey{
+enum key{ sf =1,
+  stat=2,
+  eig=3,
+  uncorr=4,	      
+  sys=5,
+  end=6
+};
+const char* keytostring (int input){
+  switch(input){
+  case(sf) : 
+    return "sf";
+  case(stat) : 
+    return "stat";
+  case(eig) : 
+    return "eig";
+  case(uncorr) : 
+    return "uncorr";
+  case(sys) : 
+    return "sys";
+  }
+  return "";
+}
 }
 
-namespace mapkey{
-    enum key{ sf =1,
-        stat=2,
-        eig=3,
-        uncorr=4,	      
-        sys=5,
-        end=6
-    };
-    const char* keytostring (int input){
-        switch(input){
-        case(sf) : 
-            return "sf";
-        case(stat) : 
-            return "stat";
-        case(eig) : 
-            return "eig";
-        case(uncorr) : 
-            return "uncorr";
-        case(sys) : 
-            return "sys";
-        }
-        return "";
-    }
+
+namespace{
+const std::string LowPt_string("LowPt");
+const std::vector<int> s_keys={mapkey::sf,mapkey::stat,mapkey::eig,mapkey::uncorr};
 }
 
+
 Root::TElectronEfficiencyCorrectionTool::TElectronEfficiencyCorrectionTool(const char *name) :
-    asg::AsgMessaging(std::string(name)),
-    m_doToyMC(false),
-    m_doCombToyMC(false),
-    m_detailLevel(2),
-    m_nToyMC(0),
-    m_seed(0),
-    m_nSysMax(0),
-    m_Rndm()
+  asg::AsgMessaging(std::string(name)),
+  m_doToyMC(false),
+  m_doCombToyMC(false),
+  m_nToyMC(0),
+  m_seed(0),
+  m_nSysMax(0),
+  m_Rndm()
 {
-    //Setup the keys
-    m_keys.push_back(mapkey::sf);
-    m_keys.push_back(mapkey::stat);
-    m_keys.push_back(mapkey::eig);
-    m_keys.push_back(mapkey::uncorr);
 }
 
 Root::TElectronEfficiencyCorrectionTool::~TElectronEfficiencyCorrectionTool() {
 
-    /*
-     * Need some gymnastic to make sure that the 
-     * TObjArray elements are owned and deleted ...
-     */
-    for (auto  &tempit : m_histList) {
-        for (unsigned int i = 0; i < tempit.second.size(); ++i) {
-            tempit.second.at(i).SetOwner(kTRUE);
-        }
-    }
-    for (auto  &tempit : m_fastHistList) {
-        for (unsigned int i = 0; i < tempit.second.size(); ++i) {
-            tempit.second.at(i).SetOwner(kTRUE);
-        }
-    }
-    for (auto  &tempit : m_sysList) {
-        for (auto  &i : tempit) {
-            i.SetOwner(kTRUE);
-        }
-    }
-    for (auto  &tempit :  m_fastSysList) {
-        for (auto  &i : tempit) {
-            i.SetOwner(kTRUE);
-        }
-    }
-    for (auto  &tempit : m_uncorrToyMCSystFull) {
-        for (auto & i : tempit) {
-            i.SetOwner(kTRUE);
-        }
-    }  
-    for (auto  &tempit : m_uncorrToyMCSystFast) {
-        for (auto & i : tempit) {
-            i.SetOwner(kTRUE);
-        }
-    }
+  /*
+   * Make sure that all TObjArray 
+   * elements are owned and deleted 
+   */
+  for (auto  &tempit : m_histList) {
+    for (unsigned int i = 0; i < tempit.second.size(); ++i) {
+      tempit.second.at(i).SetOwner(kTRUE);
+    }
+  }
+  for (auto  &tempit : m_fastHistList) {
+    for (unsigned int i = 0; i < tempit.second.size(); ++i) {
+      tempit.second.at(i).SetOwner(kTRUE);
+    }
+  }
+  for (auto  &tempit : m_sysList) {
+    for (auto  &i : tempit) {
+      i.SetOwner(kTRUE);
+    }
+  }
+  for (auto  &tempit :  m_fastSysList) {
+    for (auto  &i : tempit) {
+      i.SetOwner(kTRUE);
+    }
+  }
+  for (auto  &tempit : m_uncorrToyMCSystFull) {
+    for (auto & i : tempit) {
+      i.SetOwner(kTRUE);
+    }
+  }  
+  for (auto  &tempit : m_uncorrToyMCSystFast) {
+    for (auto & i : tempit) {
+      i.SetOwner(kTRUE);
+    }
+  }
 }
 
-// =============================================================================
-// Initialize this correction tool
-// =============================================================================
 int Root::TElectronEfficiencyCorrectionTool::initialize() {
-    // use an int as a StatusCode
-    int sc(1);
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: "
-            << __LINE__ << ") " << "Debug flag set. Printing verbose output!");
-
-    //Check if files are present
-    if (m_corrFileNameList.size() == 0) {
-        ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                << " No file added!");
-        return 0;
-    }
-    ATH_MSG_DEBUG("Initializing tool with " << m_corrFileNameList.size() 
-            << " configuration file(s)");
-
-    // Check if the first file can be opened (needed for auto-setting of the seed based on the md5-sum of the file)
-    const std::unique_ptr<char> fname(gSystem->ExpandPathName(m_corrFileNameList[0].c_str()));
-    std::unique_ptr<TFile> rootFile_tmp = CxxUtils::make_unique<TFile> (fname.get(), "READ");
-    if (!rootFile_tmp) {
-        ATH_MSG_ERROR(
-                " (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                << "No ROOT file found here: " << m_corrFileNameList[0]);
-        return 0;
-    }
-    rootFile_tmp->Close();
-    // close it back again
-    //
-    //invalid input requested
-    if (m_doToyMC && m_doCombToyMC) {
-        ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                << " Both regular and combined toy MCs booked!" << " Only use one!");
-        return 0;
-    }
-    /*
-     * initialize the random number generator if toyMC propagation booked
-     * Use the 1st 4 bytes of the CheckSum of the reccomendation file
-     * as seed
-     */
-    if (m_doToyMC || m_doCombToyMC) {
-        if (m_seed == 0) {
-            std::unique_ptr<TMD5> tmd=CxxUtils::make_unique<TMD5>();
-            const char* tmd_as_string=tmd->FileChecksum(fname.get())->AsString();
-            m_seed = *(reinterpret_cast<const unsigned long int*>(tmd_as_string));
-            ATH_MSG_DEBUG("Seed (automatically) set to " << m_seed);
-        }else {
-            ATH_MSG_DEBUG("Seed set to " << m_seed);
-        }
-        m_Rndm= TRandom3(m_seed);
-    }
-    // Load the needed histograms
-    if (0 == getHistograms()) {
-        ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " << "! Problem when calling getHistograms()");
-        return 0;
-    }
-    const unsigned int nRunNumbersFull = m_begRunNumberList.size();
-    const unsigned int nRunNumbersFast = m_begRunNumberListFastSim.size();
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") "
-            << "Found " << nRunNumbersFast << " run number ranges for fast sim with a total of " <<
-            m_fastHistList[mapkey::sf].size() << " scale factor histograms.");
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") "
-            << "Found " << nRunNumbersFull << " run number ranges for full sim with a total of " <<
-            m_histList[mapkey::sf].size() << " scale factor histograms.");
-
-    /* 
-     * Set up the vector of the position of the corr syst 
-     * At this stage we should have the m_nSysMax and we know
-     * the beginning
-     * */
-    const size_t index_of_corr=static_cast<size_t> (Position::End);  
-    m_position_corrSys.resize(m_nSysMax);
-    for (int sys = 0; sys < m_nSysMax; ++sys) { 
-        m_position_corrSys[sys] = (index_of_corr + sys);
-    }  
-    /* 
-     * The same as above by now for the toys if applicable
-     */
-    const size_t index_of_toys=static_cast<size_t> (Position::End)+m_nSysMax;
-    m_position_uncorrToyMCSF.resize(m_nToyMC); 
-    for (int toy=0; toy < m_nToyMC; ++toy) {
-        m_position_uncorrToyMCSF[toy]=(index_of_toys+toy);
-    }
-
-    ATH_MSG_DEBUG("Tool succesfully initialized!");
-
-    return sc;
+  // use an int as a StatusCode
+  int sc(1);
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: "
+                << __LINE__ << ")\n" << "Debug flag set. Printing verbose output!");
+
+  //Check if files are present
+  if (m_corrFileNameList.size() == 0) {
+    ATH_MSG_ERROR(" No file added!");
+    return 0;
+  }
+  ATH_MSG_DEBUG("Initializing tool with " << m_corrFileNameList.size() 
+                << " configuration file(s)");
+
+  /* 
+   * Check if the first file can be opened 
+   * It is needed for auto-setting of the seed based on the md5-sum of the file
+   */
+  const std::unique_ptr<char> fname(gSystem->ExpandPathName(m_corrFileNameList[0].c_str()));
+  std::unique_ptr<TFile> rootFile_tmp( TFile::Open(fname.get(), "READ") );
+  if (!rootFile_tmp) {
+    ATH_MSG_ERROR("No ROOT file found here: " << m_corrFileNameList[0]);
+    return 0;
+  }
+  rootFile_tmp->Close();
+  
+  if (m_doToyMC && m_doCombToyMC) {
+    ATH_MSG_ERROR(" Both regular and combined toy MCs booked!" << " Only use one!");
+    return 0;
+  }
+  /*
+   * initialize the random number generator if toyMC propagation booked
+   * Use the 1st 4 bytes of the CheckSum of the reccomendation file as seed
+   */
+  if (m_doToyMC || m_doCombToyMC) {
+    if (m_seed == 0) {
+      std::unique_ptr<TMD5> tmd=CxxUtils::make_unique<TMD5>();
+      const char* tmd_as_string=tmd->FileChecksum(fname.get())->AsString();
+      m_seed = *(reinterpret_cast<const unsigned long int*>(tmd_as_string));
+      ATH_MSG_DEBUG("Seed (automatically) set to " << m_seed);
+    }else {
+      ATH_MSG_DEBUG("Seed set to " << m_seed);
+    }
+    m_Rndm= TRandom3(m_seed);
+  }
+  /*
+   * Load the needed histograms
+   */
+  if (0 == getHistograms()) {
+    ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" << "! Problem when calling getHistograms()");
+    return 0;
+  }
+  const unsigned int nRunNumbersFull = m_begRunNumberList.size();
+  const unsigned int nRunNumbersFast = m_begRunNumberListFastSim.size();
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
+                << "Found " << nRunNumbersFast << " run number ranges for fast sim with a total of " <<
+                m_fastHistList[mapkey::sf].size() << " scale factor histograms.");
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
+                << "Found " << nRunNumbersFull << " run number ranges for full sim with a total of " <<
+                m_histList[mapkey::sf].size() << " scale factor histograms.");
+
+   ATH_MSG_DEBUG("Tool succesfully initialized!");
+
+  return sc;
 }
 
 int 
 Root::TElectronEfficiencyCorrectionTool::calculate(const PATCore::ParticleDataType::DataType dataType,
-        const unsigned int runnumber,
-        const double cluster_eta,
-        const double et, /* in MeV */
-        std::vector<double>& result,
-        size_t& index_of_corr,
-        size_t& index_of_toys) const {
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "  entering function calculate");
-    /* 
-     * At this point , since this is after initialize,
-     * we know the size of the vector we want to construct.
-     * it is :
-     * Position::End + m_nSysMax + m_nToyMC
-     * The starting index of the sys is Position::End 
-     * The starting point of the toys is Position::End+m_nSysMax
-     */
-    result.resize(static_cast<size_t> (Position::End)+m_nSysMax+m_nToyMC);
-    //Set up the non-0 defaults
-    result[static_cast<size_t> (Position::SF)]=-999;
-    result[static_cast<size_t> (Position::Total)]=1;
-
-    /*
-     * Set the known indices
-     */
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "Set the indices"); 
-    if (m_nSysMax) {
-        index_of_corr=m_position_corrSys.at(0);
+                                                   const unsigned int runnumber,
+                                                   const double cluster_eta,
+                                                   const double et, /* in MeV */
+                                                   std::vector<double>& result,
+                                                   size_t& index_of_corr,
+                                                   size_t& index_of_toys) const {
+
+  /* 
+   * At this point, we know the size of the vector.
+   * Position::End + m_nSysMax + m_nToyMC
+   * The starting index of the sys is Position::End 
+   * The starting point of the toys is Position::End+m_nSysMax
+   */
+  ATH_MSG_DEBUG("Max number of systematics seen : " << m_nSysMax << " number of toys " <<m_nToyMC);
+  result.resize(static_cast<size_t> (Position::End)+m_nSysMax+m_nToyMC);
+  const size_t position_corrSys= static_cast<size_t> (Position::End);
+  const size_t position_uncorrToyMCSF=position_corrSys+m_nSysMax;
+  //Set up the non-0 defaults
+  result[static_cast<size_t> (Position::SF)]=-999;
+  result[static_cast<size_t> (Position::Total)]=1; 
+  if (m_nSysMax) {
+    index_of_corr=position_corrSys;
+  }
+  if (m_nToyMC) {
+    index_of_toys=position_uncorrToyMCSF;
+  } 
+  /* 
+   * Determine Simulation flavour and find the run period
+   */
+  const bool isFastSim=(dataType == PATCore::ParticleDataType::Fast) ? true: false;
+  int runnumberIndex = -1;
+  if (isFastSim) {
+    for (unsigned int i = 0; i < m_begRunNumberListFastSim.size(); ++i) {
+      if (m_begRunNumberListFastSim[i] <= runnumber && runnumber <= m_endRunNumberListFastSim[i]) {
+        runnumberIndex=i;
+        break;
+      }
+    }  
+  }else {
+    for (unsigned int i = 0; i < m_begRunNumberList.size(); ++i) {
+      if (m_begRunNumberList[i] <= runnumber && runnumber <= m_endRunNumberList[i]) {
+        runnumberIndex=i;
+        break;
+      }
+    }
+  }
+  if(runnumberIndex <0 ){  
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No valid run number period  found for the current run number: " 
+                  << runnumber <<" for simulation type: " << dataType); 
+    return 0;
+  }
+  /* What we have is a map :
+   * Key can be SF,Stat,Eigen,UnCorr
+   * Entry is a vector<TObArray> 
+   * Each vector<TObjArray>  has as many entries as supported Run periods.
+   * Each TObjjArray has 2D histos (could be standard, low-et, or forward electrons)
+   * The 2D Histo then has the number we want.
+   * What follows is the logic to get to this number.
+   */
+  const std::unordered_map<int, std::vector< TObjArray > >& currentmap = (isFastSim)? m_fastHistList : m_histList;
+  std::unordered_map<int, std::vector< TObjArray > >::const_iterator currentVector_itr = currentmap.find(mapkey::sf); 
+  /*
+   * See if we can find a  vector for key SF in the map 
+   * and then if we can get the  corresponding TObjArray 
+   * for the run period.
+   */
+  if (currentVector_itr == currentmap.end()) {
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No valid vector of sf ObjArray found for the current run number " 
+                  << runnumber<<" for simulation type: " << dataType);  
+    return 0;
+  } 
+  const std::vector<TObjArray>& currentVector=currentVector_itr->second;
+  if (currentVector.size()<=0 || runnumberIndex>= static_cast <int> (currentVector.size())) {
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No valid  sf ObjArray found for the current run number " 
+                  << runnumber<<" for simulation type: " << dataType);  
+    return 0;
+  }
+  /* 
+   * At this stage we have found the relevant TObjArray
+   * So we need to locate the right histogram.
+   */
+  const TObjArray& currentObjectArray = currentVector.at(runnumberIndex);  
+  const int entries = currentObjectArray.GetEntries();
+  /* 
+   * Now the logic of finding the histogram
+   * Some parts of the code can be perhaps improved ...
+   */
+  double xValue(et);
+  double yValue(cluster_eta);
+  int smallEt(0), etaCov(0), nSF(0);
+  bool invalid = false;
+  bool changedEt = false;
+  int index = -1;
+  TH2 *tmpHist(0);
+
+  for (int i = 0; i < entries ; ++i) {
+    invalid = false;
+
+    tmpHist = (TH2 *) (currentObjectArray.At(i));
+    //invalid if we are below minimum et 
+    if (et < tmpHist->GetXaxis()->GetXmin()) {
+      smallEt++;
+      invalid = true;
+    }
+    //invalid if we are above max eta 
+    if (std::abs(yValue) >= tmpHist->GetYaxis()->GetXmax()) {
+      etaCov++;
+      invalid=true;
+    }
+    // invalid if we are less than minimum eta (forward electrons)
+    if (std::abs(yValue) < tmpHist->GetYaxis()->GetXmin()) {
+      etaCov++;
+      invalid = true;
     }
-    if (m_nToyMC) {
-        index_of_toys=m_position_uncorrToyMCSF.at(0);
-    } 
     /* 
-     * Determine Simulation flavour
-     * And find the run period
+     * Invalid if above max et and is a low Et histogram.
+     * If not low Et histogram then change the xValue to the maximum
+     * availabe Et of ths histogram. As we assume that the  SF stays the same 
+     * for very high Et
      */
-    const bool isFastSim=(dataType == PATCore::ParticleDataType::Fast) ? true: false;
-    int runnumberIndex = -1;
-    if (isFastSim) {
-        for (unsigned int i = 0; i < m_begRunNumberListFastSim.size(); ++i) {
-            if (m_begRunNumberListFastSim[i] <= runnumber && runnumber <= m_endRunNumberListFastSim[i]) {
-                runnumberIndex=i;
-                break;
-            }
-        }  
-    }else {
-        for (unsigned int i = 0; i < m_begRunNumberList.size(); ++i) {
-            if (m_begRunNumberList[i] <= runnumber && runnumber <= m_endRunNumberList[i]) {
-                runnumberIndex=i;
-                break;
-            }
-        }
+    if (et > tmpHist->GetXaxis()->GetXmax()) {
+      if (TString(tmpHist->GetName()).Contains(LowPt_string)) {
+        invalid = true;
+      } else {
+        xValue = tmpHist->GetXaxis()->GetBinCenter(tmpHist->GetNbinsX());
+        changedEt = true;
+      }
     }
-    if(runnumberIndex <0 ){  
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No valid run number period  found for the current run number: " 
-                << runnumber <<" for simulation type: " << dataType); 
-        return 0;
-    }
-    /* What we have is a map key:std::vector<TObjArray> 
-     * Key: sf,stat,eigen, uncorr
-     * The vector<TObArray> has as many entries as supported run periods
-     * The TobjArray has 2D histos for  high, low et, or forward electrons
-     * The 2D Histo then has the number we want.
-     * What follows is the logic to get to this number
-     */
-    const std::map<int, std::vector< TObjArray > >& currentmap = (isFastSim)? m_fastHistList : m_histList;
-    std::map<int, std::vector< TObjArray > >::const_iterator currentVector_itr = currentmap.find(mapkey::sf); //find the vector
-    //See if we can find a SF vector in the map and the corresponding TobjArray for this run period
-    if (currentVector_itr == currentmap.end()) {
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No valid vector of sf ObjArray found for the current run number " 
-                << runnumber<<" for simulation type: " << dataType);  
-        return 0;
-    }
-    //Get a reference (synonym) to this vector 
-    const std::vector<TObjArray>& currentVector=currentVector_itr->second;
-    if (currentVector.size()<=0 || runnumberIndex>= static_cast <int> (currentVector.size())) {
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No valid  sf ObjArray found for the current run number " 
-                << runnumber<<" for simulation type: " << dataType);  
-        return 0;
-    }
-    /* 
-     * At this stage we have found the relevant TobjArray
-     * So we need to locate the right histogram
-     */
-    const TObjArray& currentObjectArray = currentVector.at(runnumberIndex);  
-    const int entries = currentObjectArray.GetEntries();
-    /* 
-     * Now the logic of finding the histogram
-     * Perhaps one the points of the code that
-     * could be improved given some "feedback"
+    /*
+     * Get the histogram index in the TObjArray
+     * Also mark how many times we found something
+     * as SF should be unique
      */
-    double xValue(et);
-    double yValue(cluster_eta);
-    int smallEt(0), etaCov(0), nSF(0);
-    bool block = false;
-    bool changed = false;
-    int index = -1;
-    TH2 *tmpHist(0);
-    for (int i = 0; i < entries ; ++i) {
-        block = kFALSE;
-        tmpHist = (TH2 *) (currentObjectArray.At(i));
-        //block if we are below minimum et 
-        if (et < tmpHist->GetXaxis()->GetXmin()) {
-            smallEt++;
-            block = kTRUE;
-        }
-        //block if we are above max eta 
-        if (std::abs(yValue) >= tmpHist->GetYaxis()->GetXmax()) {
-            etaCov++;
-            block = kTRUE;
-        }
-        // Block if we are less than minimum (fwd electrons)
-        if (std::abs(yValue) < tmpHist->GetYaxis()->GetXmin()) {
-            etaCov++;
-            block = kTRUE;
-        }
-        //Block if above max et and is the low Et histo
-        if (et > tmpHist->GetXaxis()->GetXmax()) {
-            if (TString(tmpHist->GetName()).Contains(LowPt_string)) {
-                block = kTRUE;
-            } else {
-                xValue = tmpHist->GetXaxis()->GetBinCenter(tmpHist->GetNbinsX());
-                changed = kTRUE;
-            }
-        }
-        if (!block) {
-            index = i;
-            if (!changed) {
-                nSF++;
-            }
-        }
-    }
-    //We are out of bounds 
-    if (smallEt == entries) {
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No correction factor provided for et " << xValue);  
-        return 0;
-    }
-    if (etaCov == entries) {
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No correction factor provided for eta " << yValue);  
-        return 0;
-    }
-    if (nSF > 1) {
-        ATH_MSG_WARNING("More than 1 SF found for eta=" << yValue << " , et = " 
-                << et << " , run number = " << runnumber << ". Please check your input files!");
-    }
-    //Now we have the index of the histogram for this region in the TObjectarray 
-    TH2* currentHist(0);
-    if (index >= 0) {
-        currentHist = static_cast<TH2*> (currentObjectArray.At(index));
-    }
-    else {
-        ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ") "<<
-                "No correction factor provided because of an invalid index" << yValue);
-        return 0;
-    }
-    // If SF is only given in Abs(eta) convert eta input to std::abs()
-    constexpr double epsilon = 1e-6;
-    if (currentHist->GetYaxis()->GetBinLowEdge(1) >= 0 - epsilon) {
-        if (yValue < 0) {
-            ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") "
+    if (!invalid) {
+      index = i;
+      if (!changedEt) {
+        nSF++;
+      }
+    }
+  }
+  if (smallEt == entries) {
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No correction factor provided for et " << xValue);  
+    return 0;
+  }
+  if (etaCov == entries) {
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No correction factor provided for eta " << yValue);  
+    return 0;
+  }
+  if (nSF>1) {
+    ATH_MSG_WARNING("More than 1 SF found for eta=" << yValue << " , et = " 
+                    << et << " , run number = " << runnumber << ". Please check your input files!");
+  }
+  /*
+   * Now we have the index of the histogram 
+   * for this region in the TObjectArray
+   */
+  TH2* currentHist(0);
+  if (index >= 0) {
+    currentHist = static_cast<TH2*> (currentObjectArray.At(index));
+  }
+  else {
+    ATH_MSG_DEBUG("(file: " << __FILE__ << ", line: " << __LINE__ << ")\n"<<
+                  "No correction factor provided because of an invalid index" << yValue);
+    return 0;
+  }
+  /*
+   * If SF is only given in Abs(eta) convert eta input to std::abs()
+   */
+  constexpr double epsilon = 1e-6;
+  if (currentHist->GetYaxis()->GetBinLowEdge(1) >= 0 - epsilon) {
+    if (yValue < -1) {
+      ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
                     << "Scale factor only measured in Abs(eta) changing eta from " 
                     << yValue << " to " << std::abs(yValue));
-        }
-        yValue = std::abs(yValue);
-    }
-    const int globalBinNumber = currentHist->FindFixBin(xValue, yValue);
-    const double scaleFactor = currentHist->GetBinContent(globalBinNumber);
-    const double scaleFactorErr = currentHist->GetBinError(globalBinNumber);
-    //
-    // Write the retrieved values into the return object
-    result[static_cast<size_t> (Position::SF)]=scaleFactor;
-    result[static_cast<size_t> (Position::Total)]=scaleFactorErr;
-    //DONE WITH THE SF
-    //
-    //DO the stat error using the available info from above i.e index etc
-    double statErr = -999;
-    currentVector_itr = currentmap.find(mapkey::stat); //find the vector
-    if (currentVector_itr != currentmap.end()) {
-        //itr at the location of the vector, .second get the vector, at(runnumberIndex is the TObjectArray 
-        // for the period , finaly get the hist at index (from above).
-        const TH1 *stat = static_cast<TH1*>(currentVector_itr->second.at(runnumberIndex).At(index));
-        statErr = stat->GetBinContent(globalBinNumber);
-        result[static_cast<size_t> (Position::Stat)]=statErr;
-    }
-    /*
-     * Check if the correlated reduced
-     * due to the detail level
-     */ 
-    std::array<int,detailLevelEnd> sLevel{};    
-    currentVector_itr = currentmap.find(mapkey::eig); //find the vector
-    if (currentVector_itr != currentmap.end()) {
-        //Check on the ObjArray
-        if (currentVector_itr->second.at(runnumberIndex).GetEntriesFast()> 0) {
-            //itr at the location of the vector, .second get the vector, at(runnumberIndex is the TObjectArray 
-            // for the period , finaly get the hist at index (from above).
-            const TH1D *eig = static_cast<const TH1D*>(currentVector_itr->second.at(runnumberIndex).At(index)); 
-            int nSys{};
-            calcDetailLevels(eig, sLevel,nSys);
-            nSys-=sLevel[m_detailLevel];
-            result[static_cast<size_t> (Position::NSys)]=nSys;
-        }
-    }
-    /*The issue now is that the previous setup is becoming cumbersome for the 10 systematic
-     * So we keep them in a vector of vector of TObjectArray
-     * The first vector index being the runnumber
-     * The second the systematic
-     * And the obj array for high low etc
-     * We need to see if we can do something better here ...
-     */
-    const std::vector< std::vector< TObjArray > > &sysList = (isFastSim) ? m_fastSysList : m_sysList;
-    std::vector<double> corrSys; 
-    corrSys.reserve(10); 
-    corrSys.clear();
-    if (sysList.size() > static_cast<unsigned int> (index)) {
-        if (sysList.at(index).size() > static_cast<unsigned int> (runnumberIndex)) {
-            const int sys_entries = sysList.at(index).at( runnumberIndex).GetEntries();
-            for (int sys = 0; sys < sys_entries; ++sys) {
-                tmpHist = (TH2 *) sysList.at(index).at(runnumberIndex).At(sys_entries - 1 - sys);
-                corrSys.push_back(tmpHist->GetBinContent(globalBinNumber));
-                result[m_position_corrSys[(sys_entries - 1 - sys)]] =corrSys[sys];
-            }
-            if (m_position_corrSys.size() > 0 && sys_entries<=1) {
-                if (result[m_position_corrSys[0]] == 0) {
-                    result[m_position_corrSys[0]]=scaleFactorErr;
-                }
-            }
-        }
-    }
-    //Do the uncorr error using the available info from above i.e index etc
-    //Get the statErr from above
-    double val = statErr;
-    currentVector_itr = currentmap.find(mapkey::uncorr); //find the vector
-    if (currentVector_itr != currentmap.end()) {
-        //Check on the ObjArray
-        if (currentVector_itr->second.at(runnumberIndex).GetEntriesFast()>0) {
-            TH1 *uncorr = static_cast<TH1*>(currentVector_itr->second.at(runnumberIndex).At(index));
-            const double valAdd = uncorr->GetBinContent(globalBinNumber);
-            val = sqrt(val * val + valAdd * valAdd);
-            for (int i = 0; i < sLevel[m_detailLevel]; ++i) {
-                const double valAdd1 = corrSys.at(corrSys.size() - 1 - i);
-                val = sqrt(val * val + valAdd1 * valAdd1);
-            }
-        }
-    }
-    if (val == -999) {
-        val = 0;
-    }
-    result[static_cast<size_t> (Position::UnCorr)]=val;
-    /* 
-     * Do the toys
-     */
-    if (m_doToyMC || m_doCombToyMC) {
-        const std::vector<std::vector<TObjArray > >& toyMCList = ((isFastSim) ? m_uncorrToyMCSystFast : m_uncorrToyMCSystFull);
-        if (toyMCList.size() > (unsigned int) runnumberIndex) {
-            for (int toy = 0; toy < m_nToyMC; toy++) {
-                if (toyMCList.at(runnumberIndex).at(toy).GetLast() >= index) {
-                    result[m_position_uncorrToyMCSF.at(toy)]=
-                        ((TH2 *) toyMCList.at(runnumberIndex).at(toy).At(index))->GetBinContent(globalBinNumber);
-                }
-            }
-        }
-    }
-    result[static_cast<size_t> (Position::GlobalBinNumber)]=globalBinNumber;
-    return 1;
-}
-
-/*
- *Calculate the detail levels for a given eigenvector histogram
- * Since the syst are in practice eigenvalues 
- * the smaller ones could be disgarded added to uncorrelated
- */
-void
-Root::TElectronEfficiencyCorrectionTool::calcDetailLevels(
-        const TH1D *eig, 
-        std::array<int,detailLevelEnd>& sLevel,
-        int& nSys) const {
-
-    sLevel[Root::TElectronEfficiencyCorrectionTool::simple] = 0;
-    sLevel[Root::TElectronEfficiencyCorrectionTool::medium] = 0;
-    sLevel[Root::TElectronEfficiencyCorrectionTool::detailed] = 0;
-    nSys = eig->GetNbinsX() - 1;
-    double sign = 0;
-    // Calculate detail level
-    for (int i = nSys + 1; i >= 2; i--) {
-        sign += eig->GetBinContent(i);
-        if (sign > 0.8 && sLevel[Root::TElectronEfficiencyCorrectionTool::simple] == 0) {
-            sLevel[Root::TElectronEfficiencyCorrectionTool::simple] = i - 2;
-        }
-        if (sign > 0.95 && sLevel[Root::TElectronEfficiencyCorrectionTool::medium] == 0) {
-            sLevel[Root::TElectronEfficiencyCorrectionTool::medium] = i - 2;
-        }
     }
+    yValue = std::abs(yValue);
+  }
+  const int globalBinNumber = currentHist->FindFixBin(xValue, yValue);
+  const double scaleFactor = currentHist->GetBinContent(globalBinNumber);
+  const double scaleFactorErr = currentHist->GetBinError(globalBinNumber);
+  /* 
+   * Write the retrieved values to the output
+   * */
+  result[static_cast<size_t> (Position::SF)]=scaleFactor;
+  result[static_cast<size_t> (Position::Total)]=scaleFactorErr;
+  /*
+   * Do the stat error using the available info from the above (SF)
+   */
+  double statErr = -999;
+  currentVector_itr = currentmap.find(mapkey::stat); 
+  if (currentVector_itr != currentmap.end()) {
+    const TH1 *stat = static_cast<TH1*>(currentVector_itr->second.at(runnumberIndex).At(index));
+    statErr = stat->GetBinContent(globalBinNumber);
+    result[static_cast<size_t> (Position::Stat)]=statErr;
+  }
+  /*
+   * Do the Uncorr  uncertainty
+   */
+  double val = statErr;
+  currentVector_itr = currentmap.find(mapkey::uncorr); 
+  if (currentVector_itr != currentmap.end()) {
+    if (currentVector_itr->second.at(runnumberIndex).GetEntriesFast()>0) {
+     TH1 *uncorr = static_cast<TH1*>(currentVector_itr->second.at(runnumberIndex).At(index));
+      const double valAdd = uncorr->GetBinContent(globalBinNumber);
+      val = sqrt(val * val + valAdd * valAdd);
+    }
+  }
+  result[static_cast<size_t> (Position::UnCorr)]=val; 
+  /* 
+   * The previous setup is becoming cumbersome 
+   * for the N~16 systematic variations.
+   * So we keep them in a vector of vector of TObjectArray
+   * The first vector index being the runnumber
+   * The second the systematic
+   * And them the TObjArray for high low etc.
+   * We invert the order in the output
+   */
+  const std::vector< std::vector< TObjArray > > &sysList = (isFastSim) ? m_fastSysList : m_sysList;
+  std::vector<double> corrSys; 
+  corrSys.reserve(16); 
+  corrSys.clear();
+  if (sysList.size() > static_cast<unsigned int> (index)) {
+    if (sysList.at(index).size() > static_cast<unsigned int> (runnumberIndex)) {
+      const int sys_entries = sysList.at(index).at( runnumberIndex).GetEntries();
+      for (int sys = 0; sys < sys_entries; ++sys) {
+        tmpHist = (TH2 *) sysList.at(index).at(runnumberIndex).At(sys_entries - 1 - sys);
+        corrSys.push_back(tmpHist->GetBinContent(globalBinNumber));
+        result[position_corrSys + sys_entries - 1 - sys] =corrSys[sys];
+        }
+      if (m_nSysMax > 0 && sys_entries<=1) {
+        if (result[position_corrSys] == 0) {
+            result[position_corrSys]=scaleFactorErr;
+        }
+      }
+    }
+  }
+  /* 
+   * Do the toys
+   */
+  if (m_doToyMC || m_doCombToyMC) {
+    const std::vector<std::vector<TObjArray > >& toyMCList = ((isFastSim) ? m_uncorrToyMCSystFast : m_uncorrToyMCSystFull);
+    if (toyMCList.size() > (unsigned int) runnumberIndex) {
+      for (int toy = 0; toy < m_nToyMC; toy++) {
+        if (toyMCList.at(runnumberIndex).at(toy).GetLast() >= index) {
+          result[position_uncorrToyMCSF+toy]=
+            ((TH2 *) toyMCList.at(runnumberIndex).at(toy).At(index))->GetBinContent(globalBinNumber);
+        }
+      }
+    }
+  }
+  result[static_cast<size_t> (Position::GlobalBinNumber)]=globalBinNumber;
+  return 1;
 }
 /*
  * Build the toyMC tables from inputs
  * Ownership should be tranfered to the map of the tables
  * and the proper delete happens in the dtor
  */
-std::vector<TH2D *>
-Root::TElectronEfficiencyCorrectionTool::buildSingleToyMC(
-        const TH2D *sf, 
-        const TH2D *stat, 
-        const TH2D *uncorr, 
-        const TObjArray& corr,
-        const std::array<int,detailLevelEnd> sLevel,
-        int& randomCounter) {
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")! " 
-            << "entering function buildSingleToyMC");
-    std::vector<TH2D*> tmpHists;
-    int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
-    for (int toy = 0; toy < m_nToyMC; toy++) {
-        tmpHists.push_back((TH2D *) corr.At(0)->Clone());
+std::vector<TH2 *>
+Root::TElectronEfficiencyCorrectionTool::buildSingleToyMC(const TH2 *sf, 
+                                                          const TH2 *stat, 
+                                                          const TH2 *uncorr, 
+                                                          const TObjArray& corr,
+                                                          int& randomCounter) {
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")! " 
+                << "Entering function buildSingleToyMC");
+  std::vector<TH2*> tmpHists;
+  int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
+  for (int toy = 0; toy < m_nToyMC; toy++) {
+    tmpHists.push_back((TH2 *) corr.At(0)->Clone());
+  }
+  // Loop over all bins
+  for (int bin = 0; bin < nBins; bin++) {
+    double val = stat->GetBinContent(bin);
+
+    // Add uncorrelated systematics
+    if (uncorr != 0) {
+      double valAdd = uncorr->GetBinContent(bin);
+      val = sqrt(val * val + valAdd * valAdd);
     }
-    // Loop over all bins
-    for (int bin = 0; bin < nBins; bin++) {
-        double val = stat->GetBinContent(bin);
-
-        // Add uncorrelated systematics
-        if (uncorr != 0) {
-            double valAdd = uncorr->GetBinContent(bin);
-            val = sqrt(val * val + valAdd * valAdd);
-        }
-        // Add smaller correlated systematics as uncorrelated
-        for (int i = 0; i < sLevel[m_detailLevel]; ++i) {
-            if (corr.At(i) != 0) {
-                double valAdd = ((TH2D *) corr.At(i))->GetBinContent(bin);
-                val = sqrt(val * val + valAdd * valAdd);
-            }
-        }
-        for (int toy = 0; toy < m_nToyMC; toy++) {
-            tmpHists.at(toy)->SetBinContent(bin, (val * m_Rndm.Gaus(0, 1)) + sf->GetBinContent(bin));
-            randomCounter++;
-            tmpHists.at(toy)->SetDirectory(0);
-        }
+    for (int toy = 0; toy < m_nToyMC; toy++) {
+      tmpHists.at(toy)->SetBinContent(bin, (val * m_Rndm.Gaus(0, 1)) + sf->GetBinContent(bin));
+      randomCounter++;
+      tmpHists.at(toy)->SetDirectory(0);
     }
-    return tmpHists;
+  }
+  return tmpHists;
 }
 /*
  * Build the combined toyMC tables from inputs
  * Ownership should be tranfered to the map of the tables
  * and the proper delete happens in the dtor
  */
-TH2D*
-Root::TElectronEfficiencyCorrectionTool::buildSingleCombToyMC(
-        const TH2D *sf, 
-        const TH2D *stat, 
-        const TH2D *uncorr, 
-        const TObjArray& corr,
-        const std::array<int,detailLevelEnd> sLevel,
-        const int nSys,
-        int& randomCounter){
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "entering function buildSingleCombToyMC");
-
-    TH2D *tmpHist;
-    const int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
-    tmpHist = (TH2D *) corr.At(0)->Clone();
-    // Create random numbers for the corr. uncertainties
-    std::vector<double> rnd (nSys,0);
+TH2*
+Root::TElectronEfficiencyCorrectionTool::buildSingleCombToyMC(const TH2 *sf, 
+                                                              const TH2 *stat, 
+                                                              const TH2 *uncorr, 
+                                                              const TObjArray& corr,
+                                                              const int nSys,
+                                                              int& randomCounter){
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "Entering function buildSingleCombToyMC");
+
+  TH2 *tmpHist;
+  const int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
+  tmpHist = (TH2 *) corr.At(0)->Clone();
+  // Create random numbers for the corr. uncertainties
+  std::vector<double> rnd (nSys,0);
+  for (int s = 0; s < nSys; ++s) {
+    rnd[s] = m_Rndm.Gaus(0, 1);
+    randomCounter++;
+  }
+  // Loop over all bins
+  for (int bin = 0; bin < nBins; ++bin) {
+    double val = stat->GetBinContent(bin);
+
+    // Add uncorrelated systematics
+    if (uncorr != 0) {
+      double valAdd = uncorr->GetBinContent(bin);
+      val = sqrt(val * val + valAdd * valAdd);
+    }
+    val = val * m_Rndm.Gaus(0,1);
+    randomCounter++;
+    // Add larger correlated systematics
     for (int s = 0; s < nSys; ++s) {
-        rnd[s] = m_Rndm.Gaus(0, 1);
-        randomCounter++;
-    }
-    // Loop over all bins
-    for (int bin = 0; bin < nBins; ++bin) {
-        double val = stat->GetBinContent(bin);
-
-        // Add uncorrelated systematics
-        if (uncorr != 0) {
-            double valAdd = uncorr->GetBinContent(bin);
-            val = sqrt(val * val + valAdd * valAdd);
-        }
-        // Add smaller correlated systematics as uncorrelated
-        for (int s = 0; s < sLevel[m_detailLevel]; ++s) {
-            if (corr.At(s) != 0) {
-                double valAdd = ((TH2D *) corr.At(s))->GetBinContent(bin);
-                val = sqrt(val * val + valAdd * valAdd);
-            }
-        }
-        val = val * m_Rndm.Gaus(0,1);
-        randomCounter++;
-        // Add larger correlated systematics
-        for (int s = sLevel[m_detailLevel]; s < nSys; ++s) {
-            if (corr.At(s) != 0) {
-                val += ((TH2D *) corr.At(s))->GetBinContent(bin) * rnd[s];
-            }
-        }
-        tmpHist->SetBinContent(bin, val + sf->GetBinContent(bin));
-    }
-    tmpHist->SetDirectory(0);
-    return tmpHist;
+      if (corr.At(s) != 0) {
+        val += ((TH2 *) corr.At(s))->GetBinContent(bin) * rnd[s];
+      }
+    }
+    tmpHist->SetBinContent(bin, val + sf->GetBinContent(bin));
+  }
+  tmpHist->SetDirectory(0);
+  return tmpHist;
 }
 /*
  * Build the toyMC tables from inputs
  */
 std::vector<TObjArray>
 Root::TElectronEfficiencyCorrectionTool::buildToyMCTable(const TObjArray& sf, 
-        const TObjArray& eig, 
-        const TObjArray& stat,
-        const TObjArray& uncorr, 
-        const std::vector<TObjArray>& corr) {
-
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "entering function buildToyMCTable");
-    
-    std::array<int,detailLevelEnd> sLevel{}; 
-    int nSys{};
-    int randomCounter(0);
-    std::vector<TObjArray> tmpVec;
-    const int stat_entries = stat.GetEntries();
-
-    if (m_doCombToyMC) {
-        for (int toyMC = 0; toyMC < m_nToyMC; toyMC++) {
-            TObjArray tmpArray;
-            for (int i = 0; i < stat_entries; ++i) {
-                if (eig.GetEntriesFast()>0 && uncorr.GetEntriesFast()>0) {
-                    std::array<int,detailLevelEnd> sLevel{};    
-                    int nSys{};
-                    calcDetailLevels((TH1D *) eig.At(i), sLevel,nSys);
-                    tmpArray.Add(buildSingleCombToyMC((TH2D *) sf.At(i), 
-                                (TH2D *) stat.At(i), 
-                                (TH2D *) uncorr.At(i), 
-                                corr.at(i),
-                                sLevel,
-                                nSys,
-                                randomCounter));
-                }else {
-                    tmpArray.Add(buildSingleCombToyMC((TH2D *) sf.At(i), 
-                                (TH2D *) stat.At(i), 
-                                0, 
-                                corr.at(i) ,
-                                sLevel,
-                                nSys,
-                                randomCounter));
-                }
-            }
-            tmpVec.push_back(tmpArray);
-        }
-    }else {
-        std::vector< std::vector<TH2D*> > tmpVec2 ;
-        for (int i = 0; i < stat_entries; ++i) {
-            calcDetailLevels((TH1D *) eig.At(i),sLevel,nSys);
-            tmpVec2.push_back(buildSingleToyMC((TH2D *) sf.At(i), 
-                        (TH2D *) stat.At(i), 
-                        (TH2D *) uncorr.At(i),
-                        corr.at(i),
-                        sLevel,
-                        randomCounter));
-        }
-        for (int toy = 0; toy < m_nToyMC; toy++) {
-            TObjArray tmpArray;
-            for (unsigned int i = 0; i < tmpVec2.size(); ++i) {
-                tmpArray.Add(tmpVec2.at(i).at(toy));
-            }
-            tmpVec.push_back(tmpArray);
-        }
+                                                         const TObjArray& eig, 
+                                                         const TObjArray& stat,
+                                                         const TObjArray& uncorr, 
+                                                         const std::vector<TObjArray>& corr) {
+
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "Entering function buildToyMCTable");
+
+  int nSys{};
+  int randomCounter(0);
+  std::vector<TObjArray> tmpVec;
+  const int stat_entries = stat.GetEntries();
+  if (m_doCombToyMC) {
+    for (int toyMC = 0; toyMC < m_nToyMC; toyMC++) {
+      TObjArray tmpArray;
+      for (int i = 0; i < stat_entries; ++i) {
+        if (eig.GetEntriesFast()>0 && uncorr.GetEntriesFast()>0) { 
+          nSys = ((TH1*)eig.At(i))->GetNbinsX()-1;  
+          tmpArray.Add(buildSingleCombToyMC((TH2 *) sf.At(i), 
+                                            (TH2 *) stat.At(i), 
+                                            (TH2 *) uncorr.At(i), 
+                                            corr.at(i),
+                                            nSys,
+                                            randomCounter));
+        }else {
+          tmpArray.Add(buildSingleCombToyMC((TH2*) sf.At(i), 
+                                            (TH2*) stat.At(i), 
+                                            0, 
+                                            corr.at(i) ,
+                                            nSys,
+                                            randomCounter));
+        }
+      }
+      tmpVec.push_back(tmpArray);
+    }
+  }else {
+    std::vector< std::vector<TH2*> > tmpVec2 ;
+    for (int i = 0; i < stat_entries; ++i) {
+      nSys = ((TH1*)eig.At(i))->GetNbinsX()-1;
+      tmpVec2.push_back(buildSingleToyMC((TH2*) sf.At(i), 
+                                         (TH2*) stat.At(i), 
+                                         (TH2*) uncorr.At(i),
+                                         corr.at(i),
+                                         randomCounter));
     }
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "m_Rndm->Uniform(0, 1) after throwing " << randomCounter
-            << " random numbers: " << m_Rndm.Uniform(0,1));
-
-    return tmpVec;
+    for (int toy = 0; toy < m_nToyMC; toy++) {
+      TObjArray tmpArray;
+      for (unsigned int i = 0; i < tmpVec2.size(); ++i) {
+        tmpArray.Add(tmpVec2.at(i).at(toy));
+      }
+      tmpVec.push_back(tmpArray);
+    }
+  }
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "m_Rndm->Uniform(0, 1) after throwing " << randomCounter
+                << " random numbers: " << m_Rndm.Uniform(0,1));
+
+  return tmpVec;
 }
-// =============================================================================
-// Helper function to retrieve number of uncorrelated bins
-// =============================================================================
+/*
+ * Helper function to retrieve number of uncorrelated bins
+ */
 int
 Root::TElectronEfficiencyCorrectionTool::getNbins(std::map<float, std::vector<float> > &pt_eta1) const {
-    //Get sf histograms 
-    const std::vector<TObjArray >& tmpVec = m_histList.at(mapkey::sf);
-    int nbinsTotal = 0;
-    pt_eta1.clear();
-    std::vector<float>eta1;
-    eta1.clear();
-
-    //Loop over the different run ranges (one TObjeArray for each)
-    for (unsigned int ikey = 0; ikey < tmpVec.size(); ++ikey) {
-        //Loop over the histograms for a given run numbers
-        for (int entries = 0; entries < (tmpVec.at(ikey)).GetEntries(); ++entries) {
-            eta1.clear();
-            //Get number of bins
-            TH2D *h_tmp = ((TH2D * ) (tmpVec.at(ikey)).At(entries));
-            int nbinsX = h_tmp->GetNbinsX();
-            int nbinsY = h_tmp->GetNbinsY();
-            //fill in the eta pushing back
-            for (int biny = 1; biny <= nbinsY; ++biny) {
-                eta1.push_back(h_tmp->GetYaxis()->GetBinLowEdge(biny));
-            }
-            //associate each pt (bin) with the corresponding/available eta ones
-            for (int binx = 1; binx <=nbinsX; ++binx) {
-                pt_eta1[h_tmp->GetXaxis()->GetBinLowEdge(binx)] = eta1;
-            }
-        }
-    }
-    for (auto &i : pt_eta1) {
-        nbinsTotal += i.second.size();
-    }
-    return nbinsTotal;
+  //Get sf histograms 
+  const std::vector<TObjArray >& tmpVec = m_histList.at(mapkey::sf);
+  int nbinsTotal = 0;
+  pt_eta1.clear();
+  std::vector<float>eta1;
+  eta1.clear();
+
+  //Loop over the different Run range (one TObjeArray for each)
+  for (unsigned int ikey = 0; ikey < tmpVec.size(); ++ikey) {
+    //Loop over the histograms for a given run numbers
+    for (int entries = 0; entries < (tmpVec.at(ikey)).GetEntries(); ++entries) {
+      eta1.clear();
+      //Get number of bins
+      TH2 *h_tmp = ((TH2 * ) (tmpVec.at(ikey)).At(entries));
+      int nbinsX = h_tmp->GetNbinsX();
+      int nbinsY = h_tmp->GetNbinsY();
+      //fill in the eta pushing back
+      for (int biny = 1; biny <= nbinsY; ++biny) {
+        eta1.push_back(h_tmp->GetYaxis()->GetBinLowEdge(biny));
+      }
+      //associate each pt (bin) with the corresponding/available eta ones
+      for (int binx = 1; binx <=nbinsX; ++binx) {
+        pt_eta1[h_tmp->GetXaxis()->GetBinLowEdge(binx)] = eta1;
+      }
+    }
+  }
+  for (auto &i : pt_eta1) {
+    nbinsTotal += i.second.size();
+  }
+  return nbinsTotal;
 }
-// =============================================================================
-// Get the input histograms from the input files
-// =============================================================================
+/*
+ * Get the  histograms from the input files
+ */
 int Root::TElectronEfficiencyCorrectionTool::getHistograms() {
 
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "entering function getHistograms");
-    // Cache the current directory in the root file
-    TDirectory *origDir = gDirectory;
-    // -------------------------------------------------------
-    // Get the name of the first input ROOT file and
-    // interpret from that what we have:
-    // efficiency vs. efficiencySF; offline vs. trigger; medium, loose,...
-    // -------------------------------------------------------
-    if (!m_corrFileNameList.empty()) {
-        TString firstFileNameAndPath = m_corrFileNameList[0].c_str();
-        std::unique_ptr<TObjArray> myStringList(firstFileNameAndPath.Tokenize("/"));
-        int lastIdx = myStringList->GetLast();
-        TString fileName = ((TObjString *) myStringList->At(lastIdx))->GetString();
-        std::unique_ptr<TObjArray> myFileNameTokensList(fileName.Tokenize("."));
-
-        if (myFileNameTokensList->GetLast() < 3) {
-            ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                    << "input file name has wrong format!");
-            return 0;
-        }
-
-    }
-    // -------------------------------------------------------
-    // Get all ROOT files and histograms
-    // -------------------------------------------------------
-    for (unsigned int i = 0; i < m_corrFileNameList.size(); ++i) {
-        // Load the ROOT file
-        const std::unique_ptr<char> fname (gSystem->ExpandPathName(m_corrFileNameList[i].c_str()));
-        std::unique_ptr<TFile> rootFile = CxxUtils::make_unique<TFile> (fname.get(), "READ");
-        if (!rootFile) {
-            ATH_MSG_ERROR(
-                    " (file: " << __FILE__ << ", line: " << __LINE__ << ") " << "No ROOT file found here: " <<
-                    m_corrFileNameList[i]);
-            return 0;
-        }
-        // Loop over all directories inside the root file (correspond to the run number ranges
-        TIter nextdir(rootFile->GetListOfKeys());
-        TKey *dir;
-        TObject *obj;
-        while ((dir = (TKey *) nextdir())) {
-            obj = dir->ReadObj();
-            if (obj->IsA()->InheritsFrom("TDirectory")) {
-                // splits string by delimiter --> e.g RunNumber1_RunNumber2
-                TObjArray dirNameArray = *(TString(obj->GetName()).Tokenize("_"));
-                //// returns index of last string --> if one, the directory name does not contain any run numbers
-                int lastIdx = dirNameArray.GetLast();
-                if (lastIdx != 1) {
-                    ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                            << "The folder name seems to have the wrong format! Directory name:"
-                            << obj->GetName());
-                    return 0;
-                }
-                rootFile->cd(obj->GetName());
-                if (0 == this->setupHistogramsInFolder(dirNameArray, lastIdx)) {
-                    ATH_MSG_ERROR(
-                            " (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                            << "unable to setup the histograms in directory " << dir->GetName()
-                            << "in file " << m_corrFileNameList[i]);
-                    return 0;
-                }
-            }else {
-                ATH_MSG_ERROR(
-                        " (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                        << "Wrong file content! Expected only Directories " <<
-                        gDirectory->cd());
-                return 0;
-            }
-            // Return to the original ROOT directory
-            gDirectory = origDir;
-        } // End: directory loop
-    } // End: file loop
-    return 1;
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "Entering function getHistograms");
+  // Cache the current directory in the root file
+  TDirectory *origDir = gDirectory;
+  /*
+   * Get the name of the first input ROOT file and
+   * interpret from that what we have:
+   * efficiency vs. efficiencySF; offline vs. trigger; medium, loose,...
+   */
+  if (!m_corrFileNameList.empty()) {
+    TString firstFileNameAndPath = m_corrFileNameList[0].c_str();
+    std::unique_ptr<TObjArray> myStringList(firstFileNameAndPath.Tokenize("/"));
+    int lastIdx = myStringList->GetLast();
+    TString fileName = ((TObjString *) myStringList->At(lastIdx))->GetString();
+    std::unique_ptr<TObjArray> myFileNameTokensList(fileName.Tokenize("."));
+
+    if (myFileNameTokensList->GetLast() < 3) {
+      ATH_MSG_ERROR("input file name has wrong format!");
+      return 0;
+    }
+  }
+  /*
+   * Get all ROOT files and histograms
+   */
+
+  for (unsigned int i = 0; i < m_corrFileNameList.size(); ++i) {
+    // Load the ROOT file
+    const std::unique_ptr<char> fname (gSystem->ExpandPathName(m_corrFileNameList[i].c_str()));
+    std::unique_ptr<TFile> rootFile( TFile::Open(fname.get(), "READ") );
+    if (!rootFile) {
+      ATH_MSG_ERROR( "No ROOT file found here: " <<m_corrFileNameList[i]);
+      return 0;
+    }
+    // Loop over all directories inside the root file (correspond to the run number ranges
+    TIter nextdir(rootFile->GetListOfKeys());
+    TKey *dir;
+    TObject *obj;
+    while ((dir = (TKey *) nextdir())) {
+      obj = dir->ReadObj();
+      if (obj->IsA()->InheritsFrom("TDirectory")) {
+        // splits string by delimiter --> e.g RunNumber1_RunNumber2
+        TObjArray dirNameArray = *(TString(obj->GetName()).Tokenize("_"));
+        // returns index of last string --> if one, the directory name does not contain any run numbers
+        int lastIdx = dirNameArray.GetLast();
+        if (lastIdx != 1) {
+          ATH_MSG_ERROR("The folder name seems to have the wrong format! Directory name:"<< obj->GetName());
+          return 0;
+        }
+        rootFile->cd(obj->GetName());
+        if (0 == this->setupHistogramsInFolder(dirNameArray, lastIdx)) {
+          ATH_MSG_ERROR("Unable to setup the histograms in directory " << dir->GetName()
+                        << "in file " << m_corrFileNameList[i]);
+          return 0;
+        }
+      }else {
+        ATH_MSG_ERROR( "Wrong file content! Expected only Directories " <<
+                      gDirectory->cd());
+        return 0;
+      }
+      // Return to the original ROOT directory
+      gDirectory = origDir;
+    } // End: directory loop
+  } // End: file loop
+  return 1;
 }
-// =============================================================================
-// Get the input histograms from a given folder/run number range
-// =============================================================================
+/*
+ * Get the input histograms from a given folder/run number range
+ */
 int Root::TElectronEfficiencyCorrectionTool::setupHistogramsInFolder(const TObjArray& dirNameArray, int lastIdx) {
 
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "entering funtion setupHistogramsInFolder");
-
-    int runNumBegin(-1);
-    TString myBegRunNumString = ((TObjString *) dirNameArray.At(lastIdx - 1))->GetString();
-    if (myBegRunNumString.IsDigit()) {
-        runNumBegin = myBegRunNumString.Atoi();
-    }
-    int runNumEnd(-1);
-    TString myEndRunNumString = ((TObjString *) dirNameArray.At(lastIdx))->GetString();
-    if (myEndRunNumString.IsDigit()) {
-        runNumEnd = myEndRunNumString.Atoi();
-    }
-    if (runNumBegin < 0 || runNumEnd < 0 || runNumEnd < runNumBegin) {
-        ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                << "Could NOT interpret the run number range: " << runNumBegin
-                << " - " << runNumEnd);
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "Entering funtion setupHistogramsInFolder");
+
+  int runNumBegin(-1);
+  TString myBegRunNumString = ( (TObjString*) dirNameArray.At(lastIdx - 1) )->GetString();
+  if (myBegRunNumString.IsDigit()) {
+    runNumBegin = myBegRunNumString.Atoi();
+  }
+  int runNumEnd(-1);
+  TString myEndRunNumString = ( (TObjString *) dirNameArray.At(lastIdx) )->GetString();
+  if (myEndRunNumString.IsDigit()) {
+    runNumEnd = myEndRunNumString.Atoi();
+  }
+  if (runNumBegin < 0 || runNumEnd < 0 || runNumEnd < runNumBegin) {
+    ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                  << "Could NOT interpret the run number range: " << runNumBegin
+                  << " - " << runNumEnd);
+    return 0;
+  }
+  /// setup pairs of obj arrays and keys --> e.g. "sf", new Array to take all SF Histos
+  std::unordered_map<int, TObjArray> objsFull;
+  std::unordered_map<int, TObjArray > objsFast;
+  for (unsigned int ikey = 0; ikey < s_keys.size(); ++ikey) {
+    TObjArray dummyFull;
+    objsFull.insert(std::make_pair(s_keys.at(ikey),dummyFull));
+    TObjArray dummyFast;
+    objsFast.insert(std::make_pair(s_keys.at(ikey),dummyFast));
+  }  
+  TObjArray dummyFull;    
+  objsFull.insert(std::make_pair(mapkey::sys, dummyFull));
+  TObjArray dummyFast;
+  objsFast.insert(std::make_pair(mapkey::sys, dummyFast));
+
+  std::vector<TObjArray > sysObjsFull;
+  std::vector<TObjArray > sysObjsFast;
+
+  TIter nextkey(gDirectory->GetListOfKeys());
+  TKey *key;
+  TObject *obj(0);
+  int seenSystematics= 0;
+
+  //Loop of the keys 
+  while ((key = (TKey *) nextkey())) {
+    obj = key->ReadObj();
+    if (obj->IsA()->InheritsFrom("TH1")) {
+      // The histogram containing the scale factors need to end with _sf and need to contain either the string "FullSim"
+      // or "AtlFast2"!
+      if (TString(obj->GetName()).Contains("FullSim")) {
+        setupTempMapsHelper( obj,objsFull,sysObjsFull, seenSystematics); 
+      }
+      else if (TString(obj->GetName()).Contains("AtlFast2")) {
+        setupTempMapsHelper( obj,objsFast,sysObjsFast, seenSystematics); 
+      } else {
+        ATH_MSG_ERROR( "Could NOT interpret if the histogram: " << obj->GetName()
+                      << " is full or fast simulation!");
+        return 0;
+      }
+    }
+  }
+  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n" 
+                << "Setting up histograms for Run range  " <<
+                runNumEnd);
+  /*
+   * Copy from the temporaries to the actual member variables
+   * via the setup function
+   */
+  for (unsigned int ikey = 0; ikey < s_keys.size(); ++ikey) {
+    if (objsFull.find(s_keys.at(ikey))->second.GetEntries() != 0) {
+      if (0 == setup(objsFull.find(s_keys.at(ikey))->second, m_histList[s_keys.at(ikey)], 
+                     m_begRunNumberList,m_endRunNumberList,runNumBegin,runNumEnd)) {
+        ATH_MSG_ERROR("! Could NOT setup histogram " 
+                      << s_keys.at(ikey)<< " for full sim!");
         return 0;
+      }
     }
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << runNumBegin << "  " << runNumEnd);
-    //
-    /// setup pairs of obj arrays and keys --> e.g. "sf", new Array to take all SF Histos
-    std::map<int, TObjArray> objsFull;
-    std::map<int, TObjArray > objsFast;
-    for (unsigned int ikey = 0; ikey < m_keys.size(); ++ikey) {
-        TObjArray dummyFull;
-        objsFull.insert(std::make_pair(m_keys.at(ikey),dummyFull));
-        TObjArray dummyFast;
-        objsFast.insert(std::make_pair(m_keys.at(ikey),dummyFast));
-    }  
-    TObjArray dummyFull;    
-    objsFull.insert(std::make_pair(mapkey::sys, dummyFull));
-    TObjArray dummyFast;
-    objsFast.insert(std::make_pair(mapkey::sys, dummyFast));
-    //
-    std::vector<TObjArray > sysObjsFull;
-    std::vector<TObjArray > sysObjsFast;
-    //
-    TIter nextkey(gDirectory->GetListOfKeys());
-    TKey *key;
-    TObject *obj(0);
-    TString tmpName = "";
-    int tmpCounter = 0;
-    //Loop of the keys 
-    while ((key = (TKey *) nextkey())) {
-        obj = key->ReadObj();
-        if (obj->IsA()->InheritsFrom("TH1")) {
-            // The histogram containing the scale factors need to end with _sf and need to contain either the string "FullSim"
-            // or "AtlFast2"!
-            if (TString(obj->GetName()).Contains("FullSim")) {
-                //Add all except the correlated 
-                for (unsigned int ikey = 0; ikey < m_keys.size(); ++ikey) {
-                    if (TString(obj->GetName()).EndsWith("_" +  TString(mapkey::keytostring(m_keys.at(ikey))))) {
-                        objsFull.find(m_keys.at(ikey))->second.Add(obj);
-                    }
-                }
-                //
-                tmpName = TString(obj->GetName());
-                //Special treatment , this is only for photons 
-                if (tmpName.EndsWith("_sys")) {
-                    objsFull.find(mapkey::sys)->second.Add(obj);
-                    TObjArray tmpArrayFull;
-                    tmpArrayFull.Add(obj);
-                    sysObjsFull.push_back(tmpArrayFull);
-                    tmpCounter++;
-                }
-                //
-                //See if we are dealing with correlated
-                if (tmpName.Contains("_corr")) {
-                    if (tmpName.EndsWith("corr0")) {
-                        //This is the worse part ...
-                        //corr0 triggers a few thing
-                        //
-                        //1st create a TObjectArray
-                        //For high or low Pt (one for each ...)
-                        TObjArray tmpArrayFull;
-                        //Resgister it to the vector (so the vector has size 1 or 2)
-                        sysObjsFull.push_back(tmpArrayFull);
-                        //Reset the counter
-                        tmpCounter=0;
-                    }
-                    //Add to the current last element of the sysObject full
-                    //This will be Low Pt once and high Pt the other time
-                    sysObjsFull.back().Add(obj);
-                    //Now increase the counter
-                    tmpCounter++;
-                }
-                if (tmpCounter > m_nSysMax) {
-                    m_nSysMax = tmpCounter;
-                }
-            }
-            else if (TString(obj->GetName()).Contains("AtlFast2")) {
-                for (unsigned int ikey = 0; ikey < m_keys.size(); ++ikey) {
-                    if (TString(obj->GetName()).EndsWith("_" +  TString(mapkey::keytostring(m_keys.at(ikey))))) {
-                        objsFast.find(m_keys.at(ikey))->second.Add(obj);
-                    }
-                }
-                //See if we are dealing with correlated
-                tmpName = TString(obj->GetName());
-                //Special treatment , this is only for photons 
-                if (tmpName.EndsWith("_sys")) {
-                    objsFast.find(mapkey::sys)->second.Add(obj);
-                    TObjArray tmpArrayFast;
-                    tmpArrayFast.Add(obj);
-                    sysObjsFast.push_back(tmpArrayFast);
-                    tmpCounter++;
-                }
-                //
-                //See if we are dealing with correlated
-                if (tmpName.Contains("_corr")) {
-                    if (tmpName.EndsWith("corr0")) {
-                        //This is the worse part ...
-                        //corr0 triggers a few thing
-                        //1st create a TObjectArray
-                        TObjArray tmpArrayFast;
-                        //Resgister it
-                        sysObjsFast.push_back(tmpArrayFast);
-                        //Reset the counter
-                        tmpCounter=0;
-                    }
-                    //Add to the current last element of the sysObject full
-                    //This will be Low Pt once and high Pt the other time
-                    sysObjsFast.back().Add(obj);
-                    //Now increase the counter
-                    tmpCounter++;
-                }
-                if (tmpCounter > m_nSysMax) {
-                    m_nSysMax = tmpCounter;
-                }
-            } else {
-                ATH_MSG_ERROR(
-                        " (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                        << "Could NOT interpret if the histogram: " << obj->GetName()
-                        << " is full or fast simulation!");
-                return 0;
-            }
-        }
+    if (objsFast.find(s_keys.at(ikey))->second.GetEntries() != 0) {
+      if (0 == setup(objsFast.find(s_keys.at(ikey))->second, m_fastHistList[s_keys.at(ikey)],
+                     m_begRunNumberListFastSim, m_endRunNumberListFastSim,runNumBegin,runNumEnd)) {
+        ATH_MSG_ERROR("! Could NOT setup histogram " << s_keys.at(ikey)
+                      << " for fast sim");
+        return 0;
+      }
+    }
+  }
+  for (unsigned int sys = 0; sys < sysObjsFast.size(); sys++) {
+    m_fastSysList.resize(sysObjsFast.size());
+    if (0 == setup(sysObjsFast.at(sys), m_fastSysList[sys], m_begRunNumberListFastSim, 
+                   m_endRunNumberListFastSim,runNumBegin,runNumEnd)) {
+      ATH_MSG_ERROR("! Could NOT setup systematic histograms for fast sim");
+      return 0;
+    }
+  }
+  for (unsigned int sys = 0; sys < sysObjsFull.size(); sys++) {
+    m_sysList.resize(sysObjsFull.size());
+    if (0 == setup(sysObjsFull.at(sys), m_sysList[sys], m_begRunNumberList, 
+                   m_endRunNumberList,runNumBegin,runNumEnd)) {
+      ATH_MSG_ERROR("! Could NOT setup systematic histograms for fast sim");
+      return 0;
+    }
+  }
+  //Toys
+  if (m_doToyMC || m_doCombToyMC) {
+    bool fullToysBooked = setupUncorrToySyst(objsFull,sysObjsFull,m_uncorrToyMCSystFull);
+    bool fastToysBooked = setupUncorrToySyst(objsFast,sysObjsFast,m_uncorrToyMCSystFast); 
+    if (fullToysBooked || fastToysBooked) {
+      if (m_doToyMC) {
+        ATH_MSG_DEBUG("Created tables for " << m_nToyMC << " ToyMC systematics ");
+      }
+      if (m_doCombToyMC) {
+        ATH_MSG_DEBUG("Created tables for " << m_nToyMC << " combined ToyMC systematics ");
+      }
+    }
+  }
+  return 1;
+}
+/*
+ * Helper for Setting up the temporary/intermediate maps to Key -> TObjecArray from the histos
+ */
+void Root::TElectronEfficiencyCorrectionTool::setupTempMapsHelper(TObject* obj, 
+                                                                  std::unordered_map<int, TObjArray>& objs,
+                                                                  std::vector<TObjArray >& sysObjs, 
+                                                                  int& seenSystematics)  {
+  //Add all except the correlated 
+  for (unsigned int ikey = 0; ikey < s_keys.size(); ++ikey) {
+    if (TString(obj->GetName()).EndsWith("_" +  TString(mapkey::keytostring(s_keys.at(ikey))))) {
+      objs.find(s_keys.at(ikey))->second.Add(obj);
+    }
+  }
+
+  const TString tmpName(obj->GetName());
+  //Special treatment , this is only for photons 
+  if (tmpName.EndsWith("_sys")) {
+    objs.find(mapkey::sys)->second.Add(obj);
+    TObjArray tmpArray;
+    tmpArray.Add(obj);
+    sysObjs.push_back(tmpArray);
+    seenSystematics++;
+  }
+
+  //See if we are dealing with correlated
+  if (tmpName.Contains("_corr")) {
+    /*
+     * This is the worse part ...
+     * corr0 triggers a few things
+     * We assume that 0 is the 1st
+     * histogram in a series of corr(i) that 
+     * we see for each of the vector entries that 
+     * can be one for LowPt,Standard,Forward etc
+     */
+    if (tmpName.EndsWith("corr0")) {
+      /*
+       * 1st create a TObjectArray
+       */
+      TObjArray tmpArray;
+      /* 
+       * Register it to the vector
+       */
+      sysObjs.push_back(tmpArray);
+      /*
+       * Reset the counter here
+       */
+      seenSystematics=0;
     }
+    /*
+     * Now we can add to the TObjeArray
+     * This can be Low Pt or high Pt
+     */
+    sysObjs.back().Add(obj);
+    /*Increase the counter*/
+    seenSystematics++;
+  }
+
+  if (seenSystematics > m_nSysMax) {
+    m_nSysMax = seenSystematics;
+  }
+}
+/*
+ * Helper for Setting up the uncorrelated syst for the toys
+ */
+bool Root::TElectronEfficiencyCorrectionTool::setupUncorrToySyst(std::unordered_map<int, TObjArray>& objs,
+                                                                 std::vector<TObjArray>& sysObjs,
+                                                                 std::vector< std::vector<TObjArray>>& uncorrToyMCSyst){
+  bool toysBooked = false;
+  if (m_histList[mapkey::sf].size() > 0) {
+    if (objs.find(mapkey::eig)->second.GetEntries() < 1 || objs.find(mapkey::stat)->second.GetEntries() < 1 ||
+        objs.find(mapkey::uncorr)->second.GetEntries() < 1) {
 
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "setting up histograms for run ranges  " <<
-            runNumEnd);
-    //
-    //The setup here copies from the temporaties created in this function , 
-    //to the actual class member variables.
-    for (unsigned int ikey = 0; ikey < m_keys.size(); ++ikey) {
-        if (objsFull.find(m_keys.at(ikey))->second.GetEntries() != 0) {
-            if (0 == setup(objsFull.find(m_keys.at(ikey))->second, m_histList[m_keys.at(ikey)], 
-                        m_begRunNumberList,m_endRunNumberList,runNumBegin,runNumEnd)) {
-                ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                        << "! Could NOT setup histogram " 
-                        << m_keys.at(ikey)<< " for full sim!");
-                return 0;
-            }
-        }
-        if (objsFast.find(m_keys.at(ikey))->second.GetEntries() != 0) {
-            if (0 == setup(objsFast.find(m_keys.at(ikey))->second, m_fastHistList[m_keys.at(ikey)],
-                        m_begRunNumberListFastSim, m_endRunNumberListFastSim,runNumBegin,runNumEnd)) {
-                ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                        << "! Could NOT setup histogram " << m_keys.at(ikey)
-                        << " for fast sim");
-                return 0;
-            }
-        }
-    }
-    for (unsigned int sys = 0; sys < sysObjsFast.size(); sys++) {
-        m_fastSysList.resize(sysObjsFast.size());
-        if (0 == setup(sysObjsFast.at(sys), m_fastSysList[sys], m_begRunNumberListFastSim, 
-                    m_endRunNumberListFastSim,runNumBegin,runNumEnd)) {
-            ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " <<
-                    "! Could NOT setup systematic histograms for fast sim");
-            return 0;
-        }
-    }
-    for (unsigned int sys = 0; sys < sysObjsFull.size(); sys++) {
-        m_sysList.resize(sysObjsFull.size());
-        if (0 == setup(sysObjsFull.at(sys), m_sysList[sys], m_begRunNumberList, 
-                    m_endRunNumberList,runNumBegin,runNumEnd)) {
-            ATH_MSG_ERROR(
-                    " (file: " << __FILE__ << ", line: " << __LINE__ << ") " <<
-                    "! Could NOT setup systematic histograms for fast sim");
-            return 0;
-        }
-    }
-    //
-    //Toys
-    ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-            << "Checking for (m_doToyMC || m_doCombToyMC)");
+      if (objs.find(mapkey::stat)->second.GetEntries() > 1 || objs.find(mapkey::sys)->second.GetEntries() > 1) {
 
-    if (m_doToyMC || m_doCombToyMC) {
-        bool fullToysBooked = kFALSE;
-        bool fastToysBooked = kFALSE;
         TObjArray dummy;
-
-        if (m_histList[mapkey::sf].size() > 0) {
-            if (objsFull.find(mapkey::eig)->second.GetEntries() < 1 || objsFull.find(mapkey::stat)->second.GetEntries() < 1 ||
-                    objsFull.find(mapkey::uncorr)->second.GetEntries() < 1) {
-                if (objsFull.find(mapkey::stat)->second.GetEntries() > 1 || objsFull.find(mapkey::sys)->second.GetEntries() > 1) {
-                    m_uncorrToyMCSystFull.push_back(buildToyMCTable(objsFull.find(mapkey::sf)->second, dummy,
-                                objsFull.find(mapkey::stat)->second,
-                                dummy, sysObjsFull));
-                    fullToysBooked = kTRUE;
-                }else {
-                    ATH_MSG_DEBUG("! Toy MC error propagation booked, but not all needed" 
-                            <<"histograms found in the output (For full sim). Skipping toy creation!");
-                }
-            }else {
-                m_uncorrToyMCSystFull.push_back(buildToyMCTable(objsFull.find(mapkey::sf)->second, objsFull.find(mapkey::eig)->second,
-                            objsFull.find(mapkey::stat)->second,
-                            objsFull.find(mapkey::uncorr)->second, sysObjsFull));
-                fullToysBooked = kTRUE;
-            }
-        }
-        ///// AF2
-        if (m_fastHistList[mapkey::sf].size() > 0) {
-            if (objsFast.find(mapkey::eig)->second.GetEntries() < 1 || objsFast.find(mapkey::stat)->second.GetEntries() < 1 ||
-                    objsFast.find(mapkey::uncorr)->second.GetEntries() < 1) {
-                if (objsFast.find(mapkey::stat)->second.GetEntries() > 1 || objsFast.find(mapkey::sys)->second.GetEntries() > 1) {
-                    m_uncorrToyMCSystFast.push_back(buildToyMCTable(objsFast.find(mapkey::sf)->second, dummy,
-                                objsFast.find(mapkey::stat)->second,
-                                dummy, sysObjsFast));
-                    fastToysBooked = kTRUE;
-                }else {
-                    ATH_MSG_DEBUG("! Toy MC error propagation booked, but not all needed"
-                            << "histograms found in the output (For fast sim). Skipping toy creation!");
-                }
-            }else {
-                m_uncorrToyMCSystFast.push_back(buildToyMCTable(objsFast.find(mapkey::sf)->second, objsFast.find(mapkey::eig)->second,
-                            objsFast.find(mapkey::stat)->second,
-                            objsFast.find(mapkey::uncorr)->second, sysObjsFast));
-                fastToysBooked = kTRUE;
-            }
-        }
-
-        if (fullToysBooked || fastToysBooked) {
-            if (m_doToyMC) {
-                ATH_MSG_DEBUG("Created tables for " << m_nToyMC << " ToyMC systematics ");
-            }
-            if (m_doCombToyMC) {
-                ATH_MSG_DEBUG("Created tables for " << m_nToyMC << " combined ToyMC systematics ");
-            }
-        }
+        uncorrToyMCSyst.push_back(buildToyMCTable(objs.find(mapkey::sf)->second, 
+                                                  dummy,
+                                                  objs.find(mapkey::stat)->second,
+                                                  dummy, 
+                                                  sysObjs));
+        toysBooked = true;
+      }else {
+        ATH_MSG_DEBUG("! Toy MC error propagation booked, but not all needed" 
+                      <<"Histograms found in the output (For full sim). Skipping toy creation!");
+      }
+    }else {
+      uncorrToyMCSyst.push_back(buildToyMCTable(objs.find(mapkey::sf)->second, 
+                                                objs.find(mapkey::eig)->second,
+                                                objs.find(mapkey::stat)->second,
+                                                objs.find(mapkey::uncorr)->second, 
+                                                sysObjs));
+      toysBooked = true;
     }
-    return 1;
+  }
+
+  return toysBooked;
 }
+
 /*
  * Fill and interpret the setup, depending 
  * on which histograms are found in the input file(s)
  */
 int
 Root::TElectronEfficiencyCorrectionTool::setup(const TObjArray& hists,
-        std::vector< TObjArray> &histList,
-        std::vector< unsigned int > &beginRunNumberList,
-        std::vector< unsigned int > &endRunNumberList,
-        const int runNumBegin,
-        const int runNumEnd) const {
-    if (hists.GetEntriesFast()==0) {
-        ATH_MSG_ERROR(
-                "(file: " << __FILE__ << ", line: " << __LINE__ << ") " 
-                << "! Could NOT find histogram with name *_sf in folder");
-        return 0;
-    }
-    for (int i = 0; i < hists.GetEntries(); ++i) {
-        TH1* tmpHist = (TH1 *) hists.At(i);
-        tmpHist->SetDirectory(0);
-    }
-    // Now, we have all the needed info. Fill the vectors accordingly
-    histList.push_back(hists);
-    if (beginRunNumberList.size() > 0) {
-        if (runNumBegin != (int) beginRunNumberList.back()) {
-            beginRunNumberList.push_back(runNumBegin);
-        }
-    }else {
-        beginRunNumberList.push_back(runNumBegin);
-    }
-    if (endRunNumberList.size() > 0) {
-        if (runNumEnd != (int) endRunNumberList.back()) {
-            endRunNumberList.push_back(runNumEnd);
-        }
-    }else {
-        endRunNumberList.push_back(runNumEnd);
-    }
-    return 1;
+                                               std::vector< TObjArray> &histList,
+                                               std::vector< unsigned int > &beginRunNumberList,
+                                               std::vector< unsigned int > &endRunNumberList,
+                                               const int runNumBegin,
+                                               const int runNumEnd) const {
+  if (hists.GetEntriesFast()==0) {
+    ATH_MSG_ERROR( "! Could NOT find histogram with name *_sf in folder");
+    return 0;
+  }
+  TH1 *tmpHist(0);
+  for (int i = 0; i < hists.GetEntries(); ++i) {
+    tmpHist = (TH1 *) hists.At(i);
+    tmpHist->SetDirectory(0);
+  }
+  // Now, we have all the needed info. Fill the vectors accordingly
+  histList.push_back(hists);
+  if (beginRunNumberList.size() > 0) {
+    if (runNumBegin != (int) beginRunNumberList.back()) {
+      beginRunNumberList.push_back(runNumBegin);
+    }
+  }else {
+    beginRunNumberList.push_back(runNumBegin);
+  }
+  if (endRunNumberList.size() > 0) {
+    if (runNumEnd != (int) endRunNumberList.back()) {
+      endRunNumberList.push_back(runNumEnd);
+    }
+  }else {
+    endRunNumberList.push_back(runNumEnd);
+  }
+  return 1;
 }
-
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.cxx
index f1143ee0b724..53ac1aba0b9b 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.cxx
@@ -12,8 +12,7 @@
 #include "GaudiKernel/ITHistSvc.h"
 #include "PATInterfaces/ISystematicsTool.h"
 
-// #include "../ElectronChargeEfficiencyCorrectionTool/IElectronChargeEfficiencyCorrectionTool.h"
-#include "AsgAnalysisInterfaces/IEfficiencyScaleFactorTool.h"
+#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
 
 
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.h b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.h
index 7fe1c95c3297..adf091bf941c 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/src/EleChargeAlg.h
@@ -17,10 +17,7 @@
 // #include "MCTruthClassifier/IMCTruthClassifier.h"
 #include "PATInterfaces/SystematicSet.h"
 
-namespace CP{
-  // class IElectronChargeEfficiencyCorrectionTool;
-  class IEfficiencyScaleFactorTool;
-}
+class IAsgElectronEfficiencyCorrectionTool;
 
 class EleChargeAlg: public ::AthAlgorithm {
  public:
@@ -38,7 +35,7 @@ class EleChargeAlg: public ::AthAlgorithm {
   CP::SystematicSet m_syst;
 
   /// The handle to the charge-misid scale-factor tool
-  ToolHandle<CP::IEfficiencyScaleFactorTool> m_eccTool;
+  ToolHandle<IAsgElectronEfficiencyCorrectionTool> m_eccTool;
 
   /// The name of the input electron container
   StringProperty m_eleContName;
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/EgEfficiencyCorr_mem_check.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/EgEfficiencyCorr_mem_check.cxx
index 97ce34761f2a..bb4ec6dcd519 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/EgEfficiencyCorr_mem_check.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/EgEfficiencyCorr_mem_check.cxx
@@ -16,26 +16,19 @@ http://valgrind.org/docs/manual/faq.html#faq.deflost
 #include <string>
 #include <vector>
 #include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
-#include "AsgAnalysisInterfaces/IEfficiencyScaleFactorTool.h"
 #include "AsgTools/AsgMessaging.h"
 #include "AsgTools/AnaToolHandle.h"
 #ifdef ASGTOOL_STANDALONE
 // xAOD include(s):
 #   include "xAODRootAccess/TEvent.h"
 #endif // ASGTOOL_STANDALONE
-#include "CxxUtils/ubsan_suppress.h"
-#include "TInterpreter.h"
-
 
 int main( ) {
 
-    // Suppress known ubsan warning we get from cling.
-    CxxUtils::ubsan_suppress ([]() { TInterpreter::Instance(); });
-    
 #ifdef ASGTOOL_STANDALONE
     xAOD::TEvent event;
 #endif
-
+    
     using namespace asg::msgUserCode;
     ANA_CHECK_SET_TYPE (int);
 
@@ -45,7 +38,7 @@ int main( ) {
             tool.setProperty("IdKey", "Medium") &&
             tool.retrieve());
 
-    asg::AnaToolHandle<CP::IEfficiencyScaleFactorTool> eccTool;
+    asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool> eccTool;
     eccTool.setTypeAndName("CP::ElectronChargeEfficiencyCorrectionTool/ElectronChargeCorrection");
     ANA_CHECK(eccTool.setProperty( "CorrectionFileName", 
                 "ElectronEfficiencyCorrection/2015_2016/rel20.7/Moriond_February2017_v1/charge_misID/ChargeCorrectionSF.Medium_FixedCutTight.root" )&&
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrFwd.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrFwd.cxx
new file mode 100644
index 000000000000..bde38008ed68
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrFwd.cxx
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+// System include(s):
+#include <memory>
+// ROOT include(s):
+#include <TFile.h>
+// Infrastructure include(s):
+#ifdef ROOTCORE
+#   include "xAODRootAccess/Init.h"
+#   include "xAODRootAccess/TEvent.h"
+#   include "xAODRootAccess/TStore.h"
+#endif // ROOTCORE
+
+// EDM include(s):
+#include "xAODEgamma/ElectronContainer.h" 
+#include "xAODEgamma/Electron.h"
+#include "ElectronEfficiencyCorrection/AsgElectronEfficiencyCorrectionTool.h"
+#include "Messaging.h"
+#include "SFHelpers.h"
+
+//To disable sending data
+#include "xAODRootAccess/tools/TFileAccessTracer.h"
+int main( int argc, char* argv[] ) {
+
+  xAOD::TFileAccessTracer::enableDataSubmission( false );
+  // The application's name:
+  const char* APP_NAME = argv[ 0 ];
+
+  MSG::Level mylevel=MSG::INFO;
+  MSGHELPERS::getMsgStream().msg().setLevel(mylevel);
+  MSGHELPERS::getMsgStream().msg().setName(APP_NAME);
+
+  // Check if we received a file name:
+  if( argc < 2 ) {
+    MSG_ERROR( APP_NAME << "No file name received!" );
+    MSG_ERROR( APP_NAME <<"  Usage: <<APP_NAME <<  [xAOD file name] [Num of events to use]" );
+    return 1;
+  }
+
+  // Initialise the application:
+  CHECK( xAOD::Init( APP_NAME ) );
+
+  // Open the input file:
+  const TString fileName = argv[ 1 ];
+  MSG_INFO("Opening file: " << fileName.Data() );
+  std::auto_ptr< TFile > ifile( TFile::Open( fileName, "READ" ) );
+  CHECK( ifile.get() );
+
+  // Create a TEvent object:
+  xAOD::TEvent event;
+   
+  //Then the tools
+  std::vector<std::string> id_configFiles{"ElectronEfficiencyCorrection/2012/offline/efficiencySF.offline.FwdTight.2012.8TeV.rel17p2.GEO21.v02.root"}; // we don't support keys for fwd electrons, yet. Our latest file is 2012, still
+  AsgElectronEfficiencyCorrectionTool ElEffCorrectionTool ("ElEffCorrectionTool");   
+  CHECK( ElEffCorrectionTool.setProperty("CorrectionFileNameList",id_configFiles));
+  CHECK( ElEffCorrectionTool.setProperty("ForceDataType",1));
+  CHECK( ElEffCorrectionTool.setProperty("OutputLevel", mylevel ));
+  CHECK( ElEffCorrectionTool.setProperty("CorrelationModel", "FULL" )); 
+  CHECK( ElEffCorrectionTool.setProperty("UseRandomRunNumber", false ));
+  CHECK( ElEffCorrectionTool.initialize());  
+    
+  //Then open the file(s)
+  CHECK( event.readFrom( ifile.get() ) );
+  MSG_INFO( "Number of available events to read in:  " <<
+            static_cast< long long int >( event.getEntries() ) );
+
+  // Decide how many events to run over:
+  long long int entries = event.getEntries();
+  if( argc > 2 ) {
+    const long long int e = atoll( argv[ 2 ] );
+    if( e < entries ) {
+      entries = e;
+    }
+  }
+  MSG_INFO( "Number actual events to read in:  " <<entries );
+
+
+  // Loop over the events:
+  for(long  long int entry=0  ; entry < entries; ++entry ) {
+    event.getEntry( entry );
+    MSG_INFO( " \n ==> Event " << entry);
+
+    const xAOD::ElectronContainer* electrons = 0;  
+    CHECK( event.retrieve(electrons, "ForwardElectrons") );
+
+    for (const xAOD::Electron* el : *electrons){
+      if(el->pt() < 20000) continue; //skip electrons outside of recommendations
+      if(fabs(el->caloCluster()->eta()) < 2.5) continue; //skip electrons outside of recommendations
+      int index =ElEffCorrectionTool.systUncorrVariationIndex(*el);
+      /*
+       * Set up the systematic variations
+       */
+      bool isToys = false;
+      double nominalSF{};
+      double totalNeg{};
+      double totalPos{}; 
+      CHECK(SFHelpers::result(ElEffCorrectionTool,*el,nominalSF, totalPos,totalNeg,isToys)==0);
+
+      MSG_INFO("===> electron : Pt = " << el->pt() << " : eta = " << el->eta() 
+	       << " : Bin index = " <<index   <<" : SF = "<< nominalSF 
+	       << " + " << totalPos << " - " <<totalNeg << " <===");
+    }
+  }
+    
+  MSG_INFO("===> DONE <===\n"); 
+  return 0;
+
+}
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrWithoutFile.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrWithoutFile.cxx
index e07ac561fb5c..0c78b065bb4c 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrWithoutFile.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronEfficiencyCorrection/util/testEgEfficiencyCorrWithoutFile.cxx
@@ -167,5 +167,3 @@ int main( int argc, char* argv[] ) {
             << " + " << totalPos << " - " <<totalNeg << " <===");
     return 0;
 }
-
-
-- 
GitLab