diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
index f8721c64a42b8d020615adb58632eeb923e3b009..f5e63162778170bb03cf3ae1435e7f5cab94af87 100644
--- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
+++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
@@ -151,7 +151,7 @@ def makeElectronCalibrationSequence( seq, dataType, postfix = '',
                            'ElectronCalibrationAndSmearingAlg' + postfix )
     addPrivateTool( alg, 'calibrationAndSmearingTool',
                     'CP::EgammaCalibrationAndSmearingTool' )
-    alg.calibrationAndSmearingTool.ESModel = 'es2018_R21_v0'
+    alg.calibrationAndSmearingTool.ESModel = 'es2022_R21_Precision'
     alg.calibrationAndSmearingTool.decorrelationModel = '1NP_v1'
     if dataType == 'afii':
         alg.calibrationAndSmearingTool.useAFII = 1
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/EgammaCalibrationAndSmearingTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/EgammaCalibrationAndSmearingTool.h
index a27d3c9fb1d424afabd01e1faf993969b0582578..c0faba14011ff444c700101e969df2cf8b7919d2 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/EgammaCalibrationAndSmearingTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/EgammaCalibrationAndSmearingTool.h
@@ -1,10 +1,9 @@
 // Dear Emacs, this is -*- C++ -*-
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
-
 #ifndef EGAMMA_CALIB_TOOL_H_
 #define EGAMMA_CALIB_TOOL_H_
 
@@ -12,6 +11,7 @@
 #include <string>
 #include <array>
 #include <memory>
+#include <map>
 
 #include "EgammaAnalysisInterfaces/IEgammaCalibrationAndSmearingTool.h"
 #include "AsgTools/AsgTool.h"
@@ -31,48 +31,50 @@
 // Forward declarations
 class egammaMVATool;
 class egammaLayerRecalibTool;
-namespace egGain { class GainTool; }
+namespace egGain { class GainTool; class GainUncertainty; }
+class LinearityADC;
+class TH2;
 
 namespace xAOD {
   inline float get_phi_calo(const xAOD::CaloCluster& cluster, int author, bool do_throw=false)
-	{
-	  double phi_calo;
-	  if(author== xAOD::EgammaParameters::AuthorFwdElectron){
-	    phi_calo = cluster.phi();
-	  }
-	  else if (cluster.retrieveMoment(xAOD::CaloCluster::PHICALOFRAME, phi_calo)) { }
-	  else if (cluster.isAvailable<float>("phiCalo")) {
-	    phi_calo = cluster.auxdata<float>("phiCalo");
-	  }
-	  else {
-			asg::AsgMessaging msg("get_phi_calo");
-			msg.msg(MSG::ERROR) << "phiCalo not available as auxilliary variable" << endmsg;
-	    if (do_throw) { throw std::runtime_error("phiCalo not available as auxilliary variable"); }
-			msg.msg(MSG::WARNING) << "using phi as phiCalo" << endmsg;
-	    phi_calo = cluster.phi();
-	  }
-	  return phi_calo;
-	}
+  {
+    double phi_calo;
+    if(author== xAOD::EgammaParameters::AuthorFwdElectron){
+      phi_calo = cluster.phi();
+    }
+    else if (cluster.retrieveMoment(xAOD::CaloCluster::PHICALOFRAME, phi_calo)) { }
+    else if (cluster.isAvailable<float>("phiCalo")) {
+      phi_calo = cluster.auxdata<float>("phiCalo");
+    }
+    else {
+      asg::AsgMessaging msg("get_phi_calo");
+      msg.msg(MSG::ERROR) << "phiCalo not available as auxilliary variable" << endmsg;
+      if (do_throw) { throw std::runtime_error("phiCalo not available as auxilliary variable"); }
+      msg.msg(MSG::WARNING) << "using phi as phiCalo" << endmsg;
+      phi_calo = cluster.phi();
+    }
+    return phi_calo;
+  }
 
   inline float get_eta_calo(const xAOD::CaloCluster& cluster, int author, bool do_throw=false)
-	{
-	  double eta_calo;
-	  if(author== xAOD::EgammaParameters::AuthorFwdElectron){ 
-            eta_calo = cluster.eta();
-          }
-	  else if (cluster.retrieveMoment(xAOD::CaloCluster::ETACALOFRAME,
-				       eta_calo)) { }
-	  else if (cluster.isAvailable<float>("etaCalo")) {
-	    eta_calo = cluster.auxdata<float>("etaCalo");
-	  }
-	  else {
-			asg::AsgMessaging msg("get_eta_calo");
-			msg.msg(MSG::ERROR) << "etaCalo not available as auxilliary variable" << endmsg;
-	    if (do_throw) { throw std::runtime_error("etaCalo not available as auxilliary variable"); }
-			msg.msg(MSG::WARNING) << "using eta as etaCalo" << endmsg;
-	  }
-	  return eta_calo;
-	}
+  {
+    double eta_calo;
+    if(author== xAOD::EgammaParameters::AuthorFwdElectron){
+      eta_calo = cluster.eta();
+    }
+    else if (cluster.retrieveMoment(xAOD::CaloCluster::ETACALOFRAME,
+				    eta_calo)) { }
+    else if (cluster.isAvailable<float>("etaCalo")) {
+      eta_calo = cluster.auxdata<float>("etaCalo");
+    }
+    else {
+      asg::AsgMessaging msg("get_eta_calo");
+      msg.msg(MSG::ERROR) << "etaCalo not available as auxilliary variable" << endmsg;
+      if (do_throw) { throw std::runtime_error("etaCalo not available as auxilliary variable"); }
+      msg.msg(MSG::WARNING) << "using eta as etaCalo" << endmsg;
+    }
+    return eta_calo;
+  }
 }
 
 namespace CP {
@@ -83,8 +85,8 @@ class EgammaCalibrationAndSmearingTool : virtual public IEgammaCalibrationAndSme
 
 public:
 
-	enum class ScaleDecorrelation {FULL, ONENP, FULL_ETA_CORRELATED, ONENP_PLUS_UNCONR};
-	enum class ResolutionDecorrelation {FULL, ONENP};
+  enum class ScaleDecorrelation {FULL, ONENP, FULL_ETA_CORRELATED, ONENP_PLUS_UNCONR};
+  enum class ResolutionDecorrelation {FULL, ONENP};
   static const int AUTO = 2;  // this is used as a third state for boolean propertis (true/false/automatic)
   typedef unsigned int RandomNumber;
   typedef std::function<int(const EgammaCalibrationAndSmearingTool&, const xAOD::Egamma&, const xAOD::EventInfo&)> IdFunction;
@@ -121,7 +123,7 @@ public:
   virtual CP::SystematicCode applySystematicVariation(const CP::SystematicSet& systConfig) override;
   virtual void setRandomSeed(unsigned seed=0) override;
   virtual void setRandomSeedFunction(const IdFunction&& function) { m_set_seed_function = function; }
-	const IdFunction getRandomSeedFuction() const { return m_set_seed_function; }
+  const IdFunction getRandomSeedFuction() const { return m_set_seed_function; }
 
   virtual double resolution( double energy, double cl_eta, double cl_etaCalo,
                              PATCore::ParticleType::Type ptype = PATCore::ParticleType::Electron, bool withCT=false) const override;
@@ -151,7 +153,10 @@ private:
   int m_useLayer2Recalibration;
   int m_useIntermoduleCorrection;
   int m_usePhiUniformCorrection;
+  int m_useCaloDistPhiUnifCorrection;
   int m_useGainCorrection;
+  int m_doADCLinearityCorrection;
+  int m_doLeakageCorrection;
   bool m_use_ep_combination;
   int m_use_mva_calibration;
   bool m_use_full_statistical_error;
@@ -160,14 +165,17 @@ private:
   bool m_use_mapping_correction;
   int m_user_random_run_number;
 
+  // 2D histrogram (eta,phi) for a correction to cope with calo distortion (sagging)
+  std::unique_ptr<TH2> m_caloDistPhiUnifCorr;
+
   void setupSystematics();
 
   StatusCode get_simflavour_from_metadata(PATCore::ParticleDataType::DataType& result) const;
 
-	// this is needed (instead of a simpler lambda since a clang bug, see https://its.cern.ch/jira/browse/ATLASG-688)
-	struct AbsEtaCaloPredicate
+  // this is needed (instead of a simpler lambda since a clang bug, see https://its.cern.ch/jira/browse/ATLASG-688)
+  struct AbsEtaCaloPredicate
   {
-		AbsEtaCaloPredicate(double eta_min, double eta_max) : m_eta_min(eta_min), m_eta_max(eta_max) {}
+    AbsEtaCaloPredicate(double eta_min, double eta_max) : m_eta_min(eta_min), m_eta_max(eta_max) {}
     bool operator()(const xAOD::Egamma& p) {
       const double aeta = std::abs(xAOD::get_eta_calo(*p.caloCluster(),p.author()));
       return (aeta >= m_eta_min and aeta < m_eta_max);
@@ -178,10 +186,10 @@ private:
 
   const EgammaPredicate AbsEtaCaloPredicateFactory(double eta_min, double eta_max) const
 	{
-		/*return [eta_min, eta_max](const xAOD::Egamma& p) {
-			const double aeta = std::abs(xAOD::get_eta_calo(*p.caloCluster()));
-			return (aeta >= eta_min and aeta < eta_max); };*/
-		return AbsEtaCaloPredicate(eta_min, eta_max);
+	  /*return [eta_min, eta_max](const xAOD::Egamma& p) {
+	    const double aeta = std::abs(xAOD::get_eta_calo(*p.caloCluster()));
+	    return (aeta >= eta_min and aeta < eta_max); };*/
+	  return AbsEtaCaloPredicate(eta_min, eta_max);
 	}
 
 	const EgammaPredicate AbsEtaCaloPredicateFactory(std::pair<double, double> edges) const
@@ -220,11 +228,12 @@ public:
   double intermodule_correction(double Ecl, double phi, double eta) const;
   double correction_phi_unif(double eta, double phi) const;
 
-
 private:
   // use raw pointer to use forward declaration, TODO: better solution?
   mutable egammaMVATool* m_mva_tool = nullptr; //!
   egGain::GainTool* m_gain_tool = nullptr; //!
+  std::unique_ptr<egGain::GainUncertainty> m_gain_tool_run2;
+  std::shared_ptr<LinearityADC> m_ADCLinearity_tool;
   egammaLayerRecalibTool* m_layer_recalibration_tool = nullptr; //!
   std::string m_layer_recalibration_tune; //!
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/GainUncertainty.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/GainUncertainty.h
index 6130b66b0b4df03d23be329d80a6cbe53fcc2845..2c56b5115d0fe0d81bebbda6b1e6383e87f48bf7 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/GainUncertainty.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/GainUncertainty.h
@@ -1,47 +1,42 @@
-// Dear emacs, this is -*- c++ -*-
-
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifndef ELECTRONPHOTONFOURMOMENTUMCORRECTION_GAINUNCERTAINTYY_H
-#define ELECTRONPHOTONFOURMOMENTUMCORRECTION_GAINUNCERTAINTYY_H
+#ifndef ELECTRONPHOTONFOURMOMENTUMCORRECTION_GAINUNCERTAINTY_H
+#define ELECTRONPHOTONFOURMOMENTUMCORRECTION_GAINUNCERTAINTY_H
 
 #include <AsgTools/AsgMessaging.h>
 #include <PATCore/PATCoreEnums.h>
 #include <memory>
 #include <string>
 
-
-class TFile;
 class TH1;
 
-namespace egGain{
+namespace egGain {
 
 class GainUncertainty : public asg::AsgMessaging {
 public:
 
-    GainUncertainty(const std::string& filename);
-    ~GainUncertainty();
-
- // return relative uncertainty on energy from gain uncertainty
- // input etaCalo_input = eta in Calo frame
- //       et_input = Et in MeV
- //       ptype    = particle type
+  GainUncertainty(const std::string& filename, const std::string& name = "GainUncertainty");
+  ~GainUncertainty() {};
 
-  double getUncertainty(double etaCalo_input, double et_input, PATCore::ParticleType::Type ptype=PATCore::ParticleType::Electron) const;
+  // return relative uncertainty on energy from gain uncertainty
+  // input etaCalo_input = eta in Calo frame
+  //       et_input = Et in MeV
+  //       ptype    = particle type
+  //       useUncertainty : instead of the value, if a correction has been applied
+  double getUncertainty(double etaCalo_input, double et_input,
+			PATCore::ParticleType::Type ptype = PATCore::ParticleType::Electron,
+			bool useUncertainty = false) const;
 
 private:
 
-  static const int m_NUM_ETA_BINS=5;
-
-  std::unique_ptr<TFile> m_gainFile;
-
-  TH1* m_alpha_specialGainRun;
-  TH1* m_gain_impact_Zee;
-  TH1* m_gain_Impact_elec[5];
-  TH1* m_gain_Impact_conv[5];
-  TH1* m_gain_Impact_unco[5];
+  static const int s_nEtaBins=5;
+  std::unique_ptr<TH1> m_alpha_specialGainRun;
+  std::unique_ptr<TH1> m_gain_impact_Zee;
+  std::unique_ptr<TH1> m_gain_Impact_elec[s_nEtaBins]{};
+  std::unique_ptr<TH1> m_gain_Impact_conv[s_nEtaBins]{};
+  std::unique_ptr<TH1> m_gain_Impact_unco[s_nEtaBins]{};
 
 };
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/LinearityADC.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/LinearityADC.h
new file mode 100644
index 0000000000000000000000000000000000000000..b229945733efa1f7f42e37e0e30c29582936a6f4
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/LinearityADC.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ELECTRONPHOTONFOURMOMENTUMCORRECTION_LINEARITYADC_H
+#define ELECTRONPHOTONFOURMOMENTUMCORRECTION_LINEARITYADC_H
+#include <PATCore/PATCoreEnums.h>
+#include <AsgTools/AsgMessaging.h>
+
+#include <string>
+#include <map>
+#include <memory>
+
+#include <TProfile2D.h>
+
+namespace asg {
+  class AsgMessaging;
+}
+
+/**
+  @class LinearityADC
+  @brief parameterization of correction for ADC non linearity
+
+  deltaADC vs ADC parameterized from calibration runs in different eta bins for HG/MG/HG by Luca
+  applied to single particle samples to parameterize vs eta and Et and particle type
+*/
+
+class LinearityADC  : public asg::AsgMessaging {
+
+ public:
+   /** @brief constructor (initialization done there reading a root file for the HV maps per period */
+  LinearityADC(const std::string& filename, const std::string& name = "ADCNonLinearityCorrection");
+  ~LinearityADC() {};
+
+  /** @brief get relative correction factor to apply to energy: corrected energy should be original energy * correction factor */
+  /** @brief inputs: etaCalo and Et in MeV, pType (enum) */
+  float getCorr(float etaCalo, float et, PATCore::ParticleType::Type ptype = PATCore::ParticleType::Electron) const;
+
+ private:
+  std::map<PATCore::ParticleType::Type,std::unique_ptr<TProfile2D>> m_hcorr;
+
+};
+#endif
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h
index f24d64c88abd749f06e1380896f95102c4168fd3..5a89b8042dad61b2344789d2da3561009ae74414 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h
@@ -1,7 +1,7 @@
 // Dear emacs, this is -*-c++-*-
 
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //////////////////////////////////////////////////////////////
@@ -15,36 +15,25 @@
 
 // STL includes
 #include <string>
-#include <vector>
-#include <iostream>
-#include <fstream>
-#include <cstdlib>
-#include <iomanip>
-#include <cmath>
-#include <cctype>
-#include <cstddef>
+#include <memory>
+#include <utility>
 
 // PAT includes
 #include "PATCore/PATCoreEnums.h"
 #include <AsgTools/AsgMessaging.h>
 
-
 // ROOT includes
 #include "TRandom3.h"
-//#include "TList.h"
-//#include "TFile.h"
-//#include "TGraphErrors.h"
-#include "TSystem.h"
 
 // Forward declarations
 class eg_resolution;
 class get_MaterialResolutionEffect;
 class e1hg_systematics;
+class LinearityADC;
 
 class TH1;
 class TH2;
 class TAxis;
-class TFile;
 class TList;
 
 namespace egGain { class GainTool;            // run1 tool
@@ -178,14 +167,20 @@ namespace egEnergyCorr {
       // AF2 systematics
       af2Up, af2Down,
 
-      // The following apply to photons only
+      // ... ADC non linearity correction
+      ADCLinUp, ADCLinDown,
+
+      // ... Leakage : electron
+      LeakageElecUp, LeakageElecDown,
 
-      // ... Leakage
+      // The following apply to photons only
+      // ... Leakage : photon
       LeakageUnconvUp, LeakageUnconvDown, LeakageConvUp, LeakageConvDown,
 
       // ... Conversion efficiency (-> vary unconverted photon calib), fake rate (-> vary converted photon calib)
       ConvEfficiencyUp, ConvEfficiencyDown, ConvFakeRateUp, ConvFakeRateDown, ConvRadiusUp, ConvRadiusDown,
-
+      // ... in R21, 2022, Precision : NP is correlated between conv and unconv, let's call it ConvReco
+      ConvRecoUp, ConvRecoDown,
 
       AllUp, AllDown,
       AllCorrelatedUp, AllCorrelatedDown,
@@ -237,8 +232,11 @@ namespace egEnergyCorr {
     es2017_R21_v1,          // Release 21 model July 2018 adding forward, AFII, mc16d/reproc data, new mat syst 
     es2017_R21_ofc0_v1,  // Release 21 model calibration extrapolated for OFC(mu=0), coveering 2015,2016,2017 and 2018 data
     es2018_R21_v0,
+    es2018_R21_lowmu_v0, // model for 2017 and 2018 mu = 2 dataset at sqrt(s) = 13TeV and 5TeV
     es2018_R21_v1,     // model with new E1/E2 muon calibration from full run 2 low+high mu data
 
+    es2022_R21_Precision,     // Precision Recomandation Rel21 model E1/E2 muon+Electron combination ; PS scale with Low-mu runs muons
+
     UNDEFINED
 
   };
@@ -293,6 +291,9 @@ namespace AtlasRoot {
     // ... set input file
     inline void setFileName ( const std::string& val ){ m_rootFileName = val; }
 
+    // ... set runnumber
+    void setRunnumber( long int runn=0 ) { m_RunNumber = runn; }
+
     // ... set a seed for the random number generator
     void setRandomSeed( unsigned seed=0 ) { m_random3.SetSeed(seed); }
 
@@ -334,16 +335,31 @@ namespace AtlasRoot {
                       PATCore::ParticleType::Type ptype,
 		      bool withCT,
 		      bool fast,
-                      egEnergyCorr::Resolution::resolutionType resType = egEnergyCorr::Resolution::SigmaEff90 ) const;
+                      egEnergyCorr::Resolution::resolutionType resType = egEnergyCorr::Resolution::SigmaEff90) const;
 
     // new for mc12c model. Return relative uncertainty on the resolution
-    double getResolutionError(PATCore::ParticleDataType::DataType dataType,double energy, double eta, double etaCalo, PATCore::ParticleType::Type ptype, egEnergyCorr::Resolution::Variation value,
-                              egEnergyCorr::Resolution::resolutionType resType = egEnergyCorr::Resolution::Gaussian) const;
+    double getResolutionError(PATCore::ParticleDataType::DataType dataType,
+			      double energy, double eta, double etaCalo,
+			      PATCore::ParticleType::Type ptype,
+			      egEnergyCorr::Resolution::Variation value,
+                              egEnergyCorr::Resolution::resolutionType resType = egEnergyCorr::Resolution::SigmaEff90) const;
 
 
     std::string variationName(egEnergyCorr::Scale::Variation& var) const;
     std::string variationName(egEnergyCorr::Resolution::Variation& var) const;
 
+    // For run2, precision final recommendation, when we correct for L2Gain,
+    // we do not use the size of the effect as systematic uncertainty, but the estimated uncertainty
+    void setApplyL2GainCorrection() { m_useL2GainCorrection = true; }
+
+    // Idem for leakage correction
+    void setApplyLeakageCorrection(bool interp = false)
+    {
+      m_useLeakageCorrection = true;
+      m_usepTInterpolationForLeakage = interp;
+    }
+
+    void setADCTool(std::shared_ptr<LinearityADC> t) { m_ADCLinearity_tool = t; }
 
     // convenient method for decorrelation of statistical error
     const TAxis& get_ZeeStat_eta_axis() const;
@@ -352,6 +368,7 @@ namespace AtlasRoot {
     // TODO: remove mutable
     mutable std::unique_ptr<egGain::GainTool> m_gain_tool;                    // run 1
     std::unique_ptr<egGain::GainUncertainty> m_gain_tool_run2;        // based on special run for run2
+    std::shared_ptr<LinearityADC> m_ADCLinearity_tool;
     mutable std::unique_ptr<eg_resolution> m_resolution_tool;
     mutable std::unique_ptr<get_MaterialResolutionEffect> m_getMaterialDelta;
     mutable std::unique_ptr<e1hg_systematics> m_e1hg_tool;
@@ -434,6 +451,10 @@ namespace AtlasRoot {
 
     double getAlphaLeakage(double cl_eta, PATCore::ParticleType::Type ptype,
 			   egEnergyCorr::Scale::Variation var = egEnergyCorr::Scale::Nominal, double varSF = 1. ) const;
+    double getAlphaLeakage2D(double cl_eta, double et, PATCore::ParticleType::Type ptype,
+			     egEnergyCorr::Scale::Variation var = egEnergyCorr::Scale::Nominal,
+			     double varSF = 1.) const;
+    std::pair<double,double> getAlphaUncAlpha(TH1 *hh, double cl_eta, double et, bool useInterp) const;
 
     double getAlphaConvSyst(double cl_eta, double energy, PATCore::ParticleType::Type ptype,
 			    egEnergyCorr::Scale::Variation var = egEnergyCorr::Scale::Nominal, double varSF = 1. ) const;
@@ -445,6 +466,7 @@ namespace AtlasRoot {
 			    egEnergyCorr::Scale::Variation var = egEnergyCorr::Scale::Nominal, double varSF = 1. ) const;
     double get_ZeeSyst(double eta) const;
     bool isInCrack( double cl_eta ) const;
+
     double nearestEtaBEC( double cl_eta ) const;
 
  /** @brief get resolution and its uncertainty)
@@ -463,16 +485,15 @@ namespace AtlasRoot {
 
   private:
 
-
-    std::unique_ptr<TFile> m_rootFile;
     std::string m_rootFileName;
 
     mutable TRandom3   m_random3;
 
     unsigned int  m_begRunNumber;
     unsigned int  m_endRunNumber;
+    unsigned int  m_RunNumber;
 
-   std::unique_ptr<TH1>         m_trkSyst;
+    std::unique_ptr<TH1>         m_trkSyst;
 
     std::unique_ptr<TH1>         m_aPSNom;
     std::unique_ptr<TH1>         m_daPSCor;
@@ -493,6 +514,7 @@ namespace AtlasRoot {
     std::unique_ptr<TH1>         m_uA2MeV_2015_first2weeks_correction;
 
     std::unique_ptr<TH1>         m_resNom;
+    std::unique_ptr<TH1>         m_resNom_datalowmu;
     std::unique_ptr<TH1>         m_resSyst;
     std::unique_ptr<TH1>         m_peakResData;
     std::unique_ptr<TH1>         m_peakResMC;
@@ -545,6 +567,7 @@ namespace AtlasRoot {
 
     std::unique_ptr<TH1>         m_leakageConverted;
     std::unique_ptr<TH1>         m_leakageUnconverted;
+    std::unique_ptr<TH1>         m_leakageElectron;
 
     std::unique_ptr<TH1>         m_zeeES2Profile;
 
@@ -630,6 +653,10 @@ namespace AtlasRoot {
     bool m_use_new_resolution_model;
     bool m_use_stat_error_scaling;  // default = false
 
+    bool m_useL2GainCorrection;
+    bool m_useLeakageCorrection;
+    bool m_usepTInterpolationForLeakage;
+
     bool m_use_temp_correction201215;  // default = true (used only for es2015PRE)
     bool m_use_temp_correction201516;
     bool m_use_uA2MeV_2015_first2weeks_correction; // default = true (used only for es2105PRE)
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12.def b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12.def
index d95f1cac96383cecf875a9c8992efcd8d7241a21..916f77289c9a0baf4ccaf2af3bc3d61f92436fbf 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12.def
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12.def
@@ -14,6 +14,4 @@ SYSMACRO(EG_SCALE_L2GAIN,         1, std::vector<double>(),        egEnergyCorr:
 SYSMACRO(EG_SCALE_PEDESTAL,       1, std::vector<double>(),        egEnergyCorr::Scale::PedestalUp,       egEnergyCorr::Scale::PedestalDown)
 SYSMACRO(PH_SCALE_LEAKAGEUNCONV,  1, std::vector<double>(),        egEnergyCorr::Scale::LeakageUnconvUp,  egEnergyCorr::Scale::LeakageUnconvDown)
 SYSMACRO(PH_SCALE_LEAKAGECONV,    1, std::vector<double>(),        egEnergyCorr::Scale::LeakageConvUp,    egEnergyCorr::Scale::LeakageConvDown)
-SYSMACRO(PH_SCALE_CONVEFFICIENCY, 1, std::vector<double>(),        egEnergyCorr::Scale::ConvEfficiencyUp, egEnergyCorr::Scale::ConvEfficiencyDown)
-SYSMACRO(PH_SCALE_CONVFAKERATE,   1, std::vector<double>(),        egEnergyCorr::Scale::ConvFakeRateUp,   egEnergyCorr::Scale::ConvFakeRateDown)
 SYSMACRO(PH_SCALE_CONVRADIUS,     1, std::vector<double>(),        egEnergyCorr::Scale::ConvRadiusUp,     egEnergyCorr::Scale::ConvRadiusDown)
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics.def b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12_2022.def
similarity index 81%
rename from PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics.def
rename to PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12_2022.def
index e4361c416b1e41702b38576caeb28c43e4434ce9..58e84f38cac6fc85b318e050916cf1b9e3c00830 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics.def
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/ElectronPhotonFourMomentumCorrection/systematics_S12_2022.def
@@ -1,11 +1,10 @@
 SYSMACRO(EG_SCALE_ZEESYST,        1, std::vector<double>(),        egEnergyCorr::Scale::ZeeSystUp,        egEnergyCorr::Scale::ZeeSystDown)
-SYSMACRO(EG_SCALE_LARCALIB,       0, decorrelation_bins_BE,        egEnergyCorr::Scale::LArCalibUp,       egEnergyCorr::Scale::LArCalibDown)
 SYSMACRO(EG_SCALE_LARUNCONVCALIB, 0, decorrelation_bins_BE,        egEnergyCorr::Scale::LArUnconvCalibUp, egEnergyCorr::Scale::LArUnconvCalibDown)
 SYSMACRO(EG_SCALE_LARELECCALIB,   1, std::vector<double>(),        egEnergyCorr::Scale::LArElecCalibUp,   egEnergyCorr::Scale::LArElecCalibDown)
 SYSMACRO(EG_SCALE_LARELECUNCONV,  0, decorrelation_bins_BE,        egEnergyCorr::Scale::LArElecUnconvUp,  egEnergyCorr::Scale::LArElecUnconvDown)
 SYSMACRO(EG_SCALE_G4,             1, std::vector<double>(),        egEnergyCorr::Scale::G4Up,             egEnergyCorr::Scale::G4Down)
 SYSMACRO(EG_SCALE_PS,             0, decorrelation_edges_MODULE,   egEnergyCorr::Scale::PSUp,             egEnergyCorr::Scale::PSDown)
-SYSMACRO(EG_SCALE_S12,            0, decorrelation_edges_TWELVE,   egEnergyCorr::Scale::S12Up,            egEnergyCorr::Scale::S12Down);
+SYSMACRO(EG_SCALE_S12,            0, decorrelation_edges_S12,      egEnergyCorr::Scale::S12Up,            egEnergyCorr::Scale::S12Down);
 SYSMACRO(EG_SCALE_MATID,          0, decorrelation_edges_MATERIAL, egEnergyCorr::Scale::MatIDUp,          egEnergyCorr::Scale::MatIDDown);
 SYSMACRO(EG_SCALE_MATCRYO,        0, decorrelation_edges_TWELVE,   egEnergyCorr::Scale::MatCryoUp,        egEnergyCorr::Scale::MatCryoDown)
 SYSMACRO(EG_SCALE_MATCALO,        0, decorrelation_edges_TWELVE,   egEnergyCorr::Scale::MatCaloUp,        egEnergyCorr::Scale::MatCaloDown)
@@ -14,6 +13,4 @@ SYSMACRO(EG_SCALE_L2GAIN,         1, std::vector<double>(),        egEnergyCorr:
 SYSMACRO(EG_SCALE_PEDESTAL,       1, std::vector<double>(),        egEnergyCorr::Scale::PedestalUp,       egEnergyCorr::Scale::PedestalDown)
 SYSMACRO(PH_SCALE_LEAKAGEUNCONV,  1, std::vector<double>(),        egEnergyCorr::Scale::LeakageUnconvUp,  egEnergyCorr::Scale::LeakageUnconvDown)
 SYSMACRO(PH_SCALE_LEAKAGECONV,    1, std::vector<double>(),        egEnergyCorr::Scale::LeakageConvUp,    egEnergyCorr::Scale::LeakageConvDown)
-SYSMACRO(PH_SCALE_CONVEFFICIENCY, 1, std::vector<double>(),        egEnergyCorr::Scale::ConvEfficiencyUp, egEnergyCorr::Scale::ConvEfficiencyDown)
-SYSMACRO(PH_SCALE_CONVFAKERATE,   1, std::vector<double>(),        egEnergyCorr::Scale::ConvFakeRateUp,   egEnergyCorr::Scale::ConvFakeRateDown)
 SYSMACRO(PH_SCALE_CONVRADIUS,     1, std::vector<double>(),        egEnergyCorr::Scale::ConvRadiusUp,     egEnergyCorr::Scale::ConvRadiusDown)
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaCalibrationAndSmearingTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaCalibrationAndSmearingTool.cxx
index b6a229a15a6329f56fade2ce3bd9f6c03da42caf..0f9fb8becf73f7cdf284d62cae59e801c6f469fd 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaCalibrationAndSmearingTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaCalibrationAndSmearingTool.cxx
@@ -1,9 +1,10 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <string>
 #include <utility>
+#include <vector>
 
 #include <boost/format.hpp>
 
@@ -31,9 +32,13 @@
 #include "egammaMVACalib/egammaMVATool.h"
 #include "egammaLayerRecalibTool/egammaLayerRecalibTool.h"
 #include "ElectronPhotonFourMomentumCorrection/GainTool.h"
+#include "ElectronPhotonFourMomentumCorrection/LinearityADC.h"
+// For final run2, the GainUncertainty tool can be used also for a L2Gain correction
+#include "ElectronPhotonFourMomentumCorrection/GainUncertainty.h"
 
 #include "ElectronPhotonFourMomentumCorrection/EgammaCalibrationAndSmearingTool.h"
 
+#include "TH2.h"
 
 namespace CP {
 
@@ -69,8 +74,10 @@ std::unique_ptr<egGain::GainTool> gainToolFactory(egEnergyCorr::ESModel model)
     case egEnergyCorr::es2017_R21_v1:
     case egEnergyCorr::es2017_R21_ofc0_v1:
     case egEnergyCorr::es2018_R21_v0:
+    case egEnergyCorr::es2018_R21_lowmu_v0:
     case egEnergyCorr::es2018_R21_v1:
-      return nullptr;  
+    case egEnergyCorr::es2022_R21_Precision:
+      return nullptr;
     default:
       return nullptr;
   }
@@ -113,7 +120,9 @@ std::unique_ptr<egammaMVATool> egammaMVAToolFactory(egEnergyCorr::ESModel model)
         case egEnergyCorr::es2017_R21_v1:  
         case egEnergyCorr::es2017_R21_ofc0_v1:  
         case egEnergyCorr::es2018_R21_v0:
+        case egEnergyCorr::es2018_R21_lowmu_v0:  
         case egEnergyCorr::es2018_R21_v1:
+        case egEnergyCorr::es2022_R21_Precision:
 	  folder = "egammaMVACalib/offline/v7";
           break;
         default: folder = "";
@@ -163,11 +172,15 @@ std::unique_ptr<egammaLayerRecalibTool> egammaLayerRecalibToolFactory(egEnergyCo
     case egEnergyCorr::es2017_R21_v1:
     case egEnergyCorr::es2017_R21_ofc0_v1:
     case egEnergyCorr::es2018_R21_v0:
+    case egEnergyCorr::es2018_R21_lowmu_v0:
       tune = "es2017_21.0_v0";
       break;
     case egEnergyCorr::es2018_R21_v1:
       tune = "es2018_21.0_v0";
       break;
+    case egEnergyCorr::es2022_R21_Precision:
+      tune = "es2022_21.0_Precision";
+      break;
     default:
       return nullptr;
   }
@@ -206,7 +219,9 @@ bool use_intermodule_correction(egEnergyCorr::ESModel model)
     case egEnergyCorr::es2017_R21_v1:
     case egEnergyCorr::es2017_R21_ofc0_v1:
     case egEnergyCorr::es2018_R21_v0:
+    case egEnergyCorr::es2018_R21_lowmu_v0:
     case egEnergyCorr::es2018_R21_v1:
+    case egEnergyCorr::es2022_R21_Precision:
       return true;
     case egEnergyCorr::UNDEFINED:  // TODO: find better logic
       return false;
@@ -251,7 +266,9 @@ bool is_run2(egEnergyCorr::ESModel model)
     case egEnergyCorr::es2017_R21_v1:
     case egEnergyCorr::es2017_R21_ofc0_v1:
     case egEnergyCorr::es2018_R21_v0:
+    case egEnergyCorr::es2018_R21_lowmu_v0:
     case egEnergyCorr::es2018_R21_v1:
+    case egEnergyCorr::es2022_R21_Precision:
       return true;
     case egEnergyCorr::UNDEFINED:  // TODO: find better logic
       return false;
@@ -289,7 +306,10 @@ EgammaCalibrationAndSmearingTool::EgammaCalibrationAndSmearingTool(const std::st
   declareProperty("useLayer2Recalibration", m_useLayer2Recalibration = AUTO);
   declareProperty("useIntermoduleCorrection", m_useIntermoduleCorrection = AUTO);
   declareProperty("usePhiUniformCorrection", m_usePhiUniformCorrection = AUTO);
+  declareProperty("useCaloDistPhiUnifCorrection", m_useCaloDistPhiUnifCorrection = 0);
   declareProperty("useGainCorrection", m_useGainCorrection = AUTO);
+  declareProperty("doADCLinearityCorrection", m_doADCLinearityCorrection = 0);
+  declareProperty("doLeakageCorrection", m_doLeakageCorrection = 0);
   declareProperty("autoReseed", m_auto_reseed = true);
   declareProperty("MVAfolder", m_MVAfolder = "");
   declareProperty("layerRecalibrationTune", m_layer_recalibration_tune = "");
@@ -338,7 +358,9 @@ StatusCode EgammaCalibrationAndSmearingTool::initialize() {
   else if (m_ESModel == "es2017_R21_v1") {m_TESModel = egEnergyCorr::es2017_R21_v1;}
   else if (m_ESModel == "es2017_R21_ofc0_v1") {m_TESModel = egEnergyCorr::es2017_R21_ofc0_v1;}
   else if (m_ESModel == "es2018_R21_v0") {m_TESModel = egEnergyCorr::es2018_R21_v0;}
+  else if (m_ESModel == "es2018_R21_lowmu_v0") {m_TESModel = egEnergyCorr::es2018_R21_lowmu_v0;}
   else if (m_ESModel == "es2018_R21_v1") {m_TESModel = egEnergyCorr::es2018_R21_v1;}
+  else if (m_ESModel == "es2022_R21_Precision") {m_TESModel = egEnergyCorr::es2022_R21_Precision;}
   else if (m_ESModel.empty()) {
     ATH_MSG_ERROR("you must set ESModel property");
     return StatusCode::FAILURE;
@@ -507,8 +529,43 @@ StatusCode EgammaCalibrationAndSmearingTool::initialize() {
     m_useGainCorrection = bool(m_gain_tool);
   }
   else if (m_useGainCorrection == 1) {
-    m_useGainCorrection = 0;
-    ATH_MSG_ERROR("cannot instantiate gain tool for this model (you can only disable the gain tool, but not enable it)");
+    if (m_TESModel != egEnergyCorr::es2022_R21_Precision) {
+      m_useGainCorrection = 0;
+      ATH_MSG_WARNING("cannot instantiate gain tool for this model (you can only disable the gain tool, but not enable it)");
+    } else {
+      ATH_MSG_DEBUG("initializing gain tool for run2 final precision recommendations");
+      std::string gain_tool_run_2_filename =
+	PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v25/gain_uncertainty_specialRun.root");
+      m_gain_tool_run2.reset(new egGain::GainUncertainty(gain_tool_run_2_filename,"GainCorrection"));
+      m_gain_tool_run2->msg().setLevel(this->msg().level());
+      m_rootTool->setApplyL2GainCorrection();
+    }
+  }
+
+  if (m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+    // ADC non linearity correction
+    if (m_doADCLinearityCorrection == 1) {
+      std::string adcLinearityCorr_filename =
+	PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v25/linearity_ADC.root");
+      m_ADCLinearity_tool.reset(new LinearityADC(adcLinearityCorr_filename));
+      m_ADCLinearity_tool->msg().setLevel(this->msg().level());
+      m_rootTool->setADCTool(m_ADCLinearity_tool);
+    }
+
+    // Leakage correction : the true argument is for pT interpolation
+    if (m_doLeakageCorrection == 1) {
+      m_rootTool->setApplyLeakageCorrection(true);
+    }
+
+    // Calo distortion phi unif correction
+    if (m_useCaloDistPhiUnifCorrection == 1) {
+      std::string phiUnifCorrfileName =
+	PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v25/egammaEnergyCorrectionData.root");
+      std::unique_ptr<TFile> fCorr(TFile::Open(phiUnifCorrfileName.c_str(), "READ"));
+      m_caloDistPhiUnifCorr.reset(
+	dynamic_cast<TH2*>(fCorr->Get("CaloDistortionPhiUniformityCorrection/es2022_R21_Precision/h2DcorrPhiUnif")));
+      m_caloDistPhiUnifCorr->SetDirectory(nullptr);
+    }
   }
 
   //No scale correction for release 21 ==> obsolete
@@ -525,7 +582,10 @@ StatusCode EgammaCalibrationAndSmearingTool::initialize() {
   ATH_MSG_INFO("layer2 recalibration = " << m_useLayer2Recalibration);
   ATH_MSG_INFO("intermodule correction = " << m_useIntermoduleCorrection);
   ATH_MSG_INFO("phi uniformity correction = " << m_usePhiUniformCorrection);
+  ATH_MSG_INFO("distorted calo phi uniformity correction = " << m_useCaloDistPhiUnifCorrection);
   ATH_MSG_INFO("gain correction = " << m_useGainCorrection);
+  ATH_MSG_INFO("ADC non-linearity correction = " << m_doADCLinearityCorrection);
+  ATH_MSG_INFO("leakage correction for photons = " << m_doLeakageCorrection);
   ATH_MSG_INFO("smearing = " << m_doSmearing);
   ATH_MSG_INFO("insitu scales = " << m_doScaleCorrection);
   ATH_MSG_INFO("ep combination = " << m_use_ep_combination);
@@ -819,29 +879,70 @@ CP::CorrectionCode EgammaCalibrationAndSmearingTool::applyCorrection(xAOD::Egamm
     // Crack calibation correction for es2011c (calibration hits calibration)
     const auto ptype = xAOD2ptype(input);
     const double etaden = ptype == PATCore::ParticleType::Electron ? static_cast<xAOD::Electron&>(input).trackParticle()->eta() : input.caloCluster()->eta();
-    energy *= m_rootTool->applyMCCalibration( input.caloCluster()->eta(), energy / cosh(etaden), ptype);
+    energy *= m_rootTool->applyMCCalibration( input.caloCluster()->eta(), energy / std::cosh(etaden), ptype);
     ATH_MSG_DEBUG("energy after crack calibration es2011c = " << boost::format("%.2f") % energy);
   }
 
   // apply uniformity correction
-  if (dataType == PATCore::ParticleDataType::Data and m_useIntermoduleCorrection) {
-    energy = intermodule_correction(energy, input.caloCluster()->phi(), input.caloCluster()->eta());
-    ATH_MSG_DEBUG("energy after intermodule correction = " << boost::format("%.2f") % energy);
-  }
+  if (dataType == PATCore::ParticleDataType::Data) {
 
-  if (dataType == PATCore::ParticleDataType::Data and m_usePhiUniformCorrection) {
-    energy *= correction_phi_unif(xAOD::get_eta_calo(*input.caloCluster(), input.author(), false),
-                                  xAOD::get_phi_calo(*input.caloCluster(), input.author(), false));
-    ATH_MSG_DEBUG("energy after uniformity correction = " << boost::format("%.2f") % energy);
-  }
-
-  // apply gain correction
-  if (dataType == PATCore::ParticleDataType::Data and m_gain_tool)
-  {
     const auto cl_eta = input.caloCluster()->eta();
-    const auto es2 = input.caloCluster()->isAvailable<double>("correctedcl_Es2") ? input.caloCluster()->auxdataConst<double>("correctedcl_Es2") : input.caloCluster()->energyBE(2);
-    if (!(std::abs(cl_eta) < 1.52 and std::abs(cl_eta) > 1.37) and std::abs(cl_eta) < 2.4)
-    energy = m_gain_tool->CorrectionGainTool(cl_eta, energy / GeV, es2 / GeV, xAOD2ptype(input)); // cl_eta ok, TODO: check corrected E2
+    double etaCalo = 0, phiCalo = 0;
+    if (m_ADCLinearity_tool || m_gain_tool_run2 || m_usePhiUniformCorrection) {
+      etaCalo = xAOD::get_eta_calo(*input.caloCluster(),input.author(),false);
+      if (m_usePhiUniformCorrection) {
+	phiCalo = xAOD::get_phi_calo(*input.caloCluster(),input.author(),false);
+      }
+    }
+
+    // Intermodule
+    if (m_useIntermoduleCorrection) {
+      energy = intermodule_correction(energy, input.caloCluster()->phi(), cl_eta);
+      ATH_MSG_DEBUG("energy after intermodule correction = " << boost::format("%.2f") % energy);
+    }
+
+    // Calo distortion
+    if (m_TESModel == egEnergyCorr::es2022_R21_Precision &&
+	m_useCaloDistPhiUnifCorrection) {
+      double etaC = input.caloCluster()->eta();
+      double phiC = input.caloCluster()->phi();
+      int ieta = m_caloDistPhiUnifCorr->GetXaxis()->FindBin(etaC);
+      ieta = ieta == 0 ? 1 :
+	(ieta > m_caloDistPhiUnifCorr->GetNbinsX() ?
+	 m_caloDistPhiUnifCorr->GetNbinsX() : ieta);
+      int iphi = m_caloDistPhiUnifCorr->GetYaxis()->FindBin(phiC);
+      iphi = iphi == 0 ? 1 :
+	(iphi > m_caloDistPhiUnifCorr->GetNbinsY() ?
+	 m_caloDistPhiUnifCorr->GetNbinsY() : iphi);
+      energy *= m_caloDistPhiUnifCorr->GetBinContent(ieta,iphi);
+      ATH_MSG_DEBUG("energy after phi uniformity correction (for calo distortion) = "
+		    << boost::format("%.2f") % energy);
+    }
+
+    // Phi
+    if (m_usePhiUniformCorrection) {
+      energy *= correction_phi_unif(etaCalo,phiCalo);
+      ATH_MSG_DEBUG("energy after uniformity correction = " << boost::format("%.2f") % energy);
+    }
+
+    // ADC
+    if (m_ADCLinearity_tool) {
+      double et   = energy / std::cosh(cl_eta);
+      double corr = m_ADCLinearity_tool->getCorr(etaCalo,et,xAOD2ptype(input));
+      energy *= corr;
+      ATH_MSG_DEBUG("energy after ADC linearity correction = " << boost::format("%.2f") % energy);
+    }
+
+    // Gain
+    if (m_gain_tool) {
+      const auto es2 = input.caloCluster()->isAvailable<double>("correctedcl_Es2") ? input.caloCluster()->auxdataConst<double>("correctedcl_Es2") : input.caloCluster()->energyBE(2);
+      if (!(std::abs(cl_eta) < 1.52 and std::abs(cl_eta) > 1.37) and std::abs(cl_eta) < 2.4)
+	energy = m_gain_tool->CorrectionGainTool(cl_eta, energy / GeV, es2 / GeV, xAOD2ptype(input)); // cl_eta ok, TODO: check corrected E2
+    } else if (m_gain_tool_run2) {
+      double et   = energy / std::cosh(cl_eta);
+      double corr = m_gain_tool_run2->getUncertainty(etaCalo,et,xAOD2ptype(input));
+      energy /= (1+corr);
+    }
     ATH_MSG_DEBUG("energy after gain correction = " << boost::format("%.2f") % energy);
   }
 
@@ -869,12 +970,13 @@ CP::CorrectionCode EgammaCalibrationAndSmearingTool::applyCorrection(xAOD::Egamm
       runNumber_for_tool = m_user_random_run_number;
     }
   }
-
-  if (dataType == PATCore::ParticleDataType::Fast) ATH_MSG_DEBUG("is fast");
+    m_rootTool->setRunnumber(runNumber_for_tool);
+    
+  if      (dataType == PATCore::ParticleDataType::Fast) ATH_MSG_DEBUG("is fast");
   else if (dataType == PATCore::ParticleDataType::Full) ATH_MSG_DEBUG("is full");
   else if (dataType == PATCore::ParticleDataType::Data) ATH_MSG_DEBUG("is data");
 
-  // apply scale factors or systematics
+  // apply scale factors (for data : in-situ alpha and leakage) or systematics
   energy = m_rootTool->getCorrectedEnergy(
              runNumber_for_tool,
              dataType,
@@ -895,7 +997,7 @@ CP::CorrectionCode EgammaCalibrationAndSmearingTool::applyCorrection(xAOD::Egamm
   const double new_energy2 = energy * energy;
   const double m2 = input.m() * input.m();
   const double p2 = new_energy2 > m2 ? new_energy2 - m2 : 0.;
-  input.setPt(sqrt(p2) / cosh(input.eta()));
+  input.setPt(sqrt(p2) / std::cosh(input.eta()));
   ATH_MSG_DEBUG("after setting pt, energy = " << input.e());
   return CP::CorrectionCode::Ok;
 }
@@ -929,7 +1031,7 @@ double EgammaCalibrationAndSmearingTool::getElectronMomentum(const xAOD::Electro
 
   // track momentum and eta
   const float el_tracketa = eTrack->eta();
-  const float el_trackmomentum = eTrack->pt() * cosh(el->eta());
+  const float el_trackmomentum = eTrack->pt() * std::cosh(el->eta());
 
   return m_rootTool->getCorrectedMomentum(dataType,
 					  PATCore::ParticleType::Electron,
@@ -955,14 +1057,116 @@ CP::SystematicSet EgammaCalibrationAndSmearingTool::affectingSystematics() const
 void EgammaCalibrationAndSmearingTool::setupSystematics() {
   const EgammaPredicate always = [](const xAOD::Egamma&) { return true; };
 
+  // Try to simplify a bit for the ones that are fully correlate in eta, whatever the model
+  // and that are not included in the macros
+  if (m_decorrelation_model_scale == ScaleDecorrelation::FULL_ETA_CORRELATED ||
+      m_decorrelation_model_scale == ScaleDecorrelation::FULL) {
+
+    // Electron leakage, ADCLin, convReco only in final run2 recommendations
+    if (m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+      // systematic related to ADC non linearity correction. Before 2022, there was not correction, nor related systematic
+      if (m_doADCLinearityCorrection) {
+	m_syst_description[CP::SystematicVariation("EG_SCALE_ADCLIN", +1)] = SysInfo{always, egEnergyCorr::Scale::ADCLinUp};
+	m_syst_description[CP::SystematicVariation("EG_SCALE_ADCLIN", -1)] = SysInfo{always, egEnergyCorr::Scale::ADCLinDown};
+      }
+
+      // Electron leakage
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LEAKAGEELEC", +1)] = SysInfo{always, egEnergyCorr::Scale::LeakageElecUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LEAKAGEELEC", -1)] = SysInfo{always, egEnergyCorr::Scale::LeakageElecDown};
+
+      // Conversion related
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVRECO", +1)] = SysInfo{always, egEnergyCorr::Scale::ConvRecoUp};
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVRECO", -1)] = SysInfo{always, egEnergyCorr::Scale::ConvRecoDown};
+    }
+    // The equivalent of convReco for other models : convefficiency and convfakerate
+    else {
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVEFFICIENCY", +1)] = SysInfo{always, egEnergyCorr::Scale::ConvEfficiencyUp};
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVEFFICIENCY", -1)] = SysInfo{always, egEnergyCorr::Scale::ConvEfficiencyDown};
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVFAKERATE", +1)]   = SysInfo{always, egEnergyCorr::Scale::ConvFakeRateUp};
+      m_syst_description[CP::SystematicVariation("PH_SCALE_CONVFAKERATE", -1)]   = SysInfo{always, egEnergyCorr::Scale::ConvFakeRateDown};
+    }
+
+    // systematic related to wtots1
+    if (m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", +1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", -1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Down};
+    }
+
+    if (m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+
+      // topo clustr threshold systematics aded to release 21 recommendations
+      m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",+1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",-1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresDown};
+
+      // and extra AF2 systematics for release 21 recommendations - Moriond 2018 - pending proper AF2 to FullSim correction with release 21
+      m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",+1)] = SysInfo{always, egEnergyCorr::Scale::af2Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",-1)] = SysInfo{always, egEnergyCorr::Scale::af2Down};
+    }
+
+    //PS correlated barrel uncertainty
+    if (m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1){
+      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", +1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", -1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Down};
+    }
+
+    // additional systematic for S12 last eta bin run2
+    if (m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2015_5TeV) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", +1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", -1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down};
+    }
+
+    // Zee stat, if for FULL we do not ask for m_use_full_statistical_error
+    if (m_decorrelation_model_scale == ScaleDecorrelation::FULL_ETA_CORRELATED or
+	!m_use_full_statistical_error) {
+      // return 1 variation only, fully correlated in eta, equal to the correct value
+      // but scaled by sqrt(number of bins)
+      // the scaling is done by the old tool
+      m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", +1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", -1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatDown};
+    }
+
+  }
+
   if (m_decorrelation_model_scale == ScaleDecorrelation::ONENP) {
     // TODO: independet implementation of ALL UP looping on all the variations
     m_syst_description[CP::SystematicVariation("EG_SCALE_ALL", +1)] = SysInfo{always, egEnergyCorr::Scale::AllUp};
     m_syst_description[CP::SystematicVariation("EG_SCALE_ALL", -1)] = SysInfo{always, egEnergyCorr::Scale::AllDown};
     // extra AF2 systematics in addition to the 1NP
-    if ( m_TESModel == egEnergyCorr::es2017_R21_v0  || m_TESModel == egEnergyCorr::es2017_R21_v1 || m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel == egEnergyCorr::es2018_R21_v1) {
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",+1)] =  SysInfo{always, egEnergyCorr::Scale::af2Up};
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",-1)] =  SysInfo{always, egEnergyCorr::Scale::af2Down};
+    if ( m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	 m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	 m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	 m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	 m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	 m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	 m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",+1)] = SysInfo{always, egEnergyCorr::Scale::af2Up};
+       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",-1)] = SysInfo{always, egEnergyCorr::Scale::af2Down};
     }
   }
   else if (m_decorrelation_model_scale == ScaleDecorrelation::FULL_ETA_CORRELATED) {
@@ -972,81 +1176,79 @@ void EgammaCalibrationAndSmearingTool::setupSystematics() {
     #define SYSMACRO(name, fullcorrelated, decorrelation, flagup, flagdown) \
       m_syst_description[CP::SystematicVariation(#name, +1)] = SysInfo{always, flagup}; \
       m_syst_description[CP::SystematicVariation(#name, -1)] = SysInfo{always, flagdown};
-    #include "ElectronPhotonFourMomentumCorrection/systematics.def"
+    #include "ElectronPhotonFourMomentumCorrection/systematics_S12_2022.def"
     #undef SYSMACRO
-    
-    // Zee stat is not included in the macro list, add by hand
-    m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", +1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatUp};
-    m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", -1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatDown};
+
+    if (m_TESModel != egEnergyCorr::es2022_R21_Precision) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB",+1)] = SysInfo{always, egEnergyCorr::Scale::LArCalibUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB",-1)] = SysInfo{always, egEnergyCorr::Scale::LArCalibDown};
+    }
 
     // additional systematics for S12 run2
-    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or m_TESModel == egEnergyCorr::es2015PRE or
-        m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or
-        m_TESModel == egEnergyCorr::es2016PRE or m_TESModel == egEnergyCorr::es2017 or 
-	m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved
-	or m_TESModel == egEnergyCorr::es2015_5TeV) {
+    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or
+	m_TESModel == egEnergyCorr::es2015PRE or
+        m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
+        m_TESModel == egEnergyCorr::es2016PRE or
+	m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2015_5TeV) {
       m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE", +1)] = SysInfo{always, egEnergyCorr::Scale::LArCalibExtra2015PreUp};
       m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE", -1)] = SysInfo{always, egEnergyCorr::Scale::LArCalibExtra2015PreDown};
     }
 
     // additional systematics for temperature run1->run2
-    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or m_TESModel == egEnergyCorr::es2015PRE or
-        m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or
+    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or
+	m_TESModel == egEnergyCorr::es2015PRE or
+        m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
         m_TESModel == egEnergyCorr::es2016PRE) {
       m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE", +1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2015PreUp};
       m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE", -1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2015PreDown};
-    }
-
-    // additional systematic for S12 last eta bin run2
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2015_5TeV) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", +1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", -1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down};
+      // additional systematic for temperature 2015->2016
+      if (m_TESModel == egEnergyCorr::es2016PRE) {
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE", +1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2016PreUp};
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE", -1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2016PreDown};
+      }
     }
 
     // additional systematic for PP0 region
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or  m_TESModel == egEnergyCorr::es2018_R21_v1) {
+    if (m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
       m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0", +1)] = SysInfo{always, egEnergyCorr::Scale::MatPP0Up};
       m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0", -1)] = SysInfo{always, egEnergyCorr::Scale::MatPP0Down};
     }
 
-    // systematic related to wtots1
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or  m_TESModel == egEnergyCorr::es2018_R21_v1 ) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", +1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", -1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Down};
-    }
-
     // systematic for the scintillators
-    if (m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or m_TESModel == egEnergyCorr::es2016PRE or m_TESModel == egEnergyCorr::es2017
-      or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or  m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1) {
-      // scintillator systematics
+    if (m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
+	m_TESModel == egEnergyCorr::es2016PRE or
+	m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
       m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR", +1)] = SysInfo{always, egEnergyCorr::Scale::E4ScintillatorUp};
       m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR", -1)] = SysInfo{always, egEnergyCorr::Scale::E4ScintillatorDown};
     }
-
-    // additional systematic for temperature 2015->2016
-    if (m_TESModel == egEnergyCorr::es2016PRE) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE", +1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2016PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE", -1)] = SysInfo{always, egEnergyCorr::Scale::LArTemperature2016PreDown};
-    }
-    
-    //PS correlated barrel uncertainty
-    if (m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1){
-      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", +1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Up}; 
-      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", -1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Down}; 
-    }
-    
-    // topo clustr threshold systematics aded to release 21 recommendations
-    if ( m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1){
-       m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",+1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresUp};
-       m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",-1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresDown};
-    }
-
-    // extra AF2 systematics for release 21 recommendations - Moriond 2018 - pending proper AF2 to FullSim correction with release 21
-    if ( m_TESModel == egEnergyCorr::es2017_R21_v0 || m_TESModel == egEnergyCorr::es2017_R21_v1 || m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0  ||  m_TESModel ==  egEnergyCorr::es2018_R21_v1){
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",+1)] =  SysInfo{always, egEnergyCorr::Scale::af2Up};
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",-1)] =  SysInfo{always, egEnergyCorr::Scale::af2Down};
-    }
-   
     
   }
   else if (m_decorrelation_model_scale == ScaleDecorrelation::ONENP_PLUS_UNCONR) {
@@ -1070,22 +1272,39 @@ void EgammaCalibrationAndSmearingTool::setupSystematics() {
     typedef std::vector<std::pair<double, double>> pairvector;
     const pairvector decorrelation_bins_BE = {{0., 1.45}, {1.52, 2.5}};
     const std::vector<double> decorrelation_edges_TWELVE = {0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4};
-    const std::vector<double> decorrelation_edges_MODULE = {0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.37, 1.52, 1.8};
+    std::vector<double> decorrelation_edges_MODULE = {0., 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.37, 1.52, 1.8};
     const std::vector<double> decorrelation_edges_MATERIAL = {0.0, 1.1, 1.5, 2.1, 2.5};
 
     std::vector<double> decorrelation_edges_S12;
     // for es2018_R21_v1 : 4 eta bins for muon E1/E2 uncertainty correlation
-    if (m_TESModel==  egEnergyCorr::es2018_R21_v1) {
-       decorrelation_edges_S12.resize(5);
-       decorrelation_edges_S12={0.,1.35,1.5,2.4,2.5};
-     }
-     // for previous run 2 muon calibration with 20.7, 5 eta bins for E1/E2 uncertainty correlation
-     else {
-       decorrelation_edges_S12.resize(6);
-       decorrelation_edges_S12={0., 0.6, 1.4, 1.5, 2.4, 2.5};
-     }
-
-    if(m_TESModel != egEnergyCorr::es2017_summer_final and m_TESModel != egEnergyCorr::es2017_R21_v0 and m_TESModel != egEnergyCorr::es2017_R21_v1 and m_TESModel != egEnergyCorr::es2017_R21_ofc0_v1 and m_TESModel != egEnergyCorr::es2018_R21_v0 and  m_TESModel != egEnergyCorr::es2018_R21_v1){
+    if (m_TESModel == egEnergyCorr::es2018_R21_v1) {
+      decorrelation_edges_S12.resize(5);
+      decorrelation_edges_S12={0.,1.35,1.5,2.4,2.5};
+    }
+    // full Run-2 data 7 eta bins decorrelation scheme
+    else if (m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+      decorrelation_edges_S12.resize(8);
+      decorrelation_edges_S12={0., 0.6, 1.0, 1.35, 1.5, 1.8, 2.4, 2.5};
+      //
+      // PS scale from muons, so "crack" is a bit different
+      decorrelation_edges_MODULE[7] = 1.4;
+      decorrelation_edges_MODULE[8] = 1.5;
+    }
+    else if (m_TESModel != egEnergyCorr::es2017_summer_final and
+	     m_TESModel != egEnergyCorr::es2017_R21_v0 and
+	     m_TESModel != egEnergyCorr::es2017_R21_v1 and
+	     m_TESModel != egEnergyCorr::es2017_R21_ofc0_v1 and
+	     m_TESModel != egEnergyCorr::es2018_R21_v0 and
+	     m_TESModel != egEnergyCorr::es2018_R21_lowmu_v0 ) {
+      decorrelation_edges_S12 = decorrelation_edges_TWELVE;
+    }
+    // for previous run 2 muon calibration with 20.7, 5 eta bins for E1/E2 uncertainty correlation
+    else {
+      decorrelation_edges_S12.resize(6);
+      decorrelation_edges_S12={0., 0.6, 1.4, 1.5, 2.4, 2.5};
+    }
+
+    if (m_TESModel==egEnergyCorr::es2022_R21_Precision) {
     #define SYSMACRO(name, fullcorrelated, decorrelation, flagup, flagdown)                \
     if (bool(fullcorrelated)) {                                                            \
       m_syst_description[CP::SystematicVariation(#name, +1)] = SysInfo{always, flagup};    \
@@ -1099,7 +1318,7 @@ void EgammaCalibrationAndSmearingTool::setupSystematics() {
         i += 1;                                                                            \
       }                                                                                    \
     }
-    #include "ElectronPhotonFourMomentumCorrection/systematics.def"
+    #include "ElectronPhotonFourMomentumCorrection/systematics_S12_2022.def"
     #undef SYSMACRO
     }
     else{
@@ -1132,98 +1351,110 @@ void EgammaCalibrationAndSmearingTool::setupSystematics() {
         ++i;
       }
     }
-    else {
-      // return 1 variation only, fully correlated in eta, equal to the correct value
-      // but scaled by sqrt(number of bins)
-      // the scaling is done by the old tool
-      m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", +1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_ZEESTAT", -1)] = SysInfo{always, egEnergyCorr::Scale::ZeeStatDown};
-    }
 
     // additional systematics for S12 run2
-    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or m_TESModel == egEnergyCorr::es2015PRE or
-        m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or
-        m_TESModel == egEnergyCorr::es2016PRE or m_TESModel == egEnergyCorr::es2017
-	or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved
-	or m_TESModel == egEnergyCorr::es2015_5TeV) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN0", +1)] = SysInfo{AbsEtaCaloPredicateFactory({0, 1.45}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN0", -1)] = SysInfo{AbsEtaCaloPredicateFactory({0, 1.45}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN1", +1)] = SysInfo{AbsEtaCaloPredicateFactory({1.45, 2.47}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN1", -1)] = SysInfo{AbsEtaCaloPredicateFactory({1.45, 2.47}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN2", +1)] = SysInfo{AbsEtaCaloPredicateFactory({2.47, 3.2}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN2", -1)] = SysInfo{AbsEtaCaloPredicateFactory({2.47, 3.2}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
+    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or
+	m_TESModel == egEnergyCorr::es2015PRE or
+        m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
+        m_TESModel == egEnergyCorr::es2016PRE or
+	m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2015_5TeV) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN0", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({0, 1.45}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN0", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({0, 1.45}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN1", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({1.45, 2.47}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN1", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({1.45, 2.47}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN2", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({2.47, 3.2}), egEnergyCorr::Scale::LArCalibExtra2015PreUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARCALIB_EXTRA2015PRE__ETABIN2", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory({2.47, 3.2}), egEnergyCorr::Scale::LArCalibExtra2015PreDown};
     }
 
     // additional systematics for temperature run1->run2
-    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or m_TESModel == egEnergyCorr::es2015PRE or
-        m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or
+    if (m_TESModel == egEnergyCorr::es2015PRE_res_improved or
+	m_TESModel == egEnergyCorr::es2015PRE or
+        m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
         m_TESModel == egEnergyCorr::es2016PRE) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN0", +1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2015PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN0", -1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2015PreDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN1", +1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2015PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN1", -1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2015PreDown};
-    }
-
-    // additional systematic for S12 last eta bin run2
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2015_5TeV) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", +1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_S12EXTRALASTETABINRUN2", -1)] = SysInfo{always, egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN0", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2015PreUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN0", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2015PreDown};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN1", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2015PreUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__ETABIN1", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2015PreDown};
+      // additional systematic for temperature 2015->2016
+      if (m_TESModel == egEnergyCorr::es2016PRE) {
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN0", +1)] =
+	  SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2016PreUp};
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN1", +1)] =
+	  SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2016PreUp};
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN0", -1)] =
+	  SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2016PreDown};
+	m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN1", -1)] =
+	  SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2016PreDown};
+      }
     }
 
     // additional systematic for PP0 region
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or  m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN0", +1)] = SysInfo{AbsEtaCaloPredicateFactory(0, 1.5), egEnergyCorr::Scale::MatPP0Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN1", +1)] = SysInfo{AbsEtaCaloPredicateFactory(1.5, 2.5), egEnergyCorr::Scale::MatPP0Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN0", -1)] = SysInfo{AbsEtaCaloPredicateFactory(0, 1.5), egEnergyCorr::Scale::MatPP0Down};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN1", -1)] = SysInfo{AbsEtaCaloPredicateFactory(1.5, 2.5), egEnergyCorr::Scale::MatPP0Down};
-    }
-
-    // systematic related to wtots1
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", +1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Up};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_WTOTS1", -1)] = SysInfo{always, egEnergyCorr::Scale::Wtots1Down};
+    if (m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN0", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(0, 1.5), egEnergyCorr::Scale::MatPP0Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN1", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.5, 2.5), egEnergyCorr::Scale::MatPP0Up};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN0", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(0, 1.5), egEnergyCorr::Scale::MatPP0Down};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_MATPP0__ETABIN1", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.5, 2.5), egEnergyCorr::Scale::MatPP0Down};
     }
 
     // systematic for the scintillators
-    if (m_TESModel == egEnergyCorr::es2015cPRE or m_TESModel == egEnergyCorr::es2015c_summer or m_TESModel == egEnergyCorr::es2016PRE or m_TESModel == egEnergyCorr::es2017
-    or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or  m_TESModel == egEnergyCorr::es2018_R21_v1) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN0", +1)] = SysInfo{AbsEtaCaloPredicateFactory(1.4, 1.46), egEnergyCorr::Scale::E4ScintillatorUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN1", +1)] = SysInfo{AbsEtaCaloPredicateFactory(1.46, 1.52), egEnergyCorr::Scale::E4ScintillatorUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN2", +1)] = SysInfo{AbsEtaCaloPredicateFactory(1.52, 1.6), egEnergyCorr::Scale::E4ScintillatorUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN0", -1)] = SysInfo{AbsEtaCaloPredicateFactory(1.4, 1.46), egEnergyCorr::Scale::E4ScintillatorDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN1", -1)] = SysInfo{AbsEtaCaloPredicateFactory(1.46, 1.52), egEnergyCorr::Scale::E4ScintillatorDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN2", -1)] = SysInfo{AbsEtaCaloPredicateFactory(1.52, 1.6), egEnergyCorr::Scale::E4ScintillatorDown};
-
-    }
-
-    // additional systematic for temperature 2015->2016
-    if (m_TESModel == egEnergyCorr::es2016PRE) {
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN0", +1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2016PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN1", +1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2016PreUp};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN0", -1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[0]), egEnergyCorr::Scale::LArTemperature2016PreDown};
-      m_syst_description[CP::SystematicVariation("EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__ETABIN1", -1)] = SysInfo{AbsEtaCaloPredicateFactory(decorrelation_bins_BE[1]), egEnergyCorr::Scale::LArTemperature2016PreDown};
+    if (m_TESModel == egEnergyCorr::es2015cPRE or
+	m_TESModel == egEnergyCorr::es2015c_summer or
+	m_TESModel == egEnergyCorr::es2016PRE or
+	m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN0", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.4, 1.46), egEnergyCorr::Scale::E4ScintillatorUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN1", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.46, 1.52), egEnergyCorr::Scale::E4ScintillatorUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN2", +1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.52, 1.6), egEnergyCorr::Scale::E4ScintillatorUp};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN0", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.4, 1.46), egEnergyCorr::Scale::E4ScintillatorDown};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN1", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.46, 1.52), egEnergyCorr::Scale::E4ScintillatorDown};
+      m_syst_description[CP::SystematicVariation("EG_SCALE_E4SCINTILLATOR__ETABIN2", -1)] =
+	SysInfo{AbsEtaCaloPredicateFactory(1.52, 1.6), egEnergyCorr::Scale::E4ScintillatorDown};
     }
-
-    //PS correlated barrel uncertainty 
-    if (m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1){ 
-      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", +1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Up};  
-      m_syst_description[CP::SystematicVariation("EG_SCALE_PS_BARREL_B12", -1)] = SysInfo{always, egEnergyCorr::Scale::PSb12Down};  
-    }
-
-    // topo clustr threshold systematics aded to release 21 recommendations
-    if ( m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1){
-       m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",+1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresUp};
-       m_syst_description[CP::SystematicVariation("EG_SCALE_TOPOCLUSTER_THRES",-1)] = SysInfo{always, egEnergyCorr::Scale::topoClusterThresDown};
-    }
-
-    // extra AF2 systematics for release 21 recommendations - Moriond 2018 - pending proper AF2 to FullSim correction with release 21
-    if ( m_TESModel == egEnergyCorr::es2017_R21_v0  || m_TESModel == egEnergyCorr::es2017_R21_v1 ||  m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel ==  egEnergyCorr::es2018_R21_v1){
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",+1)] =  SysInfo{always, egEnergyCorr::Scale::af2Up};
-       m_syst_description[CP::SystematicVariation("EG_SCALE_AF2",-1)] =  SysInfo{always, egEnergyCorr::Scale::af2Down};
-    }
-
-
-    
   }
   else {
     ATH_MSG_FATAL("scale decorrelation model invalid");
@@ -1249,12 +1480,28 @@ void EgammaCalibrationAndSmearingTool::setupSystematics() {
     m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_MATERIALCRYO", -1)] = egEnergyCorr::Resolution::MaterialCryoDown;
     m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_PILEUP", +1)] = egEnergyCorr::Resolution::PileUpUp;
     m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_PILEUP", -1)] = egEnergyCorr::Resolution::PileUpDown;
-    if (m_TESModel == egEnergyCorr::es2017 or m_TESModel == egEnergyCorr::es2017_summer or m_TESModel == egEnergyCorr::es2017_summer_improved or m_TESModel == egEnergyCorr::es2017_summer_final or m_TESModel == egEnergyCorr::es2015_5TeV or m_TESModel == egEnergyCorr::es2017_R21_v0 or m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or m_TESModel == egEnergyCorr::es2018_R21_v0 or m_TESModel == egEnergyCorr::es2018_R21_v1) {
+    if (m_TESModel == egEnergyCorr::es2017 or
+	m_TESModel == egEnergyCorr::es2017_summer or
+	m_TESModel == egEnergyCorr::es2017_summer_improved or
+	m_TESModel == egEnergyCorr::es2017_summer_final or
+	m_TESModel == egEnergyCorr::es2015_5TeV or
+	m_TESModel == egEnergyCorr::es2017_R21_v0 or
+	m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	m_TESModel == egEnergyCorr::es2022_R21_Precision) {
       m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_MATERIALIBL", +1)] = egEnergyCorr::Resolution::MaterialIBLUp;
       m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_MATERIALIBL", -1)] = egEnergyCorr::Resolution::MaterialIBLDown;
       m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_MATERIALPP0", +1)] = egEnergyCorr::Resolution::MaterialPP0Up;
       m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_MATERIALPP0", -1)] = egEnergyCorr::Resolution::MaterialPP0Down;
-      if (m_TESModel == egEnergyCorr::es2017_R21_v1 || m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 ||  m_TESModel == egEnergyCorr::es2018_R21_v1) {
+      if (m_TESModel == egEnergyCorr::es2017_R21_v1 or
+	  m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 or
+	  m_TESModel == egEnergyCorr::es2018_R21_v0 or
+	  m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 or
+	  m_TESModel == egEnergyCorr::es2018_R21_v1 or
+	  m_TESModel == egEnergyCorr::es2022_R21_Precision) {
         m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_AF2", +1)] = egEnergyCorr::Resolution::af2Up;
         m_syst_description_resolution[CP::SystematicVariation("EG_RESOLUTION_AF2", -1)] = egEnergyCorr::Resolution::af2Down;
       }
@@ -1326,7 +1573,7 @@ double EgammaCalibrationAndSmearingTool::intermodule_correction(double Ecl,  dou
   int DivInt = 0;
   double pi = 3.1415926535897932384626433832795 ;
 
-  if ( m_TESModel == egEnergyCorr::es2017_summer_improved || m_TESModel == egEnergyCorr::es2017_summer_final || m_TESModel == egEnergyCorr::es2017_R21_v0 || m_TESModel == egEnergyCorr::es2017_R21_v1 || m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel == egEnergyCorr::es2018_R21_v1) {
+  if ( m_TESModel == egEnergyCorr::es2017_summer_improved || m_TESModel == egEnergyCorr::es2017_summer_final || m_TESModel == egEnergyCorr::es2017_R21_v0 || m_TESModel == egEnergyCorr::es2017_R21_v1 || m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 || m_TESModel == egEnergyCorr::es2018_R21_v1 || m_TESModel == egEnergyCorr::es2022_R21_Precision) {
     
     double phi_mod = 0;
     if (phi < 0)
@@ -1335,7 +1582,7 @@ double EgammaCalibrationAndSmearingTool::intermodule_correction(double Ecl,  dou
       phi_mod = fmod(phi, 2 * pi / 16.);
     
     //  The correction concerns only the barrel
-    if(fabs(eta) <= 1.37){
+    if(std::abs(eta) <= 1.37){
       
       if(phi< (-7 * pi / 8) && phi> (-1 * pi))
 	Ecl_corr = Ecl / (1-0.1086 * ((1 / (1 + exp((phi_mod- 2*pi/32.) * 175.2759))) * (1 / (1 + exp((phi_mod- 2*pi/32.) * (-189.3612))))));
@@ -1391,7 +1638,7 @@ double EgammaCalibrationAndSmearingTool::intermodule_correction(double Ecl,  dou
     if (phi_mod < 0) phi_mod += pi / 8.;
     
     //  The correction concerns only the barrel
-    if(fabs(eta) <= 1.4){
+    if(std::abs(eta) <= 1.4){
       
       //  Top quarter
       if(phi < (3 * pi) / 4. && phi >= pi / 4.){
@@ -1435,7 +1682,7 @@ double EgammaCalibrationAndSmearingTool::correction_phi_unif(double eta, double
     }
   }
   
-  if ( m_TESModel == egEnergyCorr::es2017_summer_improved || m_TESModel == egEnergyCorr::es2017_summer_final || m_TESModel == egEnergyCorr::es2017_R21_v0 || m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel == egEnergyCorr::es2018_R21_v1) {
+  if ( m_TESModel == egEnergyCorr::es2017_summer_improved || m_TESModel == egEnergyCorr::es2017_summer_final || m_TESModel == egEnergyCorr::es2017_R21_v0 || m_TESModel == egEnergyCorr::es2017_R21_v1 or m_TESModel == egEnergyCorr::es2017_R21_ofc0_v1 || m_TESModel == egEnergyCorr::es2018_R21_v0 || m_TESModel == egEnergyCorr::es2018_R21_lowmu_v0 || m_TESModel == egEnergyCorr::es2018_R21_v1 || m_TESModel == egEnergyCorr::es2022_R21_Precision) {
 
     if(eta < 0.2 && eta > 0.) {
       if (phi < (-7 * 2 * PI / 32.) && phi > (-8 * 2 * PI / 32.)) { Fcorr = 1.016314; }
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaFactory.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaFactory.cxx
index 8f30379b96cd8518190d33e063ec8f3533df5774..a0ab1d7bca1a16d36267c1ac0b7ef497a2140bf9 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaFactory.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/EgammaFactory.cxx
@@ -194,11 +194,11 @@ xAOD::Photon* EgammaFactory::create_converted_photon(float eta, float phi, float
 {
   assert(m_histo_rconv);
   assert(m_histo_zconv);
-  const int bin = m_histo_rconv->FindBin(e / cosh(eta), std::abs(eta));
+  const int bin = m_histo_rconv->FindBin(e / std::cosh(eta), std::abs(eta));
   if (m_histo_rconv->IsBinOverflow(bin)) { return create_photon(eta, phi, e, 0, 0); }
   else {
     const double rconv = m_histo_rconv->GetBinContent(bin);
-    const double zconv = m_histo_zconv->GetBinContent(m_histo_zconv->FindBin(e / cosh(eta), std::abs(eta)));
+    const double zconv = m_histo_zconv->GetBinContent(m_histo_zconv->FindBin(e / std::cosh(eta), std::abs(eta)));
     assert(rconv > 0);
     return create_photon(eta, phi, e, rconv, zconv);
   }
@@ -208,13 +208,13 @@ xAOD::Photon* EgammaFactory::create_converted_photon(float eta, float phi, float
 xAOD::Photon* EgammaFactory::create_photon(float eta, float phi, float e, float rconv, float zconv)
 {
   const bool isconv = (rconv > 0 and rconv < 800);
-  const auto l = get_layers_fraction(isconv ? m_histos_conv : m_histos_unconv, eta, e / cosh(eta));
+  const auto l = get_layers_fraction(isconv ? m_histos_conv : m_histos_unconv, eta, e / std::cosh(eta));
   return create_photon(eta, phi, l[0] * e, l[1] * e, l[2] * e, l[3] * e, e, rconv, zconv);
 }
 
 xAOD::Electron* EgammaFactory::create_electron(float eta, float phi, float e)
 {
-  const auto l = get_layers_fraction(m_histos_electron, eta, e / cosh(eta));
+  const auto l = get_layers_fraction(m_histos_electron, eta, e / std::cosh(eta));
   return create_electron(eta, phi, l[0] * e, l[1] * e, l[2] * e, l[3] * e, e);
 }
 
@@ -231,8 +231,8 @@ xAOD::Photon* EgammaFactory::create_photon(float eta, float phi, float e0, float
     vertex->setX(rconv);
     vertex->setY(0);
     // decorate with pt1, pt2
-    vertex->auxdata<float>("pt1") = e / cosh(eta) * 0.7;
-    vertex->auxdata<float>("pt2") = e / cosh(eta) * 0.3;
+    vertex->auxdata<float>("pt1") = e / std::cosh(eta) * 0.7;
+    vertex->auxdata<float>("pt2") = e / std::cosh(eta) * 0.3;
     m_vertexes->push_back(vertex);
   }
 
@@ -266,7 +266,7 @@ xAOD::Photon* EgammaFactory::create_photon(float eta, float phi, float e0, float
   ph->setEta(eta);
   ph->setPhi(phi);
   ph->setM(0);
-  ph->setPt(e / cosh(eta));
+  ph->setPt(e / std::cosh(eta));
 
   return ph;
 }
@@ -305,7 +305,7 @@ xAOD::Electron* EgammaFactory::create_electron(float eta, float phi, float e0, f
   el->setEta(eta);
   el->setPhi(phi);
   el->setM(0);
-  el->setPt(e / cosh(eta));
+  el->setPt(e / std::cosh(eta));
 
   return el;
 }
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainTool.cxx
index 0305c41717c8082df5faada78372a5e5d28e561d..8ba2ec950b00277571137c5f2c512a84568c3e2a 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainTool.cxx
@@ -256,7 +256,7 @@ namespace egGain {
       }
     }
     
-    double ets2 = energy_layer2_input/cosh(eta_input);
+    double ets2 = energy_layer2_input/std::cosh(eta_input);
     double valTO = (m_funcTO[id_eta])->Eval(ets2);
     if (valTO < 0) {
       valTO=0;
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainUncertainty.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainUncertainty.cxx
index 95ec3b083a455610481677a29799cddaefbeaf67..0157b921fbf777263acc34b100bbc35afa6b597b 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainUncertainty.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/GainUncertainty.cxx
@@ -1,83 +1,105 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <ElectronPhotonFourMomentumCorrection/GainUncertainty.h>
 #include <TH1.h>
 #include <TFile.h>
 
+template<typename TargetPtr, typename SourcePtr>
+TargetPtr
+checked_cast(SourcePtr ptr)
+{
+  static_assert(std::is_pointer<TargetPtr>::value, "attempt to cast to no ptr object");
+  static_assert(std::is_pointer<SourcePtr>::value, "attempt to cast from no ptr object");
+  if(!ptr){
+    throw std::runtime_error("Attempt to cast from nullptr");
+  }
+  TargetPtr obj = dynamic_cast<TargetPtr>(ptr);
+  if (not obj) {
+    throw std::runtime_error("failed dynamic cast for " + std::string(ptr->GetName())
+                             +" in egGain::GainUncertainty");
+  }
+  return obj;
+}
 
 namespace egGain {
 
-
 //--------------------------------------
 
-  GainUncertainty::GainUncertainty(const std::string& filename) : asg::AsgMessaging("GainUncertainty") {
+  GainUncertainty::GainUncertainty(const std::string& filename, const std::string& name) : asg::AsgMessaging(name) {
 
     ATH_MSG_INFO("opening file " << filename);
-    m_gainFile.reset( TFile::Open( filename.c_str(), "READ" ) );
-
-    if (not (m_alpha_specialGainRun = (TH1*)(m_gainFile->Get("alpha_specialGainRun")))) ATH_MSG_FATAL("cannot open histogram1");
-    if (not (m_gain_impact_Zee = (TH1*)(m_gainFile->Get("gain_impact_Zee")))) ATH_MSG_FATAL("cannot open histogram2");
-    for (int i=0;i<m_NUM_ETA_BINS;i++) {
-     char name[60];
-     sprintf(name,"gain_Impact_elec_%d",i);
-     if (not (m_gain_Impact_elec[i] = (TH1*)(m_gainFile->Get(name)))) ATH_MSG_FATAL("cannot open histogram3");
-     sprintf(name,"gain_Impact_conv_%d",i);
-     if (not (m_gain_Impact_conv[i] = (TH1*)(m_gainFile->Get(name)))) ATH_MSG_FATAL("cannot open histogram4");
-     sprintf(name,"gain_Impact_unco_%d",i);
-     if (not (m_gain_Impact_unco[i]= (TH1*)(m_gainFile->Get(name)))) ATH_MSG_FATAL("cannot open histogram5");
+    std::unique_ptr<TFile> gainFile(TFile::Open( filename.c_str(), "READ"));
+
+    m_alpha_specialGainRun.reset(checked_cast<TH1*>(gainFile->Get("alpha_specialGainRun")));
+    m_alpha_specialGainRun->SetDirectory(nullptr);
+    m_gain_impact_Zee.reset(checked_cast<TH1*>(gainFile->Get("gain_impact_Zee")));
+    m_gain_impact_Zee->SetDirectory(nullptr);
+    for (int i=0;i<s_nEtaBins;i++) {
+      char name[60];
+      sprintf(name,"gain_Impact_elec_%d",i);
+      m_gain_Impact_elec[i].reset(checked_cast<TH1*>(gainFile->Get(name)));
+      m_gain_Impact_elec[i]->SetDirectory(nullptr);
+      sprintf(name,"gain_Impact_conv_%d",i);
+      m_gain_Impact_conv[i].reset(checked_cast<TH1*>(gainFile->Get(name)));
+      m_gain_Impact_conv[i]->SetDirectory(nullptr);
+      sprintf(name,"gain_Impact_unco_%d",i);
+      m_gain_Impact_unco[i].reset(checked_cast<TH1*>(gainFile->Get(name)));
+      m_gain_Impact_unco[i]->SetDirectory(nullptr);
     }
 
   }
 
-//----------------------------------------------
-
-  GainUncertainty::~GainUncertainty() {
-      delete m_alpha_specialGainRun;
-      delete m_gain_impact_Zee;
-      for (int i=0;i<m_NUM_ETA_BINS;i++) {
-        delete m_gain_Impact_elec[i];
-        delete m_gain_Impact_conv[i];
-        delete m_gain_Impact_unco[i];
-      }
-  }
-
-//----------------------------------------------
-
-    // returns relative uncertainty on energy
-
-  double GainUncertainty::getUncertainty(double etaCalo_input, double et_input,  PATCore::ParticleType::Type ptype) const {
-       double aeta=std::fabs(etaCalo_input);
-       int ibin=-1;
-       if (aeta<0.8) ibin=0;
-       else if (aeta<1.37) ibin=1;
-       else if (aeta<1.52) ibin=2;
-       else if (aeta<1.80) ibin=3;
-       else if (aeta<2.50) ibin=4;
-       if (ibin<0) return 0.;
-       
-       //Protection needed as the histograms stops at 1 TeV
-       if(et_input>999999.) et_input = 999999.;
-       
-//       std::cout << " --- in  GainUncertainty::getUncertainty " << etaCalo_input << " " << et_input << " " << ptype << " ibin " << ibin << std::endl;
+  //----------------------------------------------
+  // returns relative uncertainty on energy
+
+  double GainUncertainty::getUncertainty(double etaCalo_input, double et_input,
+					 PATCore::ParticleType::Type ptype,
+					 bool useL2GainUncertainty) const {
+    double aeta = std::abs(etaCalo_input);
+    int ibin = -1;
+    if (aeta<0.8) ibin=0;
+    else if (aeta<1.37) ibin=1;
+    else if (aeta<1.52) ibin=2;
+    else if (aeta<1.80) ibin=3;
+    else if (aeta<2.50) ibin=4;
+    if (ibin<0) return 0.;
+
+    //Protection needed as the histograms stops at 1 TeV
+    if(et_input>999999.) et_input = 999999.;
+
+    ATH_MSG_VERBOSE("GainUncertainty::getUncertainty "
+		    << etaCalo_input << " "
+		    << et_input << " "
+		    << ptype << " ibin " << ibin);
+
+    TH1 *hImpact = nullptr;
+    if (ptype == PATCore::ParticleType::Electron)
+      hImpact = m_gain_Impact_elec[ibin].get();
+    else if (ptype == PATCore::ParticleType::ConvertedPhoton)
+      hImpact = m_gain_Impact_conv[ibin].get();
+    else if (ptype == PATCore::ParticleType::UnconvertedPhoton)
+      hImpact = m_gain_Impact_unco[ibin].get();
+    if (hImpact == nullptr) {
+      ATH_MSG_WARNING("Trying to get Gain correction of not allowed particle type");
+      return 0;
+    }
+    double impact = hImpact->GetBinContent(hImpact->FindFixBin(0.001*et_input));
 
-       double impact=0.;
-       if (ptype==PATCore::ParticleType::Electron) impact = m_gain_Impact_elec[ibin]->GetBinContent(m_gain_Impact_elec[ibin]->FindFixBin(0.001*et_input));
-       if (ptype==PATCore::ParticleType::ConvertedPhoton) impact = m_gain_Impact_conv[ibin]->GetBinContent(m_gain_Impact_conv[ibin]->FindFixBin(0.001*et_input));
-       if (ptype==PATCore::ParticleType::UnconvertedPhoton) impact = m_gain_Impact_unco[ibin]->GetBinContent(m_gain_Impact_unco[ibin]->FindFixBin(0.001*et_input));
+    int ieta = m_alpha_specialGainRun->FindFixBin(aeta);
+    double alphaG = useL2GainUncertainty ?
+      m_alpha_specialGainRun->GetBinError(ieta) :
+      m_alpha_specialGainRun->GetBinContent(ieta);
 
-//       std::cout << " impact " << impact << std::endl;
-       double_t sigmaE = m_alpha_specialGainRun->GetBinContent(m_alpha_specialGainRun->FindFixBin(aeta))
-                        /m_gain_impact_Zee->GetBinContent(m_gain_impact_Zee->FindFixBin(aeta))
-                        *impact ;
+    double impactZee = m_gain_impact_Zee->GetBinContent(m_gain_impact_Zee->FindFixBin(aeta));
 
-//       std::cout << " m_alpha_specialGainRun, m_gain_impact_Zee, impact , sigmaE " << m_alpha_specialGainRun->GetBinContent(m_alpha_specialGainRun->FindBin(aeta))
-//  << " " << m_gain_impact_Zee->GetBinContent(m_gain_impact_Zee->FindBin(aeta)) << " " << impact << " " << sigmaE << std::endl;
+    double_t sigmaE = alphaG*impact/impactZee;
 
-       return sigmaE;
+    ATH_MSG_VERBOSE("alpha_specialGainRun, gain_impact_Zee, impact, sigmaE = "
+		    << alphaG << " " << impactZee << " " << impact << " " << sigmaE);
 
+    return sigmaE;
   }
 
-
 }
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/LinearityADC.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/LinearityADC.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6a9fe8a65fb1117c97501aa38659ab88bbb81942
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/LinearityADC.cxx
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ElectronPhotonFourMomentumCorrection/LinearityADC.h"
+
+#include "TFile.h"
+
+LinearityADC::LinearityADC(const std::string& filename, const std::string& name) :
+  asg::AsgMessaging(name) 
+{
+  ATH_MSG_INFO("Initialize LinearityADC with file " << filename);
+  std::unique_ptr<TFile> adcFile(TFile::Open(filename.c_str(), "READ"));
+  static const std::map<TString,PATCore::ParticleType::Type> pN = {
+    { "elec", PATCore::ParticleType::Electron },
+    { "unco", PATCore::ParticleType::UnconvertedPhoton },
+    { "conv", PATCore::ParticleType::ConvertedPhoton } };
+  for (auto it : pN) {
+    m_hcorr[it.second].reset(dynamic_cast<TProfile2D*>(adcFile->Get(Form("linearity_%s",it.first.Data()))));
+    m_hcorr[it.second]->SetDirectory(nullptr);
+  }
+  adcFile->Close();
+}
+
+//===============================================================================
+float LinearityADC::getCorr(float etaCalo, float et, PATCore::ParticleType::Type pType) const
+{
+  float corr=0.;
+  float etGeV = et/1000.;
+  if (etGeV<6.) etGeV=6.;
+  if (etGeV>2999.) etGeV=2999.;
+
+  auto it = m_hcorr.find(pType);
+  if (it == m_hcorr.end()) {
+    ATH_MSG_ERROR("unknow particle type " << pType);
+    return 1.;
+  }
+  TProfile2D* hh = it->second.get();
+ 
+  float aeta = std::abs(etaCalo);
+  if (aeta>2.49) aeta=2.49;
+  
+  int ix = hh->GetXaxis()->FindBin(aeta);
+  int iy = hh->GetYaxis()->FindBin(etGeV);
+  float y = hh->GetYaxis()->GetBinCenter(iy);
+  int iy0,iy1;
+  if (y>etGeV) {
+    iy0 = iy-1;
+    iy1 = iy;
+  }
+  else {
+    iy0=iy;
+    iy1=iy+1;
+  }
+  
+  int iyc = hh->GetYaxis()->FindBin(40.);
+  
+  if (iy0<1)                           corr = hh->GetBinContent(ix,iy1);
+  if (iy1>hh->GetYaxis()->GetNbins())  corr = hh->GetBinContent(ix,iy0);
+  
+  float y0 = hh->GetYaxis()->GetBinCenter(iy0);
+  float y1 = hh->GetYaxis()->GetBinCenter(iy1);
+  // subtract effect for 40 GeV Et electrons
+  it = m_hcorr.find(PATCore::ParticleType::Electron);
+  float c0 = hh->GetBinContent(ix,iy0) - it->second->GetBinContent(ix,iyc);
+  float c1 = hh->GetBinContent(ix,iy1) - it->second->GetBinContent(ix,iyc);
+  
+  corr = (c1*(etGeV-y0) + c0*(y1-etGeV)) / (y1-y0);
+  ATH_MSG_VERBOSE("correction from ADC non linearity = " << corr);
+
+  return (1.+corr);
+}
+
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/e1hg_systematics.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/e1hg_systematics.cxx
index 6864be8740e34ae5c1d0782c885272e524609428..a948a7e18ed1460a42a5501fb72ac564ef2b982c 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/e1hg_systematics.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/e1hg_systematics.cxx
@@ -68,7 +68,7 @@ double e1hg_systematics::getAlpha(int particle_type, double energy, double eta,
 
 
    double energyGeV = energy*0.001;
-   double et = energyGeV/cosh(eta);
+   double et = energyGeV/std::cosh(eta);
 
    int ibinEt=m_etBins->GetSize()-2;
    for (int i=1;i<m_etBins->GetSize();i++) {
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/egammaEnergyCorrectionTool.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/egammaEnergyCorrectionTool.cxx
index 487ab4f0d86a59ba4cd6c40380c1af445fee6467..28113e0385f987db2913ba93216e2f49f8ac1dc2 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/egammaEnergyCorrectionTool.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/egammaEnergyCorrectionTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 // Dear emacs, this is -*-c++-*-
@@ -7,10 +7,8 @@
 /// Implementation of energy scale uncertainties, for 2010 data and beyond
 ///
 #include <iostream>
-#include <cassert>
 #include <exception>
-#include <iomanip>
-#include <ios>
+#include <cmath>
 
 #include <boost/format.hpp>
 
@@ -19,6 +17,7 @@
 #include "TF1.h"
 #include "TFile.h"
 #include "TList.h"
+#include "TSystem.h"
 #include "TGraphErrors.h"
 
 #include "ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h"
@@ -27,27 +26,17 @@
 #include "ElectronPhotonFourMomentumCorrection/get_MaterialResolutionEffect.h"
 #include "ElectronPhotonFourMomentumCorrection/e1hg_systematics.h"
 #include "ElectronPhotonFourMomentumCorrection/GainUncertainty.h"
-
+#include "ElectronPhotonFourMomentumCorrection/LinearityADC.h"
 
 #include "PathResolver/PathResolver.h"
 
-inline double qsum(double x, double y) { return std::hypot(x, y); }
-
-template<typename T>
-T* get_object(TFile& file, const std::string& name)
-{
-  T* obj = dynamic_cast<T*>(file.Get(name.c_str()));
-  if (not obj) { throw std::runtime_error("object " + name + " not found in file " + std::string(file.GetName())); }
-  return obj;
-}
-
 inline double getValueHistoAt(const TH1& histo, double xvalue,
 			      bool use_lastbin_overflow=false,
                               bool use_firstbin_underflow=false)
 {
   int bin = histo.FindFixBin(xvalue);
-  if (use_lastbin_overflow and histo.IsBinOverflow(bin)) { bin = histo.GetNbinsX(); }
-  if (use_firstbin_underflow and histo.IsBinUnderflow(bin)) { bin = 1; }
+  if (use_lastbin_overflow && histo.IsBinOverflow(bin)) { bin = histo.GetNbinsX(); }
+  if (use_firstbin_underflow && histo.IsBinUnderflow(bin)) { bin = 1; }
   return histo.GetBinContent(bin);
 }
 
@@ -58,11 +47,11 @@ inline double getValueHistAt(const TH2& histo, double xvalue, double yvalue,
                              bool use_firstbin_y_underflow=false)
 {
   int xbin = histo.GetXaxis()->FindFixBin(xvalue);
-  if (use_lastbin_x_overflow and xbin == histo.GetXaxis()->GetNbins() + 1) { xbin = histo.GetXaxis()->GetNbins(); }
-  if (use_fistbin_x_underflow and xbin == 0) { xbin = 1; }
+  if (use_lastbin_x_overflow && xbin == histo.GetXaxis()->GetNbins() + 1) { xbin = histo.GetXaxis()->GetNbins(); }
+  if (use_fistbin_x_underflow && xbin == 0) { xbin = 1; }
   int ybin = histo.GetYaxis()->FindFixBin(yvalue);
-  if (use_lastbin_y_overflow and ybin == histo.GetYaxis()->GetNbins() + 1) { ybin = histo.GetYaxis()->GetNbins(); }
-  if (use_firstbin_y_underflow and ybin == 0) { ybin = 1; }
+  if (use_lastbin_y_overflow && ybin == histo.GetYaxis()->GetNbins() + 1) { ybin = histo.GetYaxis()->GetNbins(); }
+  if (use_firstbin_y_underflow && ybin == 0) { ybin = 1; }
   return histo.GetBinContent(xbin, ybin);
 }
 
@@ -76,8 +65,7 @@ namespace AtlasRoot {
     m_esmodel(egEnergyCorr::UNDEFINED)
   {
 
-
-    m_rootFileName = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v24/egammaEnergyCorrectionData.root");
+    m_rootFileName = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v25/egammaEnergyCorrectionData.root");
     
     if (m_rootFileName.empty()) {
       ATH_MSG_FATAL("cannot find configuration file");
@@ -87,7 +75,6 @@ namespace AtlasRoot {
     m_begRunNumber = 0;
     m_endRunNumber = 0;
 
-
     /* 
      * All histogram vectors start empty
      */
@@ -116,6 +103,11 @@ namespace AtlasRoot {
 
     m_use_stat_error_scaling = false;
     m_initialized = false;
+
+    //
+    m_useL2GainCorrection = false;
+    m_useLeakageCorrection = false;
+    m_usepTInterpolationForLeakage = false;
   }
 
 
@@ -142,6 +134,7 @@ namespace AtlasRoot {
     // Load the ROOT filea
 
     const std::unique_ptr<char[]> fname(gSystem->ExpandPathName(m_rootFileName.c_str()));
+    std::unique_ptr<TFile> m_rootFile;
     m_rootFile.reset(TFile::Open( fname.get(), "READ" ));
 
     if ( !m_rootFile ) {
@@ -152,7 +145,7 @@ namespace AtlasRoot {
     // instantiate the resolution parametriaton
 
     //`:if (!m_getMaterialDelta)
-    m_getMaterialDelta.reset( new get_MaterialResolutionEffect());
+    m_getMaterialDelta.reset(new get_MaterialResolutionEffect());
 
 
     // Energy corrections and systematic uncertainties
@@ -198,12 +191,12 @@ namespace AtlasRoot {
       m_begRunNumber = 177531;
       m_endRunNumber = 194382;
 
-
-
       // mc11d : correct MSc in G4; new geometry
       // Final Run1 calibration scheme
 
-    } else if ( m_esmodel==egEnergyCorr::es2011d || m_esmodel==egEnergyCorr::es2011dMedium || m_esmodel==egEnergyCorr::es2011dTight ) {
+    } else if ( m_esmodel==egEnergyCorr::es2011d ||
+		m_esmodel==egEnergyCorr::es2011dMedium ||
+		m_esmodel==egEnergyCorr::es2011dTight ) {
       m_use_new_resolution_model = true;
       m_resolution_tool.reset(new eg_resolution("run1"));
       m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2011d/alphaPS_uncor")));                 m_aPSNom->SetDirectory(nullptr);
@@ -269,7 +262,6 @@ namespace AtlasRoot {
       const std::string gain_filename2 = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/FunctionsG_all.root");
       m_gain_tool.reset(new egGain::GainTool(gain_filename1, gain_filename2));
 
-
       m_e1hg_tool.reset(new e1hg_systematics());
 
       // mc12a : crude MSc fix in G4; old geometry
@@ -387,14 +379,14 @@ namespace AtlasRoot {
       m_begRunNumber = 195847;
       m_endRunNumber = 219365;
 
-
       const std::string gain_filename1 = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/FunctionsTO.root");
       const std::string gain_filename2 = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/FunctionsG_all.root");
       m_gain_tool.reset(new egGain::GainTool(gain_filename1, gain_filename2));
 
       m_e1hg_tool.reset(new e1hg_systematics());
     }
-    else if (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015cPRE) {
+    else if (m_esmodel == egEnergyCorr::es2015PRE ||
+	     m_esmodel == egEnergyCorr::es2015cPRE) {
       m_use_etaCalo_scales = true;
       m_use_new_resolution_model = true;
       m_resolution_tool.reset( new eg_resolution("run2_pre")) ;
@@ -458,7 +450,8 @@ namespace AtlasRoot {
       m_e1hg_tool.reset(new e1hg_systematics());
     }
 
-    else if (m_esmodel == egEnergyCorr::es2015PRE_res_improved or m_esmodel == egEnergyCorr::es2015cPRE_res_improved) {
+    else if (m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+	     m_esmodel == egEnergyCorr::es2015cPRE_res_improved) {
       m_use_etaCalo_scales = true;
       m_use_new_resolution_model = true;
       m_resolution_tool.reset(new eg_resolution("run2_pre"));
@@ -653,204 +646,256 @@ namespace AtlasRoot {
       m_use_temp_correction201516 = true;
     }
 
-    else if (m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved 
-             or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_PRE 
-             or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or  m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1) {//add release 21 here for now
+    else if (m_esmodel == egEnergyCorr::es2017 ||
+	     m_esmodel == egEnergyCorr::es2017_summer ||
+	     m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	     m_esmodel == egEnergyCorr::es2017_summer_final ||
+	     m_esmodel == egEnergyCorr::es2015_5TeV ||
+	     m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+             m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	     m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	     m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	     m_esmodel == egEnergyCorr::es2022_R21_Precision) { //add release 21 here for now
+
       m_use_etaCalo_scales = true;
       m_use_new_resolution_model = true;
-      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1)
+      if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2022_R21_Precision)
         m_resolution_tool.reset(new eg_resolution("run2_R21_v1"));
       else 
         m_resolution_tool.reset(new eg_resolution("run2_pre"));
-      
-      if(m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 ){
-        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaPS_uncor")));       m_aPSNom->SetDirectory(nullptr); 
-        m_daPSb12.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/dalphaPS_b12")));        m_daPSb12->SetDirectory(nullptr); 
-        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                    m_daPSCor->SetDirectory(nullptr);
-        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaS12_uncor")));      m_aS12Nom->SetDirectory(nullptr); 
-        m_daS12Cor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaS12_cor")));                   m_daS12Cor->SetDirectory(nullptr);
-      }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v1){
-        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaPS_uncor")));       m_aPSNom->SetDirectory(nullptr); 
-        m_daPSb12.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/dalphaPS_b12")));        m_daPSb12->SetDirectory(nullptr); 
-        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                    m_daPSCor->SetDirectory(nullptr);
-        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaS12_uncor")));      m_aS12Nom->SetDirectory(nullptr); 
-        m_daS12Cor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaS12_cor")));                   m_daS12Cor->SetDirectory(nullptr);
+
+      if (m_esmodel == egEnergyCorr::es2017_summer_final ||
+	  m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0) {
+        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaPS_uncor")));       m_aPSNom->SetDirectory(nullptr);
+        m_daPSb12.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/dalphaPS_b12")));       m_daPSb12->SetDirectory(nullptr);
+        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                   m_daPSCor->SetDirectory(nullptr);
+        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaS12_uncor")));     m_aS12Nom->SetDirectory(nullptr);
+        m_daS12Cor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaS12_cor")));                 m_daS12Cor->SetDirectory(nullptr);
       }
-      else{
-        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/alphaPS_uncor")));                 m_aPSNom->SetDirectory(nullptr);
-        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                  m_daPSCor->SetDirectory(nullptr);
-        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/alphaS12_uncor")));                m_aS12Nom->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v1) {
+        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaPS_uncor")));       m_aPSNom->SetDirectory(nullptr);
+        m_daPSb12.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/dalphaPS_b12")));       m_daPSb12->SetDirectory(nullptr);
+        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                   m_daPSCor->SetDirectory(nullptr);
+        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaS12_uncor")));           m_aS12Nom->SetDirectory(nullptr);
         m_daS12Cor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaS12_cor")));                 m_daS12Cor->SetDirectory(nullptr);
       }
-      m_trkSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/momentum_errSyst")));              m_trkSyst->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+	m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaPS_uncor")));      m_aPSNom->SetDirectory(nullptr);
+        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaS12_uncor")));    m_aS12Nom->SetDirectory(nullptr);
+      }
+      else {
+        m_aPSNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/alphaPS_uncor")));                   m_aPSNom->SetDirectory(nullptr);
+        m_daPSCor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaPS_cor")));                   m_daPSCor->SetDirectory(nullptr);
+        m_aS12Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/alphaS12_uncor")));                 m_aS12Nom->SetDirectory(nullptr);
+        m_daS12Cor.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/dalphaS12_cor")));                 m_daS12Cor->SetDirectory(nullptr);
+      }
+      m_trkSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2012c/momentum_errSyst")));                 m_trkSyst->SetDirectory(nullptr);
       
-      if(m_esmodel == egEnergyCorr::es2017){
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errStat_period_2016")));         m_zeeNom->SetDirectory(nullptr);
-        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errStat_period_2015")));      m_zeeNom_data2015->SetDirectory(nullptr);
+      if (m_esmodel == egEnergyCorr::es2017) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errStat_period_2016")));           m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved){
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errStat_period_2016")));         m_zeeNom->SetDirectory(nullptr); 
-        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errStat_period_2015")));      m_zeeNom_data2015->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2017_summer ||
+	       m_esmodel == egEnergyCorr::es2017_summer_improved) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errStat_period_2016")));          m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errStat_period_2015"))); m_zeeNom_data2015->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2017_summer_final){ 
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errStat_period_2016")));         m_zeeNom->SetDirectory(nullptr);  
-        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errStat_period_2015")));      m_zeeNom_data2015->SetDirectory(nullptr); 
+      else if (m_esmodel == egEnergyCorr::es2017_summer_final) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errStat_period_2016")));          m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errStat_period_2015"))); m_zeeNom_data2015->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2015_5TeV){
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2015_5TeV/alphaZee_errStat_period_2015")));         m_zeeNom->SetDirectory(nullptr);   
+      else if (m_esmodel == egEnergyCorr::es2015_5TeV) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2015_5TeV/alphaZee_errStat_period_2015")));         m_zeeNom->SetDirectory(nullptr);
         //Same histogram added twice for simplicity
         m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2015_5TeV/alphaZee_errStat_period_2015")));      m_zeeNom_data2015->SetDirectory(nullptr);
       }
       else if (m_esmodel==egEnergyCorr::es2017_R21_v0) {
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v0/alphaZee_errStat_period_2017")));  m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v0/alphaZee_errStat_period_2017")));           m_zeeNom->SetDirectory(nullptr);
         m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v0/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
         m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v0/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
       }
       else if (m_esmodel==egEnergyCorr::es2017_R21_v1) {
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errStat_period_2017")));  m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errStat_period_2017")));           m_zeeNom->SetDirectory(nullptr);
         m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
         m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
         m_zeeFwdk.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
         m_zeeFwdb.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
       }
       else if (m_esmodel==egEnergyCorr::es2017_R21_ofc0_v1) {
-        m_zeeNom.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errStat_period_2017")));  m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errStat_period_2017")));           m_zeeNom->SetDirectory(nullptr);
         m_zeeNom_data2016.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
         m_zeeNom_data2015.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
         m_zeeNom_data2018.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errStat_period_2018")));  m_zeeNom_data2018->SetDirectory(nullptr);
         m_zeeFwdk.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_v1/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
         m_zeeFwdb.reset(dynamic_cast<TH1*> (m_rootFile->Get("Scales/es2017_R21_v1/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v0){
-
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errStat_period_2018")));  m_zeeNom->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0){
+	// only 1 set of alpha for 13TEV 2018 and 2017 lowmu data (mu=2) dataset
+	m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_lowmu_v0/alphaZee_errStat")));               m_zeeNom->SetDirectory(nullptr);
+	m_zeeNom_data2017.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_lowmu_v0/alphaZee_errStat_5TeV"))); m_zeeNom_data2017->SetDirectory(nullptr);
+	m_zeeFwdk.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
+        m_zeeFwdb.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
+      }
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v0) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errStat_period_2018")));           m_zeeNom->SetDirectory(nullptr);
         m_zeeNom_data2017.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errStat_period_2017")));  m_zeeNom_data2017->SetDirectory(nullptr);
         m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
         m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
         m_zeeFwdk.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
         m_zeeFwdb.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v1) {
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2018")));  m_zeeNom->SetDirectory(nullptr);
-        m_zeeNom_data2017.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2017")));  m_zeeNom_data2017->SetDirectory(nullptr);
-        m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
-        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
+       else if (m_esmodel == egEnergyCorr::es2018_R21_v1) {
+	 m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2018")));           m_zeeNom->SetDirectory(nullptr);
+	 m_zeeNom_data2017.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2017")));  m_zeeNom_data2017->SetDirectory(nullptr);
+	 m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
+	 m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
+	 //same as in v0 model
+	 m_zeeFwdk.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
+	 m_zeeFwdb.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
+       }
+      else if (m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaZee_errStat_period_2018")));           m_zeeNom->SetDirectory(nullptr);
+        m_zeeNom_data2017.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaZee_errStat_period_2017")));  m_zeeNom_data2017->SetDirectory(nullptr);
+        m_zeeNom_data2016.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaZee_errStat_period_2016")));  m_zeeNom_data2016->SetDirectory(nullptr);
+        m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2022_R21_Precision/alphaZee_errStat_period_2015")));  m_zeeNom_data2015->SetDirectory(nullptr);
         //same as in v0 model
         m_zeeFwdk.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalk"))); m_zeeFwdk->SetDirectory(nullptr);
         m_zeeFwdb.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaFwd_Finalb"))); m_zeeFwdb->SetDirectory(nullptr);
        }
-
-      
-      else{
-        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_PRE/alphaZee_errStat_period_2016")));         m_zeeNom->SetDirectory(nullptr);  
+      else {
+        m_zeeNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_PRE/alphaZee_errStat_period_2016")));               m_zeeNom->SetDirectory(nullptr);  
         //SAME HISTO FOR 2015 FOR NOW
         m_zeeNom_data2015.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_PRE/alphaZee_errStat_period_2016")));      m_zeeNom_data2015->SetDirectory(nullptr);
       }
-      if(m_esmodel == egEnergyCorr::es2017){
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+
+      if(m_esmodel == egEnergyCorr::es2017) {
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017/alphaZee_errSyst")));                      m_zeeSyst->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2017_summer_final){
+      else if (m_esmodel == egEnergyCorr::es2017_summer_final) {
         m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2015_5TeV){
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2015_5TeV/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2015_5TeV) {
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2015_5TeV/alphaZee_errSyst")));                 m_zeeSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_v0) {
         m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer_final/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_v1) {
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_v1/alphaZee_errSyst")));               m_zeeSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1) {
          m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_R21_ofc0_v1/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v0) {
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	       m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0) {
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v0/alphaZee_errSyst")));               m_zeeSyst->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v1) {
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	       m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2018_R21_v1/alphaZee_errSyst")));               m_zeeSyst->SetDirectory(nullptr);
       }
-      else{
-        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errSyst")));         m_zeeSyst->SetDirectory(nullptr);
+      else {
+        m_zeeSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Scales/es2017_summer/alphaZee_errSyst")));               m_zeeSyst->SetDirectory(nullptr);
       }
       
       m_uA2MeV_2015_first2weeks_correction = nullptr;
       if(m_esmodel == egEnergyCorr::es2017){
         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
-      else if(m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2015_5TeV){	
+      else if(m_esmodel == egEnergyCorr::es2017_summer ||
+	      m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	      m_esmodel == egEnergyCorr::es2015_5TeV) {
         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
       else if(m_esmodel == egEnergyCorr::es2017_summer_final) {
-        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
+        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errStat")));  m_resNom->SetDirectory(nullptr);}
       else if (m_esmodel==egEnergyCorr::es2017_R21_v0) {
-         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_v0/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
+         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_v0/ctZee_errStat")));       m_resNom->SetDirectory(nullptr);}
       else if (m_esmodel==egEnergyCorr::es2017_R21_v1) {
         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_v1/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
       else if (m_esmodel==egEnergyCorr::es2017_R21_ofc0_v1) {
-        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_ofc0_v1/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
+        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_ofc0_v1/ctZee_errStat")));   m_resNom->SetDirectory(nullptr);}
       else if (m_esmodel==egEnergyCorr::es2018_R21_v0) {
         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_v0/ctZee_errStat")));        m_resNom->SetDirectory(nullptr);}
+      else if (m_esmodel==egEnergyCorr::es2018_R21_lowmu_v0) {
+	m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_lowmu_v0/ctZee_errStat")));  m_resNom->SetDirectory(nullptr);
+	m_resNom_datalowmu.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_lowmu_v0/ctZee_errStat_5TeV")));        m_resNom_datalowmu->SetDirectory(nullptr);}
       else if (m_esmodel==egEnergyCorr::es2018_R21_v1) {
-         m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_v1/ctZee_errStat")));        m_resNom->SetDirectory(nullptr); }
+	m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_v1/ctZee_errStat")));        m_resNom->SetDirectory(nullptr); }
+      else if (m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+	m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2022_R21_Precision/ctZee_errStat"))); m_resNom->SetDirectory(nullptr); }   
       else{
-        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_PRE/ctZee_errStat")));        m_resNom->SetDirectory(nullptr); 
+        m_resNom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_PRE/ctZee_errStat")));       m_resNom->SetDirectory(nullptr); 
       }
       
-      if(m_esmodel == egEnergyCorr::es2017){
-        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
+      if (m_esmodel == egEnergyCorr::es2017) {
+        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017/ctZee_errSyst")));               m_resSyst->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2017_summer_final){
-        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2017_summer_final) {
+        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errSyst")));  m_resSyst->SetDirectory(nullptr);
       }
-      else if(m_esmodel == egEnergyCorr::es2015_5TeV){
-        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2015_5TeV/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr); 
+      else if (m_esmodel == egEnergyCorr::es2015_5TeV) {
+        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2015_5TeV/ctZee_errSyst")));          m_resSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_v0) {
-         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
+         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_final/ctZee_errSyst"))); m_resSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_v1) {
         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_v1/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
       }
       else if (m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1) {
-        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_ofc0_v1/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
+        m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_R21_ofc0_v1/ctZee_errSyst")));   m_resSyst->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v0) {
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	       m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0  ) {
         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_v0/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
       }
-      else if (m_esmodel == egEnergyCorr::es2018_R21_v1) {
+      else if (m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	       m_esmodel == egEnergyCorr::es2022_R21_Precision) {
         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2018_R21_v1/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
       }
-      else{ 
+      else { 
         m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
       }
-      //else{
-      //m_resSyst.reset( dynamic_cast< TH1* >( m_rootFile->Get("Resolution/es2017_summer_improved/ctZee_errSyst")));        m_resSyst->SetDirectory(nullptr);
-      //}
       
-      m_pedestals_es2017.reset( dynamic_cast< TH1* >(m_rootFile->Get("Pedestals/es2017/pedestals")));          m_pedestals_es2017->SetDirectory(nullptr);
+      m_pedestals_es2017.reset( dynamic_cast< TH1* >(m_rootFile->Get("Pedestals/es2017/pedestals")));               m_pedestals_es2017->SetDirectory(nullptr);
 
-      m_dX_ID_Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/DX0_ConfigA")));                         m_dX_ID_Nom->SetDirectory(nullptr);
+      m_dX_ID_Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/DX0_ConfigA")));                           m_dX_ID_Nom->SetDirectory(nullptr);
 
       m_dX_IPPS_Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPPS_NewG_errUncor")));   m_dX_IPPS_Nom->SetDirectory(nullptr);
       m_dX_IPPS_LAr.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPPS_NewG_errLAr")));     m_dX_IPPS_LAr->SetDirectory(nullptr);
 
       m_dX_IPAcc_Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPAcc_NewG_errUncor")));  m_dX_IPAcc_Nom->SetDirectory(nullptr);
       m_dX_IPAcc_LAr.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPAcc_NewG_errLAr")));    m_dX_IPAcc_LAr->SetDirectory(nullptr);
-      m_dX_IPAcc_G4.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPAcc_NewG_errG4")));     m_dX_IPAcc_G4->SetDirectory(nullptr);
+      m_dX_IPAcc_G4.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPAcc_NewG_errG4")));      m_dX_IPAcc_G4->SetDirectory(nullptr);
       m_dX_IPAcc_GL1.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_IPAcc_NewG_errGL1")));    m_dX_IPAcc_GL1->SetDirectory(nullptr);
 
       m_dX_PSAcc_Nom.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_PSAcc_NewG_errUncor")));  m_dX_PSAcc_Nom->SetDirectory(nullptr);
       m_dX_PSAcc_LAr.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_PSAcc_NewG_errLAr")));    m_dX_PSAcc_LAr->SetDirectory(nullptr);
-      m_dX_PSAcc_G4.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_PSAcc_NewG_errG4")));     m_dX_PSAcc_G4->SetDirectory(nullptr);
+      m_dX_PSAcc_G4.reset( dynamic_cast< TH1* >( m_rootFile->Get("Material/Measured/DXerr_PSAcc_NewG_errG4")));      m_dX_PSAcc_G4->SetDirectory(nullptr);
 
-      m_convRadius.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRadiusMigrations")));  m_convRadius->SetDirectory(nullptr);
-      if(m_esmodel == egEnergyCorr::es2017){
-	m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convFakeRate")));          m_convFakeRate->SetDirectory(nullptr);
-	m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRecoEfficiency")));    m_convRecoEfficiency->SetDirectory(nullptr);
+      m_convRadius.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRadiusMigrations")));                      m_convRadius->SetDirectory(nullptr);
+      if (m_esmodel == egEnergyCorr::es2017) {
+	m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convFakeRate")));                          m_convFakeRate->SetDirectory(nullptr);
+	m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRecoEfficiency")));              m_convRecoEfficiency->SetDirectory(nullptr);
       }
-      else{
-	m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2017_summer/convFakeRate")));          m_convFakeRate->SetDirectory(nullptr); 
-        m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2017_summer/convRecoEfficiency")));    m_convRecoEfficiency->SetDirectory(nullptr);
+      else if (m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+	m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2022_R21_Precision/convFakeRate")));             m_convFakeRate->SetDirectory(nullptr);
+	m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2022_R21_Precision/convRecoEfficiency"))); m_convRecoEfficiency->SetDirectory(nullptr);
+      }
+      else {
+	m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2017_summer/convFakeRate")));                    m_convFakeRate->SetDirectory(nullptr);
+        m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2017_summer/convRecoEfficiency")));        m_convRecoEfficiency->SetDirectory(nullptr);
       }
       
       // TODO: change path when moving to calibarea
@@ -870,7 +915,6 @@ namespace AtlasRoot {
       //similar case for wtots1
       const std::string filename_wstot = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/wstot_related_syst.root");
       
-
       TFile file_wstot(filename_wstot.c_str());
       m_wstot_slope_A_data.reset(  dynamic_cast< TH1* >( file_wstot.Get("A_data"))); m_wstot_slope_A_data->SetDirectory(nullptr);
       m_wstot_slope_B_MC.reset(  dynamic_cast< TH1* >( file_wstot.Get("B_mc"))); m_wstot_slope_B_MC->SetDirectory(nullptr);
@@ -890,7 +934,12 @@ namespace AtlasRoot {
       m_begRunNumber = 252604;
       m_endRunNumber = 314199;
 
-      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
+      if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2022_R21_Precision) {
          m_G4OverAFII_resolution_electron.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/resol_Af2ToG4_elec_rel21")));
          m_G4OverAFII_resolution_unconverted.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/resol_Af2ToG4_unco_rel21")));
          m_G4OverAFII_resolution_converted.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/resol_Af2ToG4_conv_rel21")));
@@ -908,26 +957,33 @@ namespace AtlasRoot {
       m_G4OverAFII_resolution_unconverted->SetDirectory(nullptr);
       m_G4OverAFII_resolution_converted->SetDirectory(nullptr);
 
-      const std::string gain_filename1 = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/FunctionsTO.root");
-      const std::string gain_filename2 = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v8/FunctionsG_all.root");
+      // Prepare Gain correction or uncertainty
       m_gain_tool = nullptr;
 
       std::string gain_tool_run_2_filename;
-      if(m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer 
-         or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV ){
+      if (m_esmodel == egEnergyCorr::es2017 ||
+	  m_esmodel == egEnergyCorr::es2017_summer ||
+	  m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	  m_esmodel == egEnergyCorr::es2015_5TeV) {
         gain_tool_run_2_filename = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v11/gain_uncertainty_specialRun.root"); 
       }
-      else{
+      else if (m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+	gain_tool_run_2_filename = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v25/gain_uncertainty_specialRun.root");
+      }
+      else
+      {
         gain_tool_run_2_filename = PathResolverFindCalibFile("ElectronPhotonFourMomentumCorrection/v14/gain_uncertainty_specialRun.root");
       }
-      m_gain_tool_run2.reset( new egGain::GainUncertainty(gain_tool_run_2_filename));
+      m_gain_tool_run2.reset(new egGain::GainUncertainty(gain_tool_run_2_filename));
+      m_gain_tool_run2->msg().setLevel(this->msg().level());
       
       m_e1hg_tool.reset( new e1hg_systematics());
       m_use_temp_correction201215 = false;
       m_use_temp_correction201516 = false;
-    }
 
-    else if ( m_esmodel==egEnergyCorr::es2015_day0_3percent ) {
+    } // end rel21 settings
+
+    else if (m_esmodel==egEnergyCorr::es2015_day0_3percent ) {
       m_use_new_resolution_model = true;
       m_resolution_tool.reset(new eg_resolution("run2_pre"));
 
@@ -966,7 +1022,6 @@ namespace AtlasRoot {
       m_convRadius.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRadiusMigrations")));  m_convRadius->SetDirectory(nullptr);          // old one
       m_convFakeRate.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convFakeRate")));          m_convFakeRate->SetDirectory(nullptr);        // old one
       m_convRecoEfficiency.reset( dynamic_cast< TH1* >( m_rootFile->Get("Conversions/es2012c/convRecoEfficiency")));    m_convRecoEfficiency->SetDirectory(nullptr);  // old one
-
       m_begRunNumber = 195847;
       m_endRunNumber = 219365;
 
@@ -976,7 +1031,6 @@ namespace AtlasRoot {
 
       m_e1hg_tool.reset( new e1hg_systematics());
 
-
       // If we are here, fail      :
 
     } else if ( m_esmodel == egEnergyCorr::UNDEFINED) {
@@ -985,14 +1039,25 @@ namespace AtlasRoot {
     } else {
       ATH_MSG_FATAL("ES model not recognized - Initialization fails");
       return 0;
-
     }
 
-    if (m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017
-	or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final
-        or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1  or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1
-	or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1)
+    if (m_esmodel == egEnergyCorr::es2015cPRE ||
+	m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015c_summer ||
+	m_esmodel == egEnergyCorr::es2016PRE ||
+	m_esmodel == egEnergyCorr::es2017 ||
+	m_esmodel == egEnergyCorr::es2017_summer ||
+	m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	m_esmodel == egEnergyCorr::es2017_summer_final ||
+        m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	m_esmodel == egEnergyCorr::es2015_5TeV ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2022_R21_Precision)
     {
       // E4 systematics
       m_E4ElectronEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("E4Recalibration/v4/electron_eta_axis")));
@@ -1005,13 +1070,25 @@ namespace AtlasRoot {
     }
 
     // ... PS and S12 recalibration curves
-    if (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017
-	or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final
-        or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1
-	or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) {
-      
+    if (m_esmodel == egEnergyCorr::es2015PRE ||
+	m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015cPRE ||
+	m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015c_summer ||
+	m_esmodel == egEnergyCorr::es2016PRE ||
+	m_esmodel == egEnergyCorr::es2017 ||
+	m_esmodel == egEnergyCorr::es2017_summer ||
+	m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	m_esmodel == egEnergyCorr::es2017_summer_final ||
+        m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	m_esmodel == egEnergyCorr::es2015_5TeV ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1) {
+
       m_psElectronEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("PSRecalibration/es2015PRE/ElectronAxis")));
       m_psElectronGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("PSRecalibration/es2015PRE/ElectronBiasPS")));m_psElectronGraphs->SetOwner();
       m_psUnconvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("PSRecalibration/es2015PRE/UnconvertedAxis")));
@@ -1025,6 +1102,22 @@ namespace AtlasRoot {
       m_s12UnconvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("S1Recalibration/es2015PRE/UnconvertedBiasS1")));m_s12UnconvertedGraphs->SetOwner();
       m_s12ConvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("S1Recalibration/es2015PRE/ConvertedAxis")));
       m_s12ConvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("S1Recalibration/es2015PRE/ConvertedBiasS1")));m_s12ConvertedGraphs->SetOwner();
+
+    } else if(m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+
+      m_psElectronEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/ElectronAxis")));
+      m_psElectronGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/ElectronBiasPS")));m_psElectronGraphs->SetOwner();
+      m_psUnconvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/UnconvertedAxis")));
+      m_psUnconvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/UnconvertedBiasPS")));m_psUnconvertedGraphs->SetOwner();
+      m_psConvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/ConvertedAxis")));
+      m_psConvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("PSRecalibration/es2022_R21_Precision/ConvertedBiasPS")));m_psConvertedGraphs->SetOwner();
+
+      m_s12ElectronEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/ElectronAxis")));
+      m_s12ElectronGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/ElectronBiasS1")));m_s12ElectronGraphs->SetOwner();
+      m_s12UnconvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/UnconvertedAxis")));
+      m_s12UnconvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/UnconvertedBiasS1")));m_s12UnconvertedGraphs->SetOwner();
+      m_s12ConvertedEtaBins.reset( dynamic_cast< TAxis* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/ConvertedAxis")));
+      m_s12ConvertedGraphs.reset( dynamic_cast< TList* >( m_rootFile->Get("S1Recalibration/es2022_R21_Precision/ConvertedBiasS1")));m_s12ConvertedGraphs->SetOwner();
     }
     else // run1
     {
@@ -1080,7 +1173,12 @@ namespace AtlasRoot {
     m_matElectronCstTerm.emplace_back(std::unique_ptr<TH1>(  (TH1*) m_rootFile->Get("Material/electronCstTerm_ConfigGp") ));
     m_matElectronCstTerm.back()->SetDirectory(nullptr);
     
-    if (m_esmodel==egEnergyCorr::es2017_R21_v1 || m_esmodel==egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2022_R21_Precision) {
      // update dX0 plots for distorted geometry for case A, EL, FMX and N
       m_matX0Additions.emplace_back(std::unique_ptr<TH1>(  (TH1*) m_rootFile->Get("Material_rel21/DX0_ConfigA") )); 
       m_matX0Additions.back()->SetDirectory(nullptr);
@@ -1107,24 +1205,26 @@ namespace AtlasRoot {
       m_matX0Additions.emplace_back(std::unique_ptr<TH1>(  (TH1*) m_rootFile->Get("Material/DX0_ConfigGp") ));
       m_matX0Additions.back()->SetDirectory(nullptr);
     }
-
-    
-    m_matElectronEtaBins.reset( dynamic_cast<TAxis*>(m_rootFile->Get("Material/LinearityEtaBins")));
+ 
+    m_matElectronEtaBins.reset(dynamic_cast<TAxis*>(m_rootFile->Get("Material/LinearityEtaBins")));
     m_matElectronGraphs.emplace_back( std::unique_ptr<TList>( (TList*) m_rootFile->Get("Material/Linearity_Cluster_ConfigA")) );
     m_matElectronGraphs.emplace_back( std::unique_ptr<TList>( (TList*) m_rootFile->Get("Material/Linearity_Cluster_ConfigCpDp")) );
     m_matElectronGraphs.emplace_back( std::unique_ptr<TList>( (TList*) m_rootFile->Get("Material/Linearity_Cluster_ConfigEpLp")) );
     m_matElectronGraphs.emplace_back( std::unique_ptr<TList>( (TList*) m_rootFile->Get("Material/Linearity_Cluster_ConfigFpMX")) );
     m_matElectronGraphs.emplace_back( std::unique_ptr<TList>( (TList*) m_rootFile->Get("Material/Linearity_Cluster_ConfigGp")) );
 
-
     for (auto &mat: m_matElectronGraphs) {
       mat->SetOwner();
     }
 
-
     // ... new material distortions from release 21 parameterizations
 
-    if (m_esmodel==egEnergyCorr::es2017_R21_v1 || m_esmodel==egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2022_R21_Precision) {
       m_electronBias_ConfigA.reset( dynamic_cast< TH2* >( m_rootFile->Get("Material_rel21/electronBias_ConfigA")));            m_electronBias_ConfigA->SetDirectory(nullptr);
       m_electronBias_ConfigEpLp.reset( dynamic_cast< TH2* >( m_rootFile->Get("Material_rel21/electronBias_ConfigEpLp")));      m_electronBias_ConfigEpLp->SetDirectory(nullptr);
       m_electronBias_ConfigFpMX.reset( dynamic_cast< TH2* >( m_rootFile->Get("Material_rel21/electronBias_ConfigFpMX")));      m_electronBias_ConfigFpMX->SetDirectory(nullptr);
@@ -1145,27 +1245,35 @@ namespace AtlasRoot {
       m_convertedBias_ConfigPP0.reset( dynamic_cast< TH2* >( m_rootFile->Get("Material_rel21/convertedBias_ConfigPP0")));      m_convertedBias_ConfigPP0->SetDirectory(nullptr);
     }
 
-       
-
     // ... Fastsim to Fullsim corrections
 
-    if (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE) {
-
+    if (m_esmodel == egEnergyCorr::es2015PRE ||
+	m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015cPRE ||
+	m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015c_summer ||
+	m_esmodel == egEnergyCorr::es2016PRE) {
       m_G4OverAFII_electron.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2015/el_scale_full_fast_peak_gaussian"))); m_G4OverAFII_electron->SetDirectory(nullptr);
       m_G4OverAFII_unconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2015/ph_unconv_scale_full_fast_peak_gaussian"))); m_G4OverAFII_unconverted->SetDirectory(nullptr);
       m_G4OverAFII_converted.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2015/ph_conv_scale_full_fast_peak_gaussian"))); m_G4OverAFII_converted->SetDirectory(nullptr);
     }
-    else if (m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer 
-             or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final 
-             or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV 
-             or m_esmodel == egEnergyCorr::es2017_R21_v0) {
+    else if (m_esmodel == egEnergyCorr::es2017 ||
+	     m_esmodel == egEnergyCorr::es2017_summer ||
+             m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	     m_esmodel == egEnergyCorr::es2017_summer_final ||
+             m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	     m_esmodel == egEnergyCorr::es2015_5TeV ||
+             m_esmodel == egEnergyCorr::es2017_R21_v0) {
       m_G4OverAFII_electron.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2017/el_scale_full_fast_peak_gaussian"))); m_G4OverAFII_electron->SetDirectory(nullptr);
       m_G4OverAFII_unconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2017/ph_unconv_scale_full_fast_peak_gaussian"))); m_G4OverAFII_unconverted->SetDirectory(nullptr);
       m_G4OverAFII_converted.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/es2017/ph_conv_scale_full_fast_peak_gaussian"))); m_G4OverAFII_converted->SetDirectory(nullptr);
     }
-    else if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    else if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	     m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	     m_esmodel == egEnergyCorr::es2022_R21_Precision) {
       m_G4OverAFII_electron_2D.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/scale_Af2ToG4_elec_rel21"))); m_G4OverAFII_electron_2D->SetDirectory(nullptr);
       m_G4OverAFII_unconverted_2D.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/scale_Af2ToG4_unco_rel21"))); m_G4OverAFII_unconverted_2D->SetDirectory(nullptr);
       m_G4OverAFII_converted_2D.reset( dynamic_cast< TH2* >( m_rootFile->Get("FastSim/es2017_v1/scale_Af2ToG4_conv_rel21"))); m_G4OverAFII_converted_2D->SetDirectory(nullptr);
@@ -1173,21 +1281,39 @@ namespace AtlasRoot {
     else { // run 1
       m_G4OverAFII_electron.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/hG4OverAF")));                 m_G4OverAFII_electron->SetDirectory(nullptr);
     }
-    
     m_G4OverFrSh.reset( dynamic_cast< TH1* >( m_rootFile->Get("FastSim/hG4OverFS")));                 m_G4OverFrSh->SetDirectory(nullptr);
 
     // ... Leakage systematics
     
-    if(m_esmodel != egEnergyCorr::es2017_summer and m_esmodel != egEnergyCorr::es2017_summer_improved 
-       and m_esmodel != egEnergyCorr::es2017_summer_final and m_esmodel != egEnergyCorr::es2017_R21_PRE 
-       and m_esmodel != egEnergyCorr::es2015_5TeV and m_esmodel != egEnergyCorr::es2017_R21_v0 
-       and m_esmodel != egEnergyCorr::es2017_R21_v1 and m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 and m_esmodel != egEnergyCorr::es2018_R21_v0 and m_esmodel != egEnergyCorr::es2018_R21_v1){
-      m_leakageConverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/LeakageDiffConverted")));      m_leakageConverted->SetDirectory(nullptr);
-      m_leakageUnconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/LeakageDiffUnconverted")));    m_leakageUnconverted->SetDirectory(nullptr);
-    }
-    else{
-      m_leakageConverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2017_summer/LeakageDiffConverted")));      m_leakageConverted->SetDirectory(nullptr);
-      m_leakageUnconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2017_summer/LeakageDiffUnconverted")));    m_leakageUnconverted->SetDirectory(nullptr);
+    if (m_esmodel != egEnergyCorr::es2017_summer &&
+	m_esmodel != egEnergyCorr::es2017_summer_improved &&
+	m_esmodel != egEnergyCorr::es2017_summer_final &&
+	m_esmodel != egEnergyCorr::es2017_R21_PRE &&
+	m_esmodel != egEnergyCorr::es2015_5TeV &&
+	m_esmodel != egEnergyCorr::es2017_R21_v0 &&
+	m_esmodel != egEnergyCorr::es2017_R21_v1 &&
+	m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 &&
+	m_esmodel != egEnergyCorr::es2018_R21_v0 &&
+	m_esmodel != egEnergyCorr::es2018_R21_lowmu_v0 &&
+	m_esmodel != egEnergyCorr::es2018_R21_v1 &&
+	m_esmodel != egEnergyCorr::es2022_R21_Precision) {
+      m_leakageConverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/LeakageDiffConverted")));
+      m_leakageUnconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/LeakageDiffUnconverted")));
+    }
+    else if (m_esmodel != egEnergyCorr::es2022_R21_Precision) {
+      m_leakageConverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2017_summer/LeakageDiffConverted")));
+      m_leakageUnconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2017_summer/LeakageDiffUnconverted")));
+    } else {
+      m_leakageConverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2022_R21_Precision/LeakageDiffConverted")));
+      m_leakageUnconverted.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2022_R21_Precision/LeakageDiffUnconverted")));
+      m_leakageElectron.reset( dynamic_cast< TH1* >( m_rootFile->Get("Leakage/es2022_R21_Precision/LeakageDiffElectron")));
+      m_leakageElectron->SetDirectory(nullptr);
+    }
+    if (m_leakageConverted.get() && m_leakageUnconverted.get()) {
+      m_leakageConverted->SetDirectory(nullptr);
+      m_leakageUnconverted->SetDirectory(nullptr);
+    } else {
+      ATH_MSG_INFO("No leakage systematic uncertainty for ES model " << m_esmodel);
     }
     
     // ... Zee S2 profile (needed for gain switch syst).
@@ -1201,19 +1327,17 @@ namespace AtlasRoot {
 
   }
 
-
   // User interface
   // universal compact interface to getCorrectedEnergy(...)
-
-  double egammaEnergyCorrectionTool::getCorrectedMomentum( PATCore::ParticleDataType::DataType dataType,
-							   PATCore::ParticleType::Type ptype,
-							   double momentum,
-							   double trk_eta,
-							   egEnergyCorr::Scale::Variation scaleVar,
-							   double varSF ) const {
+  double egammaEnergyCorrectionTool::getCorrectedMomentum(PATCore::ParticleDataType::DataType dataType,
+							  PATCore::ParticleType::Type ptype,
+							  double momentum,
+							  double trk_eta,
+							  egEnergyCorr::Scale::Variation scaleVar,
+							  double varSF) const {
 
     double correctedMomentum = momentum;
-    double aeta = fabs(trk_eta);
+    double aeta = std::abs(trk_eta);
 
     if ( ptype == PATCore::ParticleType::Electron && dataType != PATCore::ParticleDataType::Data ) {
 
@@ -1230,18 +1354,18 @@ namespace AtlasRoot {
 
   // This method handles the main switches between data and the various MC flavours.
   // Called internally by getCorrectedEnergy(...)
-  double egammaEnergyCorrectionTool::getCorrectedEnergy( unsigned int runnumber,
-                                                         PATCore::ParticleDataType::DataType dataType,
-                                                         PATCore::ParticleType::Type ptype,
-                                                         double cl_eta,
-                                                         double cl_etaCalo,
-                                                         double energy,
-                                                         double energyS2,
-                                                         double eraw,
-							 egEnergyCorr::Scale::Variation scaleVar,
-                                                         egEnergyCorr::Resolution::Variation resVar,
-                                                         egEnergyCorr::Resolution::resolutionType resType,
-                                                         double varSF ) const {
+  double egammaEnergyCorrectionTool::getCorrectedEnergy(unsigned int runnumber,
+							PATCore::ParticleDataType::DataType dataType,
+							PATCore::ParticleType::Type ptype,
+							double cl_eta,
+							double cl_etaCalo,
+							double energy,
+							double energyS2,
+							double eraw,
+							egEnergyCorr::Scale::Variation scaleVar,
+							egEnergyCorr::Resolution::Variation resVar,
+							egEnergyCorr::Resolution::resolutionType resType,
+							double varSF) const {
     double fullyCorrectedEnergy = energy;
 
     // Correct fast sim flavours
@@ -1250,7 +1374,7 @@ namespace AtlasRoot {
       fullyCorrectedEnergy = energy * this->applyFStoG4(cl_eta);
     else if ( dataType == PATCore::ParticleDataType::Fast ) // AtlFast2 sim
     {
-      fullyCorrectedEnergy = energy * this->applyAFtoG4(cl_eta, 0.001*energy/cosh(cl_eta),ptype);
+      fullyCorrectedEnergy = energy * this->applyAFtoG4(cl_eta, 0.001*energy/std::cosh(cl_eta),ptype);
     }
 
     // If nothing is to be done
@@ -1268,7 +1392,7 @@ namespace AtlasRoot {
         double alpha = getAlphaValue(runnumber, cl_eta, cl_etaCalo, fullyCorrectedEnergy, energyS2, eraw, ptype, scaleVar, varSF);
 	fullyCorrectedEnergy /= (1 + alpha);
         // apply additional k.E+b corrections if histograms exist (like in es2017_R21_v1)
-	if (m_zeeFwdk &&  m_zeeFwdb && fabs(cl_eta)>2.5){ //  calo eta?
+	if (m_zeeFwdk &&  m_zeeFwdb && std::abs(cl_eta)>2.5){ //  calo eta?
 	  int ieta_k = m_zeeFwdk->GetXaxis()->FindBin(cl_eta);
 	  double value_k = m_zeeFwdk->GetBinContent(ieta_k);
 	  int ieta_b = m_zeeFwdb->GetXaxis()->FindBin(cl_eta);
@@ -1290,26 +1414,37 @@ namespace AtlasRoot {
       }
 
        // AF2 systematics  (this will not be in the sum of all other NP in the 1 NP model)
-      if (dataType == PATCore::ParticleDataType::Fast && (m_esmodel== egEnergyCorr::es2017_R21_v0 || m_esmodel== egEnergyCorr::es2017_R21_v1 || m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) ) {
-        if (scaleVar==egEnergyCorr::Scale::af2Up or scaleVar==egEnergyCorr::Scale::af2Down) {
+      if (dataType == PATCore::ParticleDataType::Fast &&
+	  (m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	   m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	   m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	   m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	   m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	   m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	   m_esmodel == egEnergyCorr::es2022_R21_Precision) ) {
+        if (scaleVar==egEnergyCorr::Scale::af2Up || scaleVar==egEnergyCorr::Scale::af2Down) {
            double daAF2=0.;
-           if (m_esmodel== egEnergyCorr::es2017_R21_v0) {
-              if (scaleVar==egEnergyCorr::Scale::af2Up) daAF2 = 0.005;
-              if (scaleVar==egEnergyCorr::Scale::af2Down) daAF2 = -0.005;
+           if (m_esmodel == egEnergyCorr::es2017_R21_v0) {
+              if (scaleVar == egEnergyCorr::Scale::af2Up) daAF2 = 0.005;
+              if (scaleVar == egEnergyCorr::Scale::af2Down) daAF2 = -0.005;
            }
-           if (m_esmodel== egEnergyCorr::es2017_R21_v1 || m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
-              if (scaleVar==egEnergyCorr::Scale::af2Up) daAF2 = 0.001;
-              if (scaleVar==egEnergyCorr::Scale::af2Down) daAF2 = -0.001;
+           if (m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	       m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	       m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	       m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	       m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	       m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+              if (scaleVar == egEnergyCorr::Scale::af2Up) daAF2 = 0.001;
+              if (scaleVar == egEnergyCorr::Scale::af2Down) daAF2 = -0.001;
            }
            fullyCorrectedEnergy *= ( 1 + daAF2);
         }
       }
 
-
       // Do the resolution correction
-      if ( resVar != egEnergyCorr::Resolution::None )
-      fullyCorrectedEnergy *= getSmearingCorrection(cl_eta, cl_etaCalo, fullyCorrectedEnergy, ptype, dataType, resVar, resType);
-
+        if ( resVar != egEnergyCorr::Resolution::None ) {
+            fullyCorrectedEnergy *= getSmearingCorrection(cl_eta, cl_etaCalo, fullyCorrectedEnergy, ptype, dataType, resVar, resType);
+            }
       ATH_MSG_DEBUG("after resolution correction = " << boost::format("%.2f") % fullyCorrectedEnergy);
     }
 
@@ -1323,9 +1458,7 @@ namespace AtlasRoot {
   // note : all energies in MeV
 
   // returns alpha_var. var = egEnergyCorr::Scale::Nominal or any systematic variation
-
-  double egammaEnergyCorrectionTool::getAlphaValue(
-						   long int runnumber,
+  double egammaEnergyCorrectionTool::getAlphaValue(long int runnumber,
 						   double cl_eta,
 						   double cl_etaCalo,
 						   double energy,      // input energy (not ET!!)
@@ -1335,13 +1468,15 @@ namespace AtlasRoot {
 						   egEnergyCorr::Scale::Variation var,
 						   double varSF ) const {
 
-    double meanE = getZeeMeanET(cl_eta)*cosh(cl_eta);
+    double meanET    = getZeeMeanET(cl_eta);
+    double meanETGeV = meanET/GeV;
+    double meanE     = meanET*std::cosh(cl_eta);
+    double Et        = energy/std::cosh(cl_eta);
 
     // Main Scale factor
 
     double alphaZee = getAlphaZee(runnumber, m_use_etaCalo_scales ? cl_etaCalo : cl_eta, var, varSF );
 
-
     // Sampling recalibration
 
     double daPS, daS12, linPS, linS12;
@@ -1349,8 +1484,15 @@ namespace AtlasRoot {
 
     double daE4 = 0., linE4 = 0.;
     // E4 contribution
-    if ((m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) and
-        (var == egEnergyCorr::Scale::E4ScintillatorUp or var == egEnergyCorr::Scale::E4ScintillatorDown))
+    if ((m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE ||
+	 m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	 m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	 m_esmodel == egEnergyCorr::es2017_R21_PRE || m_esmodel == egEnergyCorr::es2015_5TeV ||
+	 m_esmodel == egEnergyCorr::es2017_R21_v0 || m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+        (var == egEnergyCorr::Scale::E4ScintillatorUp || var == egEnergyCorr::Scale::E4ScintillatorDown))
     {
       daE4 = getE4Uncertainty(cl_eta);
       if (var == egEnergyCorr::Scale::E4ScintillatorDown) daE4 *= -1;
@@ -1359,17 +1501,23 @@ namespace AtlasRoot {
 
     //wtots1 contribution
     double daWtots1 = 0.;
-    if ((m_esmodel==egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1) and (var == egEnergyCorr::Scale::Wtots1Up or var == egEnergyCorr::Scale::Wtots1Down)){
+    if ((m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	 m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	 m_esmodel == egEnergyCorr::es2017_R21_PRE || m_esmodel == egEnergyCorr::es2015_5TeV ||
+	 m_esmodel == egEnergyCorr::es2017_R21_v0 || m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||  m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	(var == egEnergyCorr::Scale::Wtots1Up || var == egEnergyCorr::Scale::Wtots1Down)){
       daWtots1 = getWtots1Uncertainty(cl_eta, energy, ptype);
       if(var == egEnergyCorr::Scale::Wtots1Down)
 	daWtots1 = -daWtots1;
     }
 
     // ... Presampler contribution
-
-    if( var==egEnergyCorr::Scale::PSUp || var==egEnergyCorr::Scale::PSDown ||
-	var==egEnergyCorr::Scale::PSb12Up || var==egEnergyCorr::Scale::PSb12Down ||
-	var==egEnergyCorr::Scale::LArElecUnconvUp || var==egEnergyCorr::Scale::LArElecUnconvDown ) {
+    if( var == egEnergyCorr::Scale::PSUp            || var == egEnergyCorr::Scale::PSDown ||
+	var == egEnergyCorr::Scale::PSb12Up         || var == egEnergyCorr::Scale::PSb12Down ||
+	var == egEnergyCorr::Scale::LArElecUnconvUp || var == egEnergyCorr::Scale::LArElecUnconvDown ) {
 
       daPS  = getLayerUncertainty(  0, cl_eta, var, varSF );
       linPS = getLayerNonLinearity( 0, cl_eta, energy, ptype )
@@ -1378,25 +1526,26 @@ namespace AtlasRoot {
     }
 
     // ... S1 / S2 contribution
-
-    if (var == egEnergyCorr::Scale::S12Up or var==egEnergyCorr::Scale::S12Down or
-        var == egEnergyCorr::Scale::LArCalibUp or var==egEnergyCorr::Scale::LArCalibDown or
-        var == egEnergyCorr::Scale::LArCalibExtra2015PreUp or var == egEnergyCorr::Scale::LArCalibExtra2015PreDown or
-        var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up or var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down)
+    if (var == egEnergyCorr::Scale::S12Up                    || var == egEnergyCorr::Scale::S12Down ||
+        var == egEnergyCorr::Scale::LArCalibUp               || var == egEnergyCorr::Scale::LArCalibDown ||
+        var == egEnergyCorr::Scale::LArCalibExtra2015PreUp   || var == egEnergyCorr::Scale::LArCalibExtra2015PreDown ||
+        var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up || var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down)
       {
         daS12  = getLayerUncertainty(1, cl_eta, var, varSF);
 	linS12 = getLayerNonLinearity( 1, cl_eta, energy, ptype ) - getLayerNonLinearity( 1, cl_eta, meanE,  PATCore::ParticleType::Electron );
       }
 
     // Material contribution
-
     double daMatID, daMatCryo, daMatCalo;
     daMatID = daMatCryo = daMatCalo = 0;
 
     // for release 21 sensitivity use the same getMaterialNonLinearity for all particles
     // while in sensitivities derived from run 1 this is only used for electrons
 
-    if( ptype!=PATCore::ParticleType::Electron  && (m_esmodel != egEnergyCorr::es2017_R21_v1 && m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 &&  m_esmodel != egEnergyCorr::es2018_R21_v0 && m_esmodel != egEnergyCorr::es2018_R21_v1) ) {
+    if (ptype!=PATCore::ParticleType::Electron &&
+	(m_esmodel != egEnergyCorr::es2017_R21_v1 && m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 &&
+	 m_esmodel != egEnergyCorr::es2018_R21_v0 && m_esmodel != egEnergyCorr::es2018_R21_lowmu_v0 &&
+	 m_esmodel != egEnergyCorr::es2018_R21_v1 && m_esmodel != egEnergyCorr::es2022_R21_Precision) ) {
 
       daMatID   = getAlphaMaterial( cl_eta, egEnergyCorr::MatID,   ptype, var, varSF );
       daMatCryo = getAlphaMaterial( cl_eta, egEnergyCorr::MatCryo, ptype, var, varSF );
@@ -1414,7 +1563,6 @@ namespace AtlasRoot {
     }
 
     // Pedestal subtraction
-
     double daPedestal = getAlphaPedestal(cl_eta, energy, eraw, ptype, false, var, varSF)
       - getAlphaPedestal(cl_eta, meanE, eraw, PATCore::ParticleType::Electron , true, var, varSF);
 
@@ -1424,15 +1572,12 @@ namespace AtlasRoot {
     }
 
     // Leakage contribution (electron-photon difference)
-
-    double daLeakage = getAlphaLeakage(cl_eta, ptype, var, varSF);
-
+    double daLeakage = getAlphaLeakage2D(cl_eta, Et, ptype, var, varSF);
 
     // L1 Gain switch contribution
-
     double daL1GainSwitch = 0.;
 
-    if ( var==egEnergyCorr::Scale::L1GainUp || var==egEnergyCorr::Scale::L1GainDown ) {
+    if (var == egEnergyCorr::Scale::L1GainUp || var == egEnergyCorr::Scale::L1GainDown) {
 
       int eg_e1hg_ptype;
       if( ptype==PATCore::ParticleType::Electron )
@@ -1445,29 +1590,27 @@ namespace AtlasRoot {
 	return -1;
 
       daL1GainSwitch = m_e1hg_tool->getAlpha(eg_e1hg_ptype, energy, cl_eta, true);
-      if( var==egEnergyCorr::Scale::L1GainDown )
+      if( var == egEnergyCorr::Scale::L1GainDown )
 	daL1GainSwitch = -daL1GainSwitch;
 
     }
 
-
     // L2 Gain switch contribution
-
     double daL2GainSwitch = 0.;
 
-    if ( var==egEnergyCorr::Scale::L2GainUp || var==egEnergyCorr::Scale::L2GainDown ) {
+    if (var == egEnergyCorr::Scale::L2GainUp || var == egEnergyCorr::Scale::L2GainDown) {
       if (m_gain_tool) { // recipe for run1
-        if (!(fabs(cl_eta) < 1.52 and fabs(cl_eta) > 1.37) and fabs(cl_eta) < 2.4) {
-  	      double evar = m_gain_tool->CorrectionGainTool(cl_eta, energy/GeV, energyS2/GeV, ptype);
-  	      double meanES2 = m_zeeES2Profile->GetBinContent(m_zeeES2Profile->FindBin(cl_eta)); // in GeV already
-  	      double eref = m_gain_tool->CorrectionGainTool(cl_eta, meanE/GeV, meanES2, PATCore::ParticleType::Electron );
-  	      daL2GainSwitch = evar/energy - eref/meanE;
-  	      if( var==egEnergyCorr::Scale::L2GainDown )
-  	        daL2GainSwitch = -daL2GainSwitch;
+        if (!(std::abs(cl_eta) < 1.52 && std::abs(cl_eta) > 1.37) && std::abs(cl_eta) < 2.4) {
+	  double evar = m_gain_tool->CorrectionGainTool(cl_eta, energy/GeV, energyS2/GeV, ptype);
+	  double meanES2 = m_zeeES2Profile->GetBinContent(m_zeeES2Profile->FindBin(cl_eta)); // in GeV already
+	  double eref = m_gain_tool->CorrectionGainTool(cl_eta, meanE/GeV, meanES2, PATCore::ParticleType::Electron );
+	  daL2GainSwitch = evar/energy - eref/meanE;
+	  if( var==egEnergyCorr::Scale::L2GainDown )
+	    daL2GainSwitch = -daL2GainSwitch;
         }
       }
       else if (m_gain_tool_run2) { // recipe for run 2, see ATLASEG-44
-        daL2GainSwitch = m_gain_tool_run2->getUncertainty(cl_etaCalo, energy / cosh(cl_eta), ptype);
+        daL2GainSwitch = m_gain_tool_run2->getUncertainty(cl_etaCalo, Et, ptype, m_useL2GainCorrection);
         if (var == egEnergyCorr::Scale::L2GainDown) daL2GainSwitch *= -1;
       }
       else {
@@ -1479,17 +1622,19 @@ namespace AtlasRoot {
     // pp0 (and IBL)
     double dapp0 = 0.;
     // values from the histogram already are 0 for the Z->ee electrons
-    if (var == egEnergyCorr::Scale::MatPP0Up or var == egEnergyCorr::Scale::MatPP0Down) {
+    if (var == egEnergyCorr::Scale::MatPP0Up || var == egEnergyCorr::Scale::MatPP0Down) {
 
-// new parameterization for release 21 reconstruction with mc16 geometries + distortions
-      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||  m_esmodel == egEnergyCorr::es2018_R21_v1) {
+      // new parameterization for release 21 reconstruction with mc16 geometries + distortions
+      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision )  {
 
-          if (fabs(cl_eta)<1.5)
-           dapp0 = getMaterialEffect(egEnergyCorr::ConfigIBL,ptype ,cl_eta,energy / GeV / cosh(cl_eta))
-                  -getMaterialEffect(egEnergyCorr::ConfigIBL,PATCore::ParticleType::Electron, cl_eta,getZeeMeanET(cl_eta)/GeV);
+	if (std::abs(cl_eta)<1.5)
+           dapp0 = getMaterialEffect(egEnergyCorr::ConfigIBL,ptype,cl_eta,Et / GeV)
+                  -getMaterialEffect(egEnergyCorr::ConfigIBL,PATCore::ParticleType::Electron,cl_eta,meanETGeV);
           else 
-           dapp0 = getMaterialEffect(egEnergyCorr::ConfigPP0,ptype ,cl_eta,energy / GeV / cosh(cl_eta))
-                  -getMaterialEffect(egEnergyCorr::ConfigPP0,PATCore::ParticleType::Electron, cl_eta,getZeeMeanET(cl_eta)/GeV);
+           dapp0 = getMaterialEffect(egEnergyCorr::ConfigPP0,ptype,cl_eta,Et / GeV)
+                  -getMaterialEffect(egEnergyCorr::ConfigPP0,PATCore::ParticleType::Electron,cl_eta,meanETGeV);
 
           if (var == egEnergyCorr::Scale::MatPP0Down) { dapp0 = -dapp0; }
       }
@@ -1504,32 +1649,51 @@ namespace AtlasRoot {
 
         if (histo) {
           const double aeta = std::abs(cl_eta);
-          dapp0 = getValueHistAt(*histo, aeta, energy / GeV / cosh(cl_eta), false, true, false, true);
+          dapp0 = getValueHistAt(*histo, aeta, Et / GeV, false, true, false, true);
           if (var == egEnergyCorr::Scale::MatPP0Down) { dapp0 = -dapp0; }
 
           // normalize to pp0 systematics
-          if (aeta > 1.5 and aeta < 2.0) { dapp0 *= 2.6; }
-          else if (aeta >= 2.0 and aeta <= 2.5) { dapp0 *= 2.3; }
+          if (aeta > 1.5 && aeta < 2.0) { dapp0 *= 2.6; }
+          else if (aeta >= 2.0 && aeta <= 2.5) { dapp0 *= 2.3; }
         }
      }
     }
 
     // Conversion systematics
-
     double daConvSyst = getAlphaConvSyst(cl_eta, energy, ptype, var, varSF);
 
     // topo cluster threshold systematics for release 21
-    double daTopoCluster=0;
-    if ((var==egEnergyCorr::Scale::topoClusterThresUp || var==egEnergyCorr::Scale::topoClusterThresDown) && (m_esmodel== egEnergyCorr::es2017_R21_v0 || m_esmodel== egEnergyCorr::es2017_R21_v1 || m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1)) {
-       double Et = energy/cosh(cl_eta);
-       double Et0=10000.;
-       //  Effect taken as 10**-3/(Et/10GeV) - order of magniture from https://indico.cern.ch/event/669895/contributions/2745266/attachments/1535612/2405452/slides.pdf
-       if (var==egEnergyCorr::Scale::topoClusterThresUp)      daTopoCluster = 1e-3*(1./(Et/Et0)-1./(getZeeMeanET(cl_eta)/Et0));
-       if (var==egEnergyCorr::Scale::topoClusterThresUp)      daTopoCluster = -1e-3*(1./(Et/Et0)-1./(getZeeMeanET(cl_eta)/Et0));
+    double daTopoCluster = 0;
+    if ((var == egEnergyCorr::Scale::topoClusterThresUp || var == egEnergyCorr::Scale::topoClusterThresDown) &&
+	(m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2022_R21_Precision)) {
+      static const double Et0 = 10000.;
+      //  Effect taken as 10**-3/(Et/10GeV) - order of magniture from https://indico.cern.ch/event/669895/contributions/2745266/attachments/1535612/2405452/slides.pdf
+      if (var == egEnergyCorr::Scale::topoClusterThresUp)   daTopoCluster = 1e-3*(1./(Et/Et0)-1./(meanET/Et0));
+      if (var == egEnergyCorr::Scale::topoClusterThresDown) daTopoCluster = -1e-3*(1./(Et/Et0)-1./(meanET/Et0));
+    }
+
+    // ADC non linearity correction. 30% of the effect from https://indico.cern.ch/event/1001455/contributions/4205636/attachments/2179584/3681315/ADC-linearity-28jan2021.pdf ?
+    double daADCLin = 0;
+    if (m_esmodel == egEnergyCorr::es2022_R21_Precision &&
+	(var == egEnergyCorr::Scale::ADCLinUp || var == egEnergyCorr::Scale::ADCLinDown)) {
+      if (m_ADCLinearity_tool) {
+	double corr = m_ADCLinearity_tool->getCorr(cl_etaCalo,Et,ptype)-1.;
+	daADCLin = 0.3*corr;
+      } else {
+	ATH_MSG_WARNING("trying to compute ADC correction systematic, but no tool for doing it has been instantiated, setting sys to 0");
+        daADCLin = 0.;
+      }
+      if (var == egEnergyCorr::Scale::ADCLinDown)
+	daADCLin *= -1;
     }
 
     // Total
-
     double alphaTot = alphaZee;
     alphaTot += daE4 * linE4;
     alphaTot += daPS*linPS;
@@ -1543,6 +1707,7 @@ namespace AtlasRoot {
     alphaTot += daWtots1;
     alphaTot += dapp0;
     alphaTot += daTopoCluster;
+    alphaTot += daADCLin;
 
     ATH_MSG_DEBUG("alpha value for " << variationName(var) << " = " << alphaTot);
 
@@ -1550,9 +1715,7 @@ namespace AtlasRoot {
 
   }
 
-
   // returns alpha_var - alpha_nom, for systematic variations.
-
   double egammaEnergyCorrectionTool::getAlphaUncertainty(long int runnumber,
 							 double cl_eta,
 							 double cl_etaCalo,
@@ -1565,8 +1728,8 @@ namespace AtlasRoot {
     double alphaNom = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, egEnergyCorr::Scale::Nominal );
     double alphaVar = 0.;
 
-    if (var != egEnergyCorr::Scale::AllUp && var != egEnergyCorr::Scale::AllDown and
-        var != egEnergyCorr::Scale::AllCorrelatedUp and var != egEnergyCorr::Scale::AllCorrelatedDown)  {
+    if (var != egEnergyCorr::Scale::AllUp && var != egEnergyCorr::Scale::AllDown &&
+        var != egEnergyCorr::Scale::AllCorrelatedUp && var != egEnergyCorr::Scale::AllCorrelatedDown)  {
       // not an ALLUP
       alphaVar = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, var, varSF ) - alphaNom;
     }
@@ -1577,9 +1740,9 @@ namespace AtlasRoot {
         if (ivar == egEnergyCorr::Scale::ZeeAllUp) continue;
         const double v = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, ivar, varSF) - alphaNom;
         ATH_MSG_DEBUG("computing ALLUP, adding " << variationName(ivar) << ": " << v);
-        alphaVar += pow(v, 2);
+        alphaVar += v*v;
       }
-      alphaVar = sqrt(alphaVar);
+      alphaVar = std::sqrt(alphaVar);
     }
     else if (var == egEnergyCorr::Scale::AllDown) {
       for (egEnergyCorr::Scale::Variation ivar = egEnergyCorr::Scale::ZeeStatDown;
@@ -1588,37 +1751,37 @@ namespace AtlasRoot {
 	if (ivar == egEnergyCorr::Scale::ZeeAllDown) continue;
         const double v = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, ivar, varSF) - alphaNom;
         ATH_MSG_DEBUG("computing ALLDOWN, adding " << variationName(ivar) << ": " << v);
-	alphaVar += pow(v, 2);
+	alphaVar += v*v;
       }
-      alphaVar = -sqrt(alphaVar);
+      alphaVar = -std::sqrt(alphaVar);
     }
     else if (var == egEnergyCorr::Scale::AllCorrelatedUp) {
       for (egEnergyCorr::Scale::Variation ivar = egEnergyCorr::Scale::ZeeStatUp;
            ivar < egEnergyCorr::Scale::AllUp;
 	   ivar = egEnergyCorr::Scale::Variation(ivar+2)) {
-        if (ivar == egEnergyCorr::Scale::ZeeAllUp or
-            ivar == egEnergyCorr::Scale::LArCalibExtra2015PreUp or
-            ivar == egEnergyCorr::Scale::LArTemperature2015PreUp or
-            ivar == egEnergyCorr::Scale::LArTemperature2016PreUp or
+        if (ivar == egEnergyCorr::Scale::ZeeAllUp ||
+            ivar == egEnergyCorr::Scale::LArCalibExtra2015PreUp ||
+            ivar == egEnergyCorr::Scale::LArTemperature2015PreUp ||
+            ivar == egEnergyCorr::Scale::LArTemperature2016PreUp ||
             ivar == egEnergyCorr::Scale::E4ScintillatorUp) continue;
         const double v = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, ivar, varSF) - alphaNom;
-        alphaVar += pow(v, 2);
+        alphaVar += v*v;
       }
-      alphaVar = sqrt(alphaVar);
+      alphaVar = std::sqrt(alphaVar);
     }
     else if (var == egEnergyCorr::Scale::AllCorrelatedDown) {
       for (egEnergyCorr::Scale::Variation ivar = egEnergyCorr::Scale::ZeeStatDown;
            ivar < egEnergyCorr::Scale::AllDown;
            ivar = egEnergyCorr::Scale::Variation(ivar+2)) {
-        if (ivar == egEnergyCorr::Scale::ZeeAllDown or
-            ivar == egEnergyCorr::Scale::LArCalibExtra2015PreDown or
-            ivar == egEnergyCorr::Scale::LArTemperature2015PreDown or
-            ivar == egEnergyCorr::Scale::LArTemperature2016PreDown or
+        if (ivar == egEnergyCorr::Scale::ZeeAllDown ||
+            ivar == egEnergyCorr::Scale::LArCalibExtra2015PreDown ||
+            ivar == egEnergyCorr::Scale::LArTemperature2015PreDown ||
+            ivar == egEnergyCorr::Scale::LArTemperature2016PreDown ||
             ivar == egEnergyCorr::Scale::E4ScintillatorDown) continue;
         const double v = getAlphaValue(runnumber, cl_eta, cl_etaCalo, energy, energyS2, eraw, ptype, ivar, varSF) - alphaNom;
-        alphaVar += pow(v, 2);
+        alphaVar += v*v;
       }
-      alphaVar = -sqrt(alphaVar);
+      alphaVar = -std::sqrt(alphaVar);
     }
 
     return alphaVar;
@@ -1638,10 +1801,9 @@ namespace AtlasRoot {
 
 
   // sampling term inMC, parametrization from Iro Koletsou
-
   double egammaEnergyCorrectionTool::mcSamplingTerm(double cl_eta) const {
 
-    double aeta = fabs( cl_eta );
+    double aeta = std::abs( cl_eta );
     double sampling = 0.;
 
     if ( aeta<0.8 )
@@ -1668,7 +1830,6 @@ namespace AtlasRoot {
 
 
   // sampling term uncertainty
-
   double egammaEnergyCorrectionTool::mcSamplingTermRelError( double cl_eta ) const {
 
     (void) cl_eta; // not used
@@ -1678,10 +1839,9 @@ namespace AtlasRoot {
 
 
   // noise term in MC (from Iro)
-
   double egammaEnergyCorrectionTool::mcNoiseTerm( double cl_eta ) const {
 
-    double aeta = fabs( cl_eta );
+    double aeta = std::abs( cl_eta );
     double noise = 0.;
 
     double noise37[25]={ 0.27, 0.27, 0.27, 0.27, 0.27,
@@ -1693,7 +1853,7 @@ namespace AtlasRoot {
     int ieta = (int) (aeta/0.1);
 
     if ( ieta >= 0 && ieta<25 )
-      noise =  noise37[ieta] * cosh(cl_eta); // the above parametrization is vs ET
+      noise =  noise37[ieta] * std::cosh(cl_eta); // the above parametrization is vs ET
 
     return noise;
 
@@ -1701,10 +1861,9 @@ namespace AtlasRoot {
 
 
   // constant term in MC (local)
-
   double egammaEnergyCorrectionTool::mcConstantTerm( double cl_eta ) const {
 
-    double aeta = fabs( cl_eta );
+    double aeta = std::abs( cl_eta );
     double cst = 0.;
 
     if ( aeta<0.6 )
@@ -1724,9 +1883,13 @@ namespace AtlasRoot {
 
 
   // constant term fitted in data (long range)
-
   double egammaEnergyCorrectionTool::dataConstantTerm( double eta ) const {
-    return std::max(0., m_resNom->GetBinContent(m_resNom->FindBin(eta)));
+      double val ;
+      if (m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 && m_RunNumber<=341184 && m_RunNumber>=340634)
+          val = m_resNom_datalowmu->GetBinContent(m_resNom_datalowmu->FindBin(eta)) ;
+          else
+          val =  m_resNom->GetBinContent(m_resNom->FindBin(eta));
+    return std::max(0., val);
   }
 
   double egammaEnergyCorrectionTool::dataConstantTermError( double eta ) const {
@@ -1735,7 +1898,6 @@ namespace AtlasRoot {
 
 
   // fitted Z peak resolution, data, in GeV
-
   double egammaEnergyCorrectionTool::dataZPeakResolution( double cl_eta ) const {
 
     return m_peakResData->GetBinContent( m_peakResData->GetXaxis()->FindBin(cl_eta) );
@@ -1744,7 +1906,6 @@ namespace AtlasRoot {
 
 
   // fitted Z peak resolution, MC, in GeV
-
   double egammaEnergyCorrectionTool::mcZPeakResolution( double cl_eta ) const {
 
     return m_peakResMC->GetBinContent( m_peakResMC->GetXaxis()->FindBin(cl_eta) );
@@ -1753,7 +1914,6 @@ namespace AtlasRoot {
 
 
   // correlated part of constant term uncertainty, in data (approx.)
-
   double egammaEnergyCorrectionTool::dataConstantTermCorError( double cl_eta ) const {
 
     double mz = 91.2;
@@ -1765,23 +1925,23 @@ namespace AtlasRoot {
     double smpup = 1. + mcSamplingTermRelError( cl_eta );
     double smpdo = 1. - mcSamplingTermRelError( cl_eta );
 
-    double central = sqrt( 2*(resData*resData - resMC*resMC)/mz/mz + cmc*cmc );
-    double vardown = sqrt( 2*(resData*resData - resMC*resMC*smpup*smpup)/mz/mz + cmc*cmc );
-    double varup   = sqrt( 2*(resData*resData - resMC*resMC*smpdo*smpdo)/mz/mz + cmc*cmc );
+    double central = std::sqrt( 2*(resData*resData - resMC*resMC)/mz/mz + cmc*cmc );
+    double vardown = std::sqrt( 2*(resData*resData - resMC*resMC*smpup*smpup)/mz/mz + cmc*cmc );
+    double varup   = std::sqrt( 2*(resData*resData - resMC*resMC*smpdo*smpdo)/mz/mz + cmc*cmc );
 
-    double errdown = fabs( central - vardown );
-    double errup   = fabs( central - varup );
+    double errdown = std::abs( central - vardown );
+    double errup   = std::abs( central - varup );
 
     return .5*( errup + errdown );
 
   }
 
   // get fractional uncertainty on resolution
-
-  double egammaEnergyCorrectionTool::getResolutionError(PATCore::ParticleDataType::DataType dataType,double energy, double eta, double etaCalo, 
-                                                        PATCore::ParticleType::Type ptype,egEnergyCorr::Resolution::Variation value,
-                                                       egEnergyCorr::Resolution::resolutionType resType) const
-
+  double egammaEnergyCorrectionTool::getResolutionError(PATCore::ParticleDataType::DataType dataType,
+							double energy, double eta, double etaCalo, 
+                                                        PATCore::ParticleType::Type ptype,
+							egEnergyCorr::Resolution::Variation value,
+							egEnergyCorr::Resolution::resolutionType resType) const
   {
 
     int eg_resolution_ptype;
@@ -1832,28 +1992,30 @@ namespace AtlasRoot {
     }
 
     double sign = 1.;
-    if (value==egEnergyCorr::Resolution::AllDown ||  value==egEnergyCorr::Resolution::ZSmearingDown ||
-        value==egEnergyCorr::Resolution::SamplingTermDown ||  value==egEnergyCorr::Resolution::MaterialIDDown ||
-        value==egEnergyCorr::Resolution::MaterialGapDown || value==egEnergyCorr::Resolution::MaterialCaloDown ||
+    if (value==egEnergyCorr::Resolution::AllDown          || value==egEnergyCorr::Resolution::ZSmearingDown ||
+        value==egEnergyCorr::Resolution::SamplingTermDown || value==egEnergyCorr::Resolution::MaterialIDDown ||
+        value==egEnergyCorr::Resolution::MaterialGapDown  || value==egEnergyCorr::Resolution::MaterialCaloDown ||
         value==egEnergyCorr::Resolution::MaterialCryoDown || value==egEnergyCorr::Resolution::PileUpDown ||
-	value==egEnergyCorr::Resolution::MaterialIBLDown || value==egEnergyCorr::Resolution::MaterialPP0Down ||
+	value==egEnergyCorr::Resolution::MaterialIBLDown  || value==egEnergyCorr::Resolution::MaterialPP0Down ||
         value==egEnergyCorr::Resolution::af2Down) sign=-1.;
 
     double resolution;
     double resolution_error;
     double resolution_error_up;
     double resolution_error_down;
-
-
-    getResolution_systematics(eg_resolution_ptype, energy,  eta, etaCalo, isys,  resolution, resolution_error, resolution_error_up, resolution_error_down, resType, 
-          dataType == PATCore::ParticleDataType::Fast);
+    getResolution_systematics(eg_resolution_ptype,
+			      energy, eta, etaCalo,
+			      isys,
+			      resolution, resolution_error, resolution_error_up, resolution_error_down,
+			      resType, 
+			      dataType == PATCore::ParticleDataType::Fast);
 
     // total resolution uncertainty
-    if (value==egEnergyCorr::Resolution::AllUp || value==egEnergyCorr::Resolution::AllDown) {
+    if (value == egEnergyCorr::Resolution::AllUp || value == egEnergyCorr::Resolution::AllDown) {
       resolution_error = resolution_error / resolution * sign;
     } else {
-      if (sign==1) resolution_error= resolution_error_up/resolution;
-      else         resolution_error=resolution_error_down/resolution;
+      if (sign==1) resolution_error = resolution_error_up/resolution;
+      else         resolution_error = resolution_error_down/resolution;
     }
 
     return resolution_error;
@@ -1870,7 +2032,7 @@ namespace AtlasRoot {
 
     double Cdata_unc = 0.;
     if( Cdata_err > Cdata_cor )
-      Cdata_unc = sqrt( Cdata_err*Cdata_err - Cdata_cor*Cdata_cor );
+      Cdata_unc = std::sqrt( Cdata_err*Cdata_err - Cdata_cor*Cdata_cor );
     if( Cdata_unc<0.001 )
       Cdata_unc = 0.001; // preserve at least the stat error
 
@@ -1885,17 +2047,16 @@ namespace AtlasRoot {
     double err4 = -err3;
 
     errUp = 0;
-    if( err1>0 ) errUp = sqrt( errUp*errUp + err1*err1);
-    if( err2>0 ) errUp = sqrt( errUp*errUp + err2*err2);
-    if( err3>0 ) errUp = sqrt( errUp*errUp + err3*err3);
-    if( err4>0 ) errUp = sqrt( errUp*errUp + err4*err4);
+    if( err1>0 ) errUp = std::sqrt( errUp*errUp + err1*err1);
+    if( err2>0 ) errUp = std::sqrt( errUp*errUp + err2*err2);
+    if( err3>0 ) errUp = std::sqrt( errUp*errUp + err3*err3);
+    if( err4>0 ) errUp = std::sqrt( errUp*errUp + err4*err4);
 
     errDown   = -errUp;
   }
 
 
   // total resolution (fractional)
-
   double egammaEnergyCorrectionTool::resolution(double energy, double cl_eta, double cl_etaCalo,
 						                                    PATCore::ParticleType::Type ptype,
 						                                    bool withCT,
@@ -1903,9 +2064,9 @@ namespace AtlasRoot {
                                                 egEnergyCorr::Resolution::resolutionType resType) const
 {
     int eg_resolution_ptype;
-    if (ptype == PATCore::ParticleType::Electron) eg_resolution_ptype = 0;
-    else if (ptype==PATCore::ParticleType::UnconvertedPhoton) eg_resolution_ptype = 1;
-    else if (ptype==PATCore::ParticleType::ConvertedPhoton) eg_resolution_ptype = 2;
+    if      (ptype == PATCore::ParticleType::Electron)          eg_resolution_ptype = 0;
+    else if (ptype == PATCore::ParticleType::UnconvertedPhoton) eg_resolution_ptype = 1;
+    else if (ptype == PATCore::ParticleType::ConvertedPhoton)   eg_resolution_ptype = 2;
     else {
       ATH_MSG_FATAL("cannot understand particle type");
       return -1;
@@ -1914,9 +2075,9 @@ namespace AtlasRoot {
     double sig2 = 0.;
 
     if (m_use_new_resolution_model) {
-      sig2 = pow(m_resolution_tool->getResolution(eg_resolution_ptype, energy, cl_eta, resType), 2);
-      const double et = energy / cosh(cl_eta);
-      sig2 += pow(pileUpTerm(energy, cl_eta, eg_resolution_ptype) / et, 2);  // TODO: why et and not E?
+      sig2 = std::pow(m_resolution_tool->getResolution(eg_resolution_ptype, energy, cl_eta, resType), 2);
+      const double et = energy / std::cosh(cl_eta);
+      sig2 += std::pow(pileUpTerm(energy, cl_eta, eg_resolution_ptype) / et, 2);  // TODO: why et and not E?
     } else { // OLD model
 
       double energyGeV = energy/GeV;
@@ -1927,30 +2088,41 @@ namespace AtlasRoot {
 
     }
 
-    if (withCT and fast) {
+    if (withCT && fast) {
       throw std::runtime_error("It doesn't make sense to ask resolution fast sim + additional CT."
 			                         " The resolution on data is FULL sim resolution + CT");
     }
 
-    if (fast and std::abs(cl_eta) < 2.5) {
-      if (m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    if (fast && std::abs(cl_eta) < 2.5) {
+      if (m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	  m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	  m_esmodel == egEnergyCorr::es2017_R21_PRE || m_esmodel == egEnergyCorr::es2015_5TeV ||
+	  m_esmodel == egEnergyCorr::es2015PRE || m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+	  m_esmodel == egEnergyCorr::es2015cPRE || m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+	  m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE ||
+	  m_esmodel == egEnergyCorr::es2017_R21_v0 || m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	  m_esmodel == egEnergyCorr::es2022_R21_Precision) {
 
         double ratio_IQR_full_fast = 1.;
-        const double ptGeV = energy / cosh(cl_eta) / 1E3;
+        const double ptGeV = energy / std::cosh(cl_eta) / 1E3;
 
-        if  ( m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) {
+        if  (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) {
 //
 // for es2017_R21_v1, histograms contain directly values of deltaSigma**2 of relative energy resolution (FastSIm-FulSim) so need to subtract this value to get the sigma**2 of FastSim
 
-           if(ptype == PATCore::ParticleType::Electron) sig2 -=   getValueHistAt(*m_G4OverAFII_resolution_electron,cl_eta,ptGeV,true,true,true,true);
-           if (ptype == PATCore::ParticleType::UnconvertedPhoton) sig2 -=   getValueHistAt(*m_G4OverAFII_resolution_unconverted,cl_eta,ptGeV,true,true,true,true);
-           if (ptype == PATCore::ParticleType::ConvertedPhoton) sig2 -=   getValueHistAt(*m_G4OverAFII_resolution_converted,cl_eta,ptGeV,true,true,true,true);
+           if (ptype == PATCore::ParticleType::Electron)          sig2 -= getValueHistAt(*m_G4OverAFII_resolution_electron,cl_eta,ptGeV,true,true,true,true);
+           if (ptype == PATCore::ParticleType::UnconvertedPhoton) sig2 -= getValueHistAt(*m_G4OverAFII_resolution_unconverted,cl_eta,ptGeV,true,true,true,true);
+           if (ptype == PATCore::ParticleType::ConvertedPhoton)   sig2 -= getValueHistAt(*m_G4OverAFII_resolution_converted,cl_eta,ptGeV,true,true,true,true);
            if (sig2<0.) sig2=0.;
         }
         else {
-          if (ptype == PATCore::ParticleType::Electron) { ratio_IQR_full_fast = getValueHistAt(*m_G4OverAFII_resolution_electron, ptGeV, cl_eta, true, false); }
+          if (ptype == PATCore::ParticleType::Electron)               { ratio_IQR_full_fast = getValueHistAt(*m_G4OverAFII_resolution_electron, ptGeV, cl_eta, true, false); }
           else if (ptype == PATCore::ParticleType::UnconvertedPhoton) { ratio_IQR_full_fast = getValueHistAt(*m_G4OverAFII_resolution_unconverted, ptGeV, cl_eta, true, false); }
-          else if (ptype == PATCore::ParticleType::ConvertedPhoton) {  ratio_IQR_full_fast = getValueHistAt(*m_G4OverAFII_resolution_converted, ptGeV, cl_eta, true, false); }
+          else if (ptype == PATCore::ParticleType::ConvertedPhoton)   { ratio_IQR_full_fast = getValueHistAt(*m_G4OverAFII_resolution_converted, ptGeV, cl_eta, true, false); }
 
           sig2 /= ratio_IQR_full_fast * ratio_IQR_full_fast;
         }
@@ -1958,21 +2130,20 @@ namespace AtlasRoot {
     }
 
     // add the additional constant term from the Zee data/MC measurement
-    if (withCT) sig2 += pow(dataConstantTerm(m_use_etaCalo_scales ? cl_etaCalo : cl_eta), 2);  // TODO: is it correct? Or should be += -c**2 + (c + deltac) ** 2 ?
+    if (withCT) sig2 += std::pow(dataConstantTerm(m_use_etaCalo_scales ? cl_etaCalo : cl_eta), 2);  // TODO: is it correct? Or should be += -c**2 + (c + deltac) ** 2 ?
 
-    return sqrt(sig2);
+    return std::sqrt(sig2);
   }
 
 
   // internal use only
-
   double egammaEnergyCorrectionTool::fcn_sigma(double energy, double Cdata, double Cdata_er, double S, double S_er) const {
 
     double sigma2 = std::pow((Cdata+Cdata_er)*energy,2) + std::pow(S*(1+S_er)*std::sqrt(energy),2);
 
     double sigma=0;
     if (sigma2>0)
-      sigma=sqrt(sigma2);
+      sigma=std::sqrt(sigma2);
 
     return sigma/energy;
 
@@ -2023,7 +2194,7 @@ namespace AtlasRoot {
     // which is just the additional constant term
     if (sigma2 <= 0) { return 1; }
 
-    const double sigma = sqrt(sigma2);
+    const double sigma = std::sqrt(sigma2);
 
     ATH_MSG_DEBUG("seed before = " << m_random3.GetSeed());
 
@@ -2039,13 +2210,12 @@ namespace AtlasRoot {
 
   // a calibration correction for crack electrons, to be applied to both data11 and MC11
   // not to be used in data12 / MC12
-
   double egammaEnergyCorrectionTool::applyMCCalibration( double eta, double ET, PATCore::ParticleType::Type ptype) const {
 
     if( ptype != PATCore::ParticleType::Electron || m_esmodel != egEnergyCorr::es2011c )
       return 1.;
 
-    double aeta = fabs(eta);
+    double aeta = std::abs(eta);
 
     if( aeta<1.42 || aeta>1.55 )
       return 1.;
@@ -2073,30 +2243,34 @@ namespace AtlasRoot {
 
 
   // AF -> G4 correction
-
   double egammaEnergyCorrectionTool::applyAFtoG4(double eta, double ptGeV,
 						 PATCore::ParticleType::Type ptype) const {
-    const double aeta = fabs(eta);
+    const double aeta = std::abs(eta);
     if (aeta > 2.47) return 1.;
 
-    if (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017
-	or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final
-	or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    if (m_esmodel == egEnergyCorr::es2015PRE || m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015cPRE || m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE ||
+	m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	m_esmodel == egEnergyCorr::es2017_R21_PRE || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision ) {
      
-      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||  m_esmodel == egEnergyCorr::es2018_R21_v1) {
-//
-// in es02017_R21_v1 : AF2 to FullSim correction is in a 2D eta-Pt histogram
-
-        if (ptype == PATCore::ParticleType::Electron) { return (1.+getValueHistAt(*m_G4OverAFII_electron_2D, aeta,ptGeV,true,true,true,true)); }
-        else if (ptype == PATCore::ParticleType::ConvertedPhoton) { return (1.+getValueHistAt(*m_G4OverAFII_converted_2D, aeta,ptGeV,true,true,true,true)); }
+      if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+	//
+	// in es02017_R21_v1 : AF2 to FullSim correction is in a 2D eta-Pt histogram
+        if      (ptype == PATCore::ParticleType::Electron)          { return (1.+getValueHistAt(*m_G4OverAFII_electron_2D, aeta,ptGeV,true,true,true,true)); }
+        else if (ptype == PATCore::ParticleType::ConvertedPhoton)   { return (1.+getValueHistAt(*m_G4OverAFII_converted_2D, aeta,ptGeV,true,true,true,true)); }
         else if (ptype == PATCore::ParticleType::UnconvertedPhoton) { return (1.+getValueHistAt(*m_G4OverAFII_unconverted_2D, aeta,ptGeV,true,true,true,true)); }
         else { throw std::runtime_error("particle not valid"); }
       }
       else {
-        if (ptype == PATCore::ParticleType::Electron) { return getValueHistoAt(*m_G4OverAFII_electron, aeta); }
-        else if (ptype == PATCore::ParticleType::ConvertedPhoton) { return getValueHistoAt(*m_G4OverAFII_converted, aeta); }
+        if      (ptype == PATCore::ParticleType::Electron)          { return getValueHistoAt(*m_G4OverAFII_electron, aeta); }
+        else if (ptype == PATCore::ParticleType::ConvertedPhoton)   { return getValueHistoAt(*m_G4OverAFII_converted, aeta); }
         else if (ptype == PATCore::ParticleType::UnconvertedPhoton) { return getValueHistoAt(*m_G4OverAFII_unconverted, aeta); }
         else { throw std::runtime_error("particle not valid"); }
       }
@@ -2109,10 +2283,9 @@ namespace AtlasRoot {
 
 
   // Frozen Showers -> G4 correction
-
   double egammaEnergyCorrectionTool::applyFStoG4(double eta) const {
 
-    double aeta = fabs(eta);
+    double aeta = std::abs(eta);
     if( aeta<3.3 || aeta>4.9 )
       return 1.;
 
@@ -2121,7 +2294,6 @@ namespace AtlasRoot {
   }
 
   // functions for energy scale corrections
-
   double egammaEnergyCorrectionTool::getAlphaZee(long int runnumber, double eta, egEnergyCorr::Scale::Variation var, double varSF) const {
 
     if (!m_zeeNom) {
@@ -2133,18 +2305,29 @@ namespace AtlasRoot {
     double value = m_zeeNom->GetBinContent(ieta);
 
     // for es2018_R21_v0 and v1 different set of scales for 2018, 2017, 2016 and 2015 data 
-    if ((m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1)  && runnumber<=341649 && runnumber>=324320){
+    if ((m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	 m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	&& runnumber<=341649 && runnumber>=324320){
       int ieta = m_zeeNom_data2017->GetXaxis()->FindBin(eta);
       value = m_zeeNom_data2017->GetBinContent(ieta);
     }
 
+    // low mu data 2017 5TeV differnet scale    
+    if (m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 &&
+	runnumber<=341184 && runnumber>=340634) {
+      int ieta = m_zeeNom_data2017->GetXaxis()->FindBin(eta);
+      value = m_zeeNom_data2017->GetBinContent(ieta); 
+    }
+    
      // for es2017_R21_v0 different set of scales for 2017, 2016 and 2015 data
     if ( m_esmodel == egEnergyCorr::es2017_R21_v0 && runnumber<322817 && runnumber>=297000) {
        int ieta = m_zeeNom_data2016->GetXaxis()->FindBin(eta);
        value = m_zeeNom_data2016->GetBinContent(ieta);
     }
     
-    if ( (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) && runnumber<322817 && runnumber>=297000) {
+    if ( (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	  m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	 runnumber<322817 && runnumber>=297000) {
       int ieta = m_zeeNom_data2016->GetXaxis()->FindBin(eta);
       value = m_zeeNom_data2016->GetBinContent(ieta);
     }
@@ -2164,15 +2347,20 @@ namespace AtlasRoot {
         value = m_zeeNom_data2018->GetBinContent(ieta);
     }
    
-    if ((m_esmodel==egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) && runnumber < 297000) {
+    if ((m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	 m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	 m_esmodel == egEnergyCorr::es2015_5TeV || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	runnumber < 297000) {
       // 2 sets of scales for this configuration
       // change histogram if 2015 data
       int ieta = m_zeeNom_data2015->GetXaxis()->FindBin(eta);
       value = m_zeeNom_data2015->GetBinContent(ieta);
     }
 
-    if (m_esmodel==egEnergyCorr::es2015PRE or m_esmodel==egEnergyCorr::es2015PRE_res_improved or
-        m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved) {
+    if (m_esmodel==egEnergyCorr::es2015PRE || m_esmodel==egEnergyCorr::es2015PRE_res_improved ||
+        m_esmodel == egEnergyCorr::es2015cPRE || m_esmodel == egEnergyCorr::es2015cPRE_res_improved) {
       // special case for es2015PRE
       // additional correction due to LAr temperature effect
       // for extrapolation 2012 -> 2015 temperature change
@@ -2195,7 +2383,7 @@ namespace AtlasRoot {
 
       // special case for es2015PRE
       // additional correction for uA->MeV first 2 weeks 2015 data
-      if (runnumber >= 266904 and runnumber <= 267639 and m_use_uA2MeV_2015_first2weeks_correction)
+      if (runnumber >= 266904 && runnumber <= 267639 && m_use_uA2MeV_2015_first2weeks_correction)
       {
         const double uA2MeV_correction = m_uA2MeV_2015_first2weeks_correction->GetBinContent(
                                            m_uA2MeV_2015_first2weeks_correction->FindFixBin(std::abs(eta)));
@@ -2205,13 +2393,13 @@ namespace AtlasRoot {
       }
     }  // end special case for es2015PRE*
 
-    if ((m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE) and m_use_temp_correction201215) {
+    if ((m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE) && m_use_temp_correction201215) {
       // keep the correction 2012->2015 for |eta| > 2.5
-      // if (eta > 2.5 and eta < 3.2) value += 0.;
-      if (eta < -2.5 and eta > -3.2) value += -0.45E-2;
+      // if (eta > 2.5 && eta < 3.2) value += 0.;
+      if (eta < -2.5 && eta > -3.2) value += -0.45E-2;
     }
 
-    if (m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE) { // correction for the extrapolation from es2015_summer
+    if (m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE) { // correction for the extrapolation from es2015_summer
       if (runnumber >= 297000) { // only for 2016 data
         if (eta >= 0) {  // side A
           if (eta < 1.45) value *= 1.00028;
@@ -2224,55 +2412,66 @@ namespace AtlasRoot {
       }
     }
 
+    ATH_MSG_DEBUG("getAlphaZee, def alpha " << value << " at eta = " << eta << " ieta = " << ieta);
 
-    if (var == egEnergyCorr::Scale::ZeeStatUp or var == egEnergyCorr::Scale::ZeeStatDown) {
+    if (var == egEnergyCorr::Scale::ZeeStatUp || var == egEnergyCorr::Scale::ZeeStatDown) {
       const double sign = (var == egEnergyCorr::Scale::ZeeStatUp) ? 1 : -1;
 
       TH1* h= ((TH1*)m_zeeNom.get());
       
-      if ((m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or 
-           m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or 
-           m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or 
-           m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) && runnumber < 297000){
+      if ((m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+           m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+           m_esmodel == egEnergyCorr::es2015_5TeV || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+           m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	   m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	   m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	  runnumber < 297000){
         h=((TH1*) m_zeeNom_data2015.get()); // special for 2015 with es2017
       }
-      if ( (m_esmodel== egEnergyCorr::es2017_R21_v0 || m_esmodel== egEnergyCorr::es2017_R21_v1 || 
-            m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) && runnumber>=297000 && runnumber<322817){
+      if ( (m_esmodel == egEnergyCorr::es2017_R21_v0 || m_esmodel== egEnergyCorr::es2017_R21_v1 ||
+            m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	    m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	   runnumber>=297000 && runnumber<322817){
         h = m_zeeNom_data2016.get(); // 2016 data
       }
-      if (  m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 && runnumber>347847) {
+      if (m_esmodel== egEnergyCorr::es2017_R21_ofc0_v1 && runnumber>347847) {
         h = m_zeeNom_data2018.get();
       }
-      if ( (m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) && runnumber>=324320 && runnumber<=341649 ){
-        h=((TH1*)m_zeeNom_data2017.get()); // 2017 data                                                                                                                                                                                
+      if ( (m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	    m_esmodel == egEnergyCorr::es2022_R21_Precision ) &&
+	   runnumber>=324320 && runnumber<=341649 ){
+        h=((TH1*)m_zeeNom_data2017.get()); // 2017 data                                                           
       }
+      if (m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 &&
+	  runnumber<=341184 && runnumber>=340634)
+	h=((TH1*)m_zeeNom_data2017.get()); // 2017 data 5TeV
+    
       double stat_error = h->GetBinError(h->FindFixBin(eta));
-	    if (m_use_stat_error_scaling) {
-        stat_error = stat_error / sqrt(h->GetNbinsX());
-	    }
-	    value += sign * stat_error * varSF;
+      if (m_use_stat_error_scaling) {
+        stat_error = stat_error / std::sqrt(h->GetNbinsX());
+      }
+      ATH_MSG_VERBOSE("getAlphaZee, adding " << sign * stat_error * varSF
+		      << " from " << stat_error << " and " << varSF
+		      << " at eta = " << eta << " ieta = " << h->FindFixBin(eta)
+		      << " err scaling ? " << m_use_stat_error_scaling);
+      value += sign * stat_error * varSF;
     }
     else if( var==egEnergyCorr::Scale::ZeeSystUp && m_zeeSyst ) {
       value += get_ZeeSyst(eta) * varSF;
-    
+      ATH_MSG_VERBOSE("getAlphaZee, adding " << get_ZeeSyst(eta) * varSF);
     } else if( var==egEnergyCorr::Scale::ZeeSystDown && m_zeeSyst ) {
       value -= get_ZeeSyst(eta) * varSF;
+      ATH_MSG_VERBOSE("getAlphaZee, adding " << -get_ZeeSyst(eta) * varSF);
     } else if( var==egEnergyCorr::Scale::ZeePhysUp && m_zeePhys ) {
-      
       ieta = m_zeePhys->GetXaxis()->FindBin( eta );
       value += m_zeePhys->GetBinContent(ieta) * varSF;
-
-
     } else if( var==egEnergyCorr::Scale::ZeePhysDown && m_zeePhys ) {
-
       ieta = m_zeePhys->GetXaxis()->FindBin( eta );
       value -= m_zeePhys->GetBinContent(ieta) * varSF;
-
-
     }
-    else if ((var == egEnergyCorr::Scale::LArTemperature2015PreUp or var == egEnergyCorr::Scale::LArTemperature2015PreDown) and
-             (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-              m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved) and
+    else if ((var == egEnergyCorr::Scale::LArTemperature2015PreUp || var == egEnergyCorr::Scale::LArTemperature2015PreDown) &&
+             (m_esmodel == egEnergyCorr::es2015PRE || m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+              m_esmodel == egEnergyCorr::es2015cPRE || m_esmodel == egEnergyCorr::es2015cPRE_res_improved) &&
              m_use_temp_correction201215)
     {
       // special case only for es2015PRE
@@ -2282,45 +2481,46 @@ namespace AtlasRoot {
       const double aeta = std::abs(eta);
       const double sign = (var == egEnergyCorr::Scale::LArTemperature2015PreUp) ? 1 : -1;
       if (aeta < 1.45) { value += 0.15E-2 * sign; }
-      else if (aeta > 1.45 and aeta < 3.2) { value += 0.25E-2 * sign; }
+      else if (aeta > 1.45 && aeta < 3.2) { value += 0.25E-2 * sign; }
     }
 
-    else if ((var == egEnergyCorr::Scale::LArTemperature2015PreUp or var == egEnergyCorr::Scale::LArTemperature2015PreDown) and
-             (m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE) and m_use_temp_correction201215) {
+    else if ((var == egEnergyCorr::Scale::LArTemperature2015PreUp || var == egEnergyCorr::Scale::LArTemperature2015PreDown) &&
+             (m_esmodel == egEnergyCorr::es2015c_summer || m_esmodel == egEnergyCorr::es2016PRE) && m_use_temp_correction201215) {
       // keep 2012->2015 extrapolation correction for eta > 2.5
       const double aeta = std::abs(eta);
       const double sign = (var == egEnergyCorr::Scale::LArTemperature2015PreUp) ? 1 : -1;
-      if (aeta > 2.5 and aeta < 3.2) { value += 0.25E-2 * sign; }
+      if (aeta > 2.5 && aeta < 3.2) { value += 0.25E-2 * sign; }
     }
 
 
-    else if ((var == egEnergyCorr::Scale::LArTemperature2016PreUp or var == egEnergyCorr::Scale::LArTemperature2016PreDown) and
-             (m_esmodel == egEnergyCorr::es2016PRE) and
+    else if ((var == egEnergyCorr::Scale::LArTemperature2016PreUp || var == egEnergyCorr::Scale::LArTemperature2016PreDown) &&
+             (m_esmodel == egEnergyCorr::es2016PRE) &&
              m_use_temp_correction201516)
     {
       // special case for es2016PRE (extrapolation from 2015)
         const double sign = (var == egEnergyCorr::Scale::LArTemperature2016PreUp) ? 1 : -1;
         // temp + pileup
-        value += qsum(0.05E-2, 0.02E-2) * sign; // Guillaume email 23/05/2016 + 26/5/2016
+	static constexpr double ivalue = std::hypot(0.05E-2, 0.02E-2);
+        value += ivalue * sign; // Guillaume email 23/05/2016 + 26/5/2016
     }
 
 
     else if( var==egEnergyCorr::Scale::ZeeAllDown || var==egEnergyCorr::Scale::ZeeAllUp ) {
 
       ieta = m_zeeNom->GetXaxis()->FindBin( eta );
-      double diff = pow(m_zeeNom->GetBinError(ieta) * varSF, 2);
+      double diff = std::pow(m_zeeNom->GetBinError(ieta) * varSF, 2);
 
       if( m_zeeSyst ) {
-	diff += pow(get_ZeeSyst(eta) * varSF, 2);
+	diff += std::pow(get_ZeeSyst(eta) * varSF, 2);
       }
 
       if( m_zeePhys ) {
         ieta = m_zeePhys->GetXaxis()->FindBin(eta);
-        diff += pow(m_zeePhys->GetBinContent(ieta) * varSF, 2);
+        diff += std::pow(m_zeePhys->GetBinContent(ieta) * varSF, 2);
       }
 
-      if( var==egEnergyCorr::Scale::ZeeAllUp ) value += sqrt(diff);
-      else if( var==egEnergyCorr::Scale::ZeeAllDown ) value -= sqrt(diff);
+      if( var==egEnergyCorr::Scale::ZeeAllUp ) value += std::sqrt(diff);
+      else if( var==egEnergyCorr::Scale::ZeeAllDown ) value -= std::sqrt(diff);
     }
 
     return value;
@@ -2330,7 +2530,7 @@ namespace AtlasRoot {
 
   double egammaEnergyCorrectionTool::getE4Uncertainty(double eta) const {
     const double aeta = std::abs(eta);
-    if ((aeta > 1.6) or (aeta < 1.4)) { return 0.; }
+    if ((aeta > 1.6) || (aeta < 1.4)) { return 0.; }
 
     // numbers from Archil 20/5/2016
 
@@ -2364,14 +2564,14 @@ namespace AtlasRoot {
     double B = m_wstot_slope_B_MC->GetBinContent(bin);
 
     //the wstot=f(pT) depends on the particle type
-    double ETGeV = energy / cosh(cl_eta) / 1E3;
+    double ETGeV = energy / std::cosh(cl_eta) / 1E3;
     double wstot_pT_data_p0 = 0.;
     double wstot_pT_data_p1 = 0.;
     double wstot_pT_MC_p0 = 0.;
     double wstot_pT_MC_p1 = 0.;
 
-    double wstot_40_data = m_wstot_pT_data_p0_electrons->GetBinContent(bin) + (m_wstot_pT_data_p1_electrons->GetBinContent(bin))/sqrt(40.);
-    double wstot_40_MC   = m_wstot_pT_MC_p0_electrons->GetBinContent(bin) + (m_wstot_pT_MC_p1_electrons->GetBinContent(bin))/sqrt(40.);
+    double wstot_40_data = m_wstot_pT_data_p0_electrons->GetBinContent(bin) + (m_wstot_pT_data_p1_electrons->GetBinContent(bin))/std::sqrt(40.);
+    double wstot_40_MC   = m_wstot_pT_MC_p0_electrons->GetBinContent(bin) + (m_wstot_pT_MC_p1_electrons->GetBinContent(bin))/std::sqrt(40.);
 
     if (ptype == PATCore::ParticleType::Electron ) {
       wstot_pT_data_p0 = m_wstot_pT_data_p0_electrons->GetBinContent(bin);
@@ -2404,8 +2604,8 @@ namespace AtlasRoot {
     //flat uncertainty below 25 GeV
     if(ETGeV<25.) ETGeV = 25.;
 
-    wstot_pT_data = wstot_pT_data_p0+wstot_pT_data_p1/sqrt(ETGeV);
-    wstot_pT_MC = wstot_pT_MC_p0+wstot_pT_MC_p1/sqrt(ETGeV);
+    wstot_pT_data = wstot_pT_data_p0+wstot_pT_data_p1/std::sqrt(ETGeV);
+    wstot_pT_MC = wstot_pT_MC_p0+wstot_pT_MC_p1/std::sqrt(ETGeV);
 
     value = 2*A/91.2*(wstot_pT_data-wstot_40_data) - 2*B/91.2*(wstot_pT_MC-wstot_40_MC);
 
@@ -2420,7 +2620,7 @@ namespace AtlasRoot {
   double egammaEnergyCorrectionTool::getLayerUncertainty( int iLayer,
 							  double cl_eta,
 							  egEnergyCorr::Scale::Variation var,
-                double varSF) const {
+							  double varSF) const {
 
     double value = 0.;
 
@@ -2453,16 +2653,22 @@ namespace AtlasRoot {
 
     else if( iLayer==1 ) { // use cl_eta
 
-      if (var == egEnergyCorr::Scale::S12Up && m_aS12Nom)	{ value = m_aS12Nom->GetBinError(m_aS12Nom->FindBin(cl_eta)); }
-      else if (var == egEnergyCorr::Scale::S12Down && m_aS12Nom) { value = -m_aS12Nom->GetBinError(m_aS12Nom->FindBin(cl_eta)); }
-      else if (var == egEnergyCorr::Scale::LArCalibUp && m_daS12Cor) { value = m_daS12Cor->GetBinContent(m_daS12Cor->FindBin(cl_eta)); }
+      if (var == egEnergyCorr::Scale::S12Up && m_aS12Nom)	       { value = m_aS12Nom->GetBinError(m_aS12Nom->FindBin(cl_eta)); }
+      else if (var == egEnergyCorr::Scale::S12Down && m_aS12Nom)       { value = -m_aS12Nom->GetBinError(m_aS12Nom->FindBin(cl_eta)); }
+      else if (var == egEnergyCorr::Scale::LArCalibUp && m_daS12Cor)   { value = m_daS12Cor->GetBinContent(m_daS12Cor->FindBin(cl_eta)); }
       else if (var == egEnergyCorr::Scale::LArCalibDown && m_daS12Cor) { value = -m_daS12Cor->GetBinContent( m_daS12Cor->FindBin(cl_eta)); }
-      else if (var == egEnergyCorr::Scale::LArCalibExtra2015PreUp and 
-	       (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-		m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-		m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017
-		or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_R21_PRE
-		or m_esmodel == egEnergyCorr::es2015_5TeV)) { 
+      else if (var == egEnergyCorr::Scale::LArCalibExtra2015PreUp &&
+	       (m_esmodel == egEnergyCorr::es2015PRE ||
+		m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+		m_esmodel == egEnergyCorr::es2015cPRE ||
+		m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+		m_esmodel == egEnergyCorr::es2015c_summer ||
+		m_esmodel == egEnergyCorr::es2016PRE ||
+		m_esmodel == egEnergyCorr::es2017 ||
+		m_esmodel == egEnergyCorr::es2017_summer ||
+		m_esmodel == egEnergyCorr::es2017_summer_improved ||
+		m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+		m_esmodel == egEnergyCorr::es2015_5TeV)) {
 	// special case for es2015PRE and also for es2015c_summer and also for es2017
 	// numbers from Lydia and Christophe,
 	// https://indico.cern.ch/event/395345/contribution/2/material/slides/0.pdf
@@ -2470,8 +2676,11 @@ namespace AtlasRoot {
 	// es2017_summer: increased to 5% in the endcap
 	const double aeta = std::abs(cl_eta); 
 	//endcap
-	if ( aeta >= 1.37 and aeta < 2.5){
-	  if ( m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV) value = 5.0E-2;
+	if (aeta >= 1.37 && aeta < 2.5) {
+	  if ( m_esmodel == egEnergyCorr::es2017_summer ||
+	       m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	       m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	       m_esmodel == egEnergyCorr::es2015_5TeV) value = 5.0E-2;
 	  else value = 1.5E-2;
 	}
 	else{//barrel
@@ -2479,29 +2688,43 @@ namespace AtlasRoot {
 	  else value = 1.5E-2;
 	}
       }
-      else if (var == egEnergyCorr::Scale::LArCalibExtra2015PreDown and
-               (m_esmodel == egEnergyCorr::es2015PRE or m_esmodel == egEnergyCorr::es2015PRE_res_improved or
-                m_esmodel == egEnergyCorr::es2015cPRE or m_esmodel == egEnergyCorr::es2015cPRE_res_improved or
-                m_esmodel == egEnergyCorr::es2015c_summer or m_esmodel == egEnergyCorr::es2016PRE or m_esmodel == egEnergyCorr::es2017
-		or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_R21_PRE
-		or m_esmodel == egEnergyCorr::es2015_5TeV)) {
+      else if (var == egEnergyCorr::Scale::LArCalibExtra2015PreDown &&
+               (m_esmodel == egEnergyCorr::es2015PRE ||
+		m_esmodel == egEnergyCorr::es2015PRE_res_improved ||
+                m_esmodel == egEnergyCorr::es2015cPRE ||
+		m_esmodel == egEnergyCorr::es2015cPRE_res_improved ||
+                m_esmodel == egEnergyCorr::es2015c_summer ||
+		m_esmodel == egEnergyCorr::es2016PRE ||
+		m_esmodel == egEnergyCorr::es2017 ||
+		m_esmodel == egEnergyCorr::es2017_summer ||
+		m_esmodel == egEnergyCorr::es2017_summer_improved ||
+		m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+		m_esmodel == egEnergyCorr::es2015_5TeV)) {
 	const double aeta = std::abs(cl_eta);  
         //endcap 
-        if ( aeta >= 1.37 and aeta < 2.5){ 
-          if ( m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV) value = -5.0E-2; 
-          else value = -1.5E-2; 
+        if (aeta >= 1.37 && aeta < 2.5) {
+          if ( m_esmodel == egEnergyCorr::es2017_summer ||
+	       m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	       m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	       m_esmodel == egEnergyCorr::es2015_5TeV) value = -5.0E-2;
+          else value = -1.5E-2;
         } 
         else{//barrel 
-          if (m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2015_5TeV) value = -2.5E-2; 
-          else value = -1.5E-2; 
+          if (m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	      m_esmodel == egEnergyCorr::es2015_5TeV) value = -2.5E-2;
+          else value = -1.5E-2;
         } 
       }
       
-      else if (var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up or var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down) {
+      else if (var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up || var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down) {
         // special large sys for run2 in the last eta-bin in es2017, see ATLASEG-42
-        if (m_esmodel == egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV) {
+        if (m_esmodel == egEnergyCorr::es2017 ||
+	    m_esmodel == egEnergyCorr::es2017_summer ||
+	    m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	    m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	    m_esmodel == egEnergyCorr::es2015_5TeV) {
 	  const double aeta = std::abs(cl_eta);
-	  if (aeta >= 2.4 and aeta < 2.5) {
+	  if (aeta >= 2.4 && aeta < 2.5) {
 	    if (var == egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up) value = 25E-2;
 	    else value = -25E-2;
 	  }
@@ -2510,7 +2733,6 @@ namespace AtlasRoot {
 
     }
 
-
     return value * varSF;
 
   }
@@ -2520,7 +2742,7 @@ namespace AtlasRoot {
   {
     double value = 0;
     const double aeta = std::abs(cl_eta);
-    const double ETGeV = energy / cosh(cl_eta) / 1E3;
+    const double ETGeV = energy / std::cosh(cl_eta) / 1E3;
 
     //This will point to the return of get() of a unique_ptr
     TAxis* axis;
@@ -2544,7 +2766,7 @@ namespace AtlasRoot {
 
 
     const int ieta = axis->FindFixBin(aeta) - 1;
-    if (ieta >= 0 and ieta < graphs->GetSize()) {
+    if (ieta >= 0 && ieta < graphs->GetSize()) {
       value = static_cast<TGraph*>(graphs->At(ieta))->Eval(ETGeV);
     }
 
@@ -2557,8 +2779,8 @@ namespace AtlasRoot {
 							   PATCore::ParticleType::Type ptype ) const {
 
     double value = 0;
-    double aeta = fabs(cl_eta);
-    double ET = energy/cosh(cl_eta);
+    double aeta = std::abs(cl_eta);
+    double ET = energy/std::cosh(cl_eta);
 
     // move out of crack
     aeta = nearestEtaBEC(aeta);
@@ -2573,13 +2795,13 @@ namespace AtlasRoot {
       if( iLayer==0 ) {
 
 	const int ieta = m_psElectronEtaBins->FindFixBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_psElectronGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_psElectronGraphs->GetSize()) {
 	  value = ((TF1*)m_psElectronGraphs->At(ieta))->Eval( ET );
 	}
       } else if( iLayer==1 ) {
 
 	const int ieta = m_s12ElectronEtaBins->FindFixBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_s12ElectronGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_s12ElectronGraphs->GetSize()) {
 	  value = ((TF1*)m_s12ElectronGraphs->At(ieta))->Eval( ET );
 	}
       }
@@ -2589,14 +2811,14 @@ namespace AtlasRoot {
       if( iLayer==0 ) {
 
 	const int ieta = m_psUnconvertedEtaBins->FindBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_psUnconvertedGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_psUnconvertedGraphs->GetSize()) {
 	  value = ((TF1*)m_psUnconvertedGraphs->At(ieta))->Eval( ET );
 	}
 
       } else if( iLayer==1 ) {
 
 	const int ieta = m_s12UnconvertedEtaBins->FindBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_s12UnconvertedGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_s12UnconvertedGraphs->GetSize()) {
 	  value = ((TF1*)m_s12UnconvertedGraphs->At(ieta))->Eval( ET );
 	}
       }
@@ -2606,14 +2828,14 @@ namespace AtlasRoot {
       if( iLayer==0 ) {
 
 	const int ieta = m_psConvertedEtaBins->FindBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_psConvertedGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_psConvertedGraphs->GetSize()) {
 	  value = ((TF1*)m_psConvertedGraphs->At(ieta))->Eval( ET );
 	}
 
       } else if( iLayer==1 ) {
 
 	const int ieta = m_s12ConvertedEtaBins->FindBin( aeta ) - 1;
-	if (ieta >= 0 and ieta < m_s12ConvertedGraphs->GetSize()) {
+	if (ieta >= 0 && ieta < m_s12ConvertedGraphs->GetSize()) {
 	  value = ((TF1*)m_s12ConvertedGraphs->At(ieta))->Eval( ET );
 	}
       }
@@ -2634,13 +2856,12 @@ namespace AtlasRoot {
   //////////////////////////////
 
   // ... material look-up function, called internally by getAlphaMaterial() and getMaterialNonLinearity()
-
   double egammaEnergyCorrectionTool::getDeltaX( double cl_eta,
 						egEnergyCorr::MaterialCategory imat,
 						egEnergyCorr::Scale::Variation var ) const {
 
     double value = 0.;
-    double aeta = fabs(cl_eta);
+    double aeta = std::abs(cl_eta);
 
     // "ID" : inner detector material; bottom-up (from construction/simulation accuracy : ConfigA)
 
@@ -2735,7 +2956,6 @@ namespace AtlasRoot {
   //   I.e : DX_M = DX_Meas +- dMeas
 
   // Then calculate the impact on the scale accordingly.
-
   double egammaEnergyCorrectionTool::getAlphaMaterial( double cl_eta,
 						       egEnergyCorr::MaterialCategory imat,
 						       PATCore::ParticleType::Type ptype,
@@ -2749,7 +2969,7 @@ namespace AtlasRoot {
 
     egEnergyCorr::Geometry geoID, geoCryo, geoCalo, geoGp;
     geoID = egEnergyCorr::ConfigA;
-    if( fabs(cl_eta)<2. )
+    if( std::abs(cl_eta)<2. )
       geoCryo = egEnergyCorr::ConfigEL;
     else
       geoCryo = egEnergyCorr::ConfigFMX;
@@ -2790,27 +3010,25 @@ namespace AtlasRoot {
 
     // normal case
 
-    int idx = m_matX0Additions[geoID]->FindBin( fabs(cl_eta) );
+    int idx = m_matX0Additions[geoID]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoID]->GetNbinsX())
       DAlphaDXID = 0;
     else
       DAlphaDXID /= m_matX0Additions[geoID]->GetBinContent(idx);
 
-    idx = m_matX0Additions[geoCryo]->FindBin( fabs(cl_eta) );
+    idx = m_matX0Additions[geoCryo]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoCryo]->GetNbinsX())
       DAlphaDXCryo = 0;
     else
       DAlphaDXCryo /= m_matX0Additions[geoCryo]->GetBinContent(idx);
 
-    idx = m_matX0Additions[geoCalo]->FindBin( fabs(cl_eta) );
+    idx = m_matX0Additions[geoCalo]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoCalo]->GetNbinsX())
       DAlphaDXCalo = 0;
     else
       DAlphaDXCalo /= m_matX0Additions[geoCalo]->GetBinContent(idx);
 
     // final value
-
-
     if( imat==egEnergyCorr::MatID )
       value = DeltaX * (DAlphaDXID - DAlphaDXCryo);
     else if( imat==egEnergyCorr::MatCryo )
@@ -2818,17 +3036,16 @@ namespace AtlasRoot {
     else if( imat==egEnergyCorr::MatCalo )
       value = DeltaX * DAlphaDXCalo;
 
-
     return value * varSF;
 
   }
 
-double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,PATCore::ParticleType::Type ptype,double cl_eta,double ET) const {
+  double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,PATCore::ParticleType::Type ptype,double cl_eta,double ET) const {
  
-  //Again this does no need to be ptr just get the one owned
-   TH2D* hmat;
-
-   if (ptype==PATCore::ParticleType::Electron) {
+    //Again this does no need to be ptr just get the one owned
+    TH2D* hmat;
+    
+    if (ptype==PATCore::ParticleType::Electron) {
       if (geo==egEnergyCorr::ConfigA) hmat=((TH2D*) m_electronBias_ConfigA.get());
       else if (geo==egEnergyCorr::ConfigEL) hmat=((TH2D*)m_electronBias_ConfigEpLp.get());
       else if (geo==egEnergyCorr::ConfigFMX) hmat=((TH2D*)m_electronBias_ConfigFpMX.get());
@@ -2836,7 +3053,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       else if (geo==egEnergyCorr::ConfigIBL) hmat=((TH2D*)m_electronBias_ConfigIBL.get());
       else if (geo==egEnergyCorr::ConfigPP0) hmat=((TH2D*)m_electronBias_ConfigPP0.get());
       else return 0;
-   } else if (ptype==PATCore::ParticleType::UnconvertedPhoton) {
+    } else if (ptype==PATCore::ParticleType::UnconvertedPhoton) {
       if (geo==egEnergyCorr::ConfigA) hmat=((TH2D*)m_unconvertedBias_ConfigA.get());
       else if (geo==egEnergyCorr::ConfigEL) hmat=((TH2D*)m_unconvertedBias_ConfigEpLp.get());
       else if (geo==egEnergyCorr::ConfigFMX) hmat=((TH2D*)m_unconvertedBias_ConfigFpMX.get());
@@ -2844,7 +3061,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       else if (geo==egEnergyCorr::ConfigIBL) hmat=((TH2D*)m_unconvertedBias_ConfigIBL.get());
       else if (geo==egEnergyCorr::ConfigPP0) hmat=((TH2D*)m_unconvertedBias_ConfigIBL.get());
       else return 0;
-   } else if (ptype==PATCore::ParticleType::ConvertedPhoton) {
+    } else if (ptype==PATCore::ParticleType::ConvertedPhoton) {
       if (geo==egEnergyCorr::ConfigA) hmat=((TH2D*)m_convertedBias_ConfigA.get());
       else if (geo==egEnergyCorr::ConfigEL) hmat=((TH2D*)m_convertedBias_ConfigEpLp.get());
       else if (geo==egEnergyCorr::ConfigFMX) hmat=((TH2D*)m_convertedBias_ConfigFpMX.get());
@@ -2852,75 +3069,76 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       else if (geo==egEnergyCorr::ConfigIBL) hmat=((TH2D*)m_convertedBias_ConfigIBL.get());
       else if (geo==egEnergyCorr::ConfigPP0) hmat=((TH2D*)m_convertedBias_ConfigPP0.get());
       else return 0;
-   } else return 0;
-
-
-
-   
-
-   // use one bin in eta and linear interpolation in Et between 2 bins
-
-  double aeta=fabs(cl_eta);
-  int ieta = hmat->GetXaxis()->FindBin(aeta);
-
-  int ipt = hmat->GetYaxis()->FindBin(ET);
-  double ptBin = hmat->GetYaxis()->GetBinCenter(ipt);
-
-  int i1,i2;
-  double pt1,pt2;
-   if (ET>ptBin) {
+    } else return 0;
+    
+    
+    // use one bin in eta and linear interpolation in Et between 2 bins
+    double aeta=std::abs(cl_eta);
+    int ieta = hmat->GetXaxis()->FindBin(aeta);
+    
+    int ipt = hmat->GetYaxis()->FindBin(ET);
+    double ptBin = hmat->GetYaxis()->GetBinCenter(ipt);
+    
+    int i1,i2;
+    double pt1,pt2;
+    if (ET>ptBin) {
       i1=ipt;
       i2=ipt+1;
       pt1=ptBin;
       pt2= hmat->GetYaxis()->GetBinCenter(i2);
+    }
+    else {
+      i1=ipt-1;
+      i2=ipt;
+      pt1=hmat->GetYaxis()->GetBinCenter(i1);
+      pt2=ptBin;
+    }
+    
+    int nbins=hmat->GetYaxis()->GetNbins();
+    double value=0;
+    if (i1>=1 && i1 < nbins) {
+      double v1 = hmat->GetBinContent(ieta,i1);
+      double v2 = hmat->GetBinContent(ieta,i2);
+      value =  (v1*(pt2-ET) + v2*(ET-pt1)) / (pt2-pt1);
+    }
+    else{
+      if (ipt<1) ipt=1;
+      if (ipt>nbins) ipt=nbins;
+      value=hmat->GetBinContent(ieta,ipt);
+    }
+    return value;
+    
   }
-  else {
-     i1=ipt-1;
-     i2=ipt;
-     pt1=hmat->GetYaxis()->GetBinCenter(i1);
-     pt2=ptBin;
-  }
-
-  int nbins=hmat->GetYaxis()->GetNbins();
-  double value=0;
-  if (i1>=1 && i1 < nbins) {
-    double v1 = hmat->GetBinContent(ieta,i1);
-    double v2 = hmat->GetBinContent(ieta,i2);
-    value =  (v1*(pt2-ET) + v2*(ET-pt1)) / (pt2-pt1);
-  }
-  else{
-    if (ipt<1) ipt=1;
-    if (ipt>nbins) ipt=nbins;
-    value=hmat->GetBinContent(ieta,ipt);
-  }
-  return value;
-
-}
-
-
+  
   // returns the energy dependence of the above (non-zero for electrons only).
-
   double egammaEnergyCorrectionTool::getMaterialNonLinearity( double cl_eta, double energy,
 							      egEnergyCorr::MaterialCategory imat,
 							      PATCore::ParticleType::Type ptype,
 							      egEnergyCorr::Scale::Variation var, double varSF ) const {
 
     double value = 0;
-    double ET = energy/cosh(cl_eta)/GeV;
+    double ET = energy/std::cosh(cl_eta)/GeV;
 
-    if( (ptype!=PATCore::ParticleType::Electron && (m_esmodel != egEnergyCorr::es2017_R21_v1 && m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 && m_esmodel != egEnergyCorr::es2018_R21_v0 &&  m_esmodel !=egEnergyCorr::es2018_R21_v1) )  || var==egEnergyCorr::Scale::Nominal )
+    if( (ptype!=PATCore::ParticleType::Electron &&
+	 (m_esmodel != egEnergyCorr::es2017_R21_v1 && m_esmodel != egEnergyCorr::es2017_R21_ofc0_v1 &&
+	  m_esmodel != egEnergyCorr::es2018_R21_v0 && m_esmodel != egEnergyCorr::es2018_R21_lowmu_v0 &&
+	  m_esmodel != egEnergyCorr::es2018_R21_v1 && m_esmodel != egEnergyCorr::es2022_R21_Precision) ) ||
+	var==egEnergyCorr::Scale::Nominal )
       return value;
 
     egEnergyCorr::Geometry geoID, geoCryo, geoCalo, geoGp;
     geoID = egEnergyCorr::ConfigA;
-    if( fabs(cl_eta)<2. )
+    if( std::abs(cl_eta)<2. )
       geoCryo = egEnergyCorr::ConfigEL;
     else
       geoCryo = egEnergyCorr::ConfigFMX;
 
     //   G.Unal 21.08.2018
     // for Calo material use correctly ConfigN material for endcap (PS to Calo) in release 21 (not done for run 1, which used FMX in this case)
-    if (fabs(cl_eta)>1.52 && (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||  m_esmodel == egEnergyCorr::es2018_R21_v1))
+    if (std::abs(cl_eta)>1.52 &&
+	(m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	 m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision ))
       geoCalo = egEnergyCorr::ConfigN;
     else   
       geoCalo = egEnergyCorr::ConfigFMX;
@@ -2930,21 +3148,21 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
     double DeltaX = getDeltaX(cl_eta, imat, var) - getDeltaX(cl_eta, imat, egEnergyCorr::Scale::Nominal);
 
-
     // calculate scale change per unit added material
 
     // G.Unal 21.08.2019 new code called for release 21 sensivitities
-
     double DAlphaDXGp,DAlphaDXID,DAlphaDXCryo,DAlphaDXCalo;
 
-    if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 ||  m_esmodel == egEnergyCorr::es2018_R21_v1) {
+    if (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision ) {
        DAlphaDXGp = getMaterialEffect(egEnergyCorr::ConfigFMX,ptype,cl_eta,ET);   // no G' in release 21, use FMX for the crack
        DAlphaDXID = getMaterialEffect(geoID,ptype,cl_eta,ET);
        DAlphaDXCryo = getMaterialEffect(geoCryo,ptype,cl_eta,ET);
        DAlphaDXCalo = getMaterialEffect(geoCalo,ptype,cl_eta,ET);
 
     } else {
-      int ialpha = m_matElectronEtaBins->FindBin( fabs(cl_eta) ) - 1;
+      int ialpha = m_matElectronEtaBins->FindBin( std::abs(cl_eta) ) - 1;
       if (ialpha<0 || ialpha>=m_matElectronGraphs[geoGp]->GetSize())
         return 0.;
 
@@ -2956,7 +3174,6 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
 
     // when in crack, use G', exit
-
     if( isInCrack(cl_eta) ) {
       if( imat==egEnergyCorr::MatID && var==egEnergyCorr::Scale::MatIDUp )
 	value = DAlphaDXGp;
@@ -2965,7 +3182,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       return value;
     }
 
-    int idx = m_matX0Additions[geoID]->FindBin( fabs(cl_eta) );
+    int idx = m_matX0Additions[geoID]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoID]->GetNbinsX())
       DAlphaDXID = 0;
     else
@@ -2974,7 +3191,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       else DAlphaDXID=0.;
     }
 
-    idx = m_matX0Additions[geoCryo]->FindBin( fabs(cl_eta) );
+    idx = m_matX0Additions[geoCryo]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoCryo]->GetNbinsX())
       DAlphaDXCryo = 0;
     else
@@ -2983,7 +3200,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
       else DAlphaDXCryo=0.;
     }
 
-    idx = m_matX0Additions[geoCalo]->FindBin( fabs(cl_eta) );
+    idx = m_matX0Additions[geoCalo]->FindBin( std::abs(cl_eta) );
     if(idx<1 || idx>m_matX0Additions[geoCalo]->GetNbinsX())
       DAlphaDXCalo = 0;
     else
@@ -2993,7 +3210,6 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     }
 
     // final value
-
     if( imat==egEnergyCorr::MatID )
       value = DeltaX * (DAlphaDXID - DAlphaDXCryo);
     else if( imat==egEnergyCorr::MatCryo )
@@ -3001,22 +3217,19 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     else if( imat==egEnergyCorr::MatCalo )
       value = DeltaX * DAlphaDXCalo;
 
-
     return value * varSF;
 
   }
 
 
-
   double egammaEnergyCorrectionTool::getAlphaLeakage(double cl_eta, PATCore::ParticleType::Type ptype,
 						     egEnergyCorr::Scale::Variation var, double varSF) const {
 
-    double alpha = 0.;
-    double aeta = fabs(cl_eta);
-
     if( var==egEnergyCorr::Scale::Nominal || ptype==PATCore::ParticleType::Electron )
-      return alpha;
+      return 0.;
 
+    double alpha = 0.;
+    double aeta = std::abs(cl_eta);
     if( ptype==PATCore::ParticleType::UnconvertedPhoton ) {
 
       if( var==egEnergyCorr::Scale::LeakageUnconvUp ) {
@@ -3039,33 +3252,163 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
   }
 
-  double egammaEnergyCorrectionTool::getAlphaConvSyst(double cl_eta, double energy, PATCore::ParticleType::Type ptype,
-						      egEnergyCorr::Scale::Variation var, double varSF) const {
+  double egammaEnergyCorrectionTool::getAlphaLeakage2D(double cl_eta, double et,
+						       PATCore::ParticleType::Type ptype,
+						       egEnergyCorr::Scale::Variation var,
+						       double varSF) const {
+
+    // To be on the safe side
+    if (m_esmodel != egEnergyCorr::es2022_R21_Precision) {
+      return getAlphaLeakage(cl_eta, ptype, var, varSF);
+    }
+
+    // Outside acceptance. Should never happen
+    double aeta = std::abs(cl_eta);
+    if (aeta > 2.47) {
+      ATH_MSG_WARNING("Very high |eta| object, eta = " << cl_eta);
+      return 0.;
+    }
+
+    // No correction for electron
+    if (ptype == PATCore::ParticleType::Electron &&
+	var != egEnergyCorr::Scale::LeakageElecDown &&
+	var != egEnergyCorr::Scale::LeakageElecUp)
+      return 0.;
+
+    // If no correction applied, can only be the egEnergyCorr::Scale::LeakageXXX syst
+    if (!m_useLeakageCorrection &&
+	var != egEnergyCorr::Scale::LeakageConvDown &&
+	var != egEnergyCorr::Scale::LeakageConvUp &&
+	var != egEnergyCorr::Scale::LeakageUnconvDown &&
+	var != egEnergyCorr::Scale::LeakageUnconvUp &&
+	var != egEnergyCorr::Scale::LeakageElecDown &&
+	var != egEnergyCorr::Scale::LeakageElecUp)
+      return 0.;
+
+    double etGeV = et/GeV;
+    double alpha = 0, dalpha = 0;
+    if (var == egEnergyCorr::Scale::LeakageElecDown ||
+	var == egEnergyCorr::Scale::LeakageElecUp) {
+      dalpha = getAlphaUncAlpha(m_leakageElectron.get(),aeta,etGeV,
+				m_usepTInterpolationForLeakage).first;
+      if (var == egEnergyCorr::Scale::LeakageElecDown)
+	dalpha *= -1;
+      if (ptype == PATCore::ParticleType::Electron)
+	return dalpha;
+    }
+
+    bool isConv = ptype == PATCore::ParticleType::ConvertedPhoton;
+    TH1 *hh = isConv ? m_leakageConverted.get() : m_leakageUnconverted.get();
+    std::pair<double,double> p = getAlphaUncAlpha(hh,aeta,etGeV,
+						  m_usepTInterpolationForLeakage);
+
+    if (m_useLeakageCorrection) {
+      alpha = p.first;
+    }
+    if ( (isConv &&
+	  (var == egEnergyCorr::Scale::LeakageConvDown ||
+	   var == egEnergyCorr::Scale::LeakageConvUp)) ||
+	 (!isConv &&
+	  (var == egEnergyCorr::Scale::LeakageUnconvDown ||
+	   var == egEnergyCorr::Scale::LeakageUnconvUp)) ) {
+      // If we correct, use uncertainty. Else use full size of the effect
+      if (m_useLeakageCorrection)
+	dalpha = p.second;
+      else
+	dalpha = alpha;
+
+      if (var == egEnergyCorr::Scale::LeakageConvDown ||
+	  var == egEnergyCorr::Scale::LeakageUnconvDown)
+	dalpha *= -1;
+    }
+    alpha += dalpha;
+
+    ATH_MSG_VERBOSE("In leakage2D alpha = " << alpha
+		    << " from var = " << variationName(var));
+
+    return alpha*varSF;
+  }
+
+  std::pair<double,double> egammaEnergyCorrectionTool::getAlphaUncAlpha(
+      TH1 *hh, double aeta, double et, bool useInterp) const {
+
+    // stay within the histogram limits in pT
+    // no warning to say the pT is not in the "validity" range...
+    int ibeta = hh->GetXaxis()->FindBin(aeta);
+    int nbpT  = hh->GetYaxis()->GetNbins();
+    int ibpT  = hh->GetYaxis()->FindBin(et);
+    bool isOUFlow = false;
+    if (ibpT > nbpT) {
+      ibpT = nbpT;
+      isOUFlow = true;
+    } else if (ibpT == 0) {
+      ibpT = 1;
+      isOUFlow = true;
+    }
+    double alpha = 0.;
+    double pTp = hh->GetYaxis()->GetBinCenter(ibpT), pTn = pTp;
+    if (!useInterp || isOUFlow || (ibpT == nbpT && et > pTp) || (ibpT == 1 && et < pTp)) 
+      alpha = hh->GetBinContent(ibeta,ibpT);
+    else {
+      int jp = ibpT, jn = ibpT-1;
+      if (et > pTp) {
+	jp = ibpT + 1;
+	jn = ibpT;
+	pTn = pTp;
+	pTp = hh->GetYaxis()->GetBinCenter(jp);
+      } else {
+	pTn = hh->GetYaxis()->GetBinCenter(jn);
+      }
+      double aPos = hh->GetBinContent(ibeta,jp);
+      double aNeg = hh->GetBinContent(ibeta,jn);
+      alpha = (aPos*(et-pTn) + aNeg*(pTp-et)) / (pTp - pTn);
+      ATH_MSG_VERBOSE("interp et = " << et << " alpha+ = " << aPos << " alpha- = " << aNeg << " alpha = " << alpha);
+    }
+    double dalpha = hh->GetBinError(ibeta,ibpT);
+
+    return std::make_pair(alpha,dalpha);
+  }
+
+  double egammaEnergyCorrectionTool::getAlphaConvSyst(double cl_eta, double energy,
+						      PATCore::ParticleType::Type ptype,
+						      egEnergyCorr::Scale::Variation var,
+						      double varSF) const {
 
     double alpha = 0.;
-    double aeta = fabs(cl_eta);
-    double ET = energy/cosh(cl_eta)/GeV;
+    double aeta  = std::abs(cl_eta);
+    // If the acceptance cut is on etaS2, cluster eta might be above...
+    if (aeta > 2.37)
+      aeta = 2.36;
+    double ET    = energy/std::cosh(cl_eta);
 
-    if( var==egEnergyCorr::Scale::Nominal || ptype==PATCore::ParticleType::Electron )
+    if (var == egEnergyCorr::Scale::Nominal || ptype == PATCore::ParticleType::Electron)
       return alpha;
 
-    if( ptype==PATCore::ParticleType::UnconvertedPhoton ) {
+    if (ptype == PATCore::ParticleType::UnconvertedPhoton) {
 
-      if( var==egEnergyCorr::Scale::ConvEfficiencyUp )
+      if (var == egEnergyCorr::Scale::ConvEfficiencyUp && m_esmodel != egEnergyCorr::es2022_R21_Precision)
 	alpha =  m_convRecoEfficiency->GetBinContent( m_convRecoEfficiency->FindBin(aeta) );
-      else if( var==egEnergyCorr::Scale::ConvEfficiencyDown )
+      else if (var == egEnergyCorr::Scale::ConvEfficiencyDown && m_esmodel != egEnergyCorr::es2022_R21_Precision)
 	alpha = -m_convRecoEfficiency->GetBinContent( m_convRecoEfficiency->FindBin(aeta) );
+      else if (var == egEnergyCorr::Scale::ConvRecoUp && m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	alpha =  m_convRecoEfficiency->GetBinContent( m_convRecoEfficiency->FindBin(aeta,ET) );
+      else if (var == egEnergyCorr::Scale::ConvRecoDown && m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	alpha = -m_convRecoEfficiency->GetBinContent( m_convRecoEfficiency->FindBin(aeta,ET) );
 
-    } else if( ptype==PATCore::ParticleType::ConvertedPhoton ) {
+    } else if (ptype==PATCore::ParticleType::ConvertedPhoton) {
 
-      if( var==egEnergyCorr::Scale::ConvFakeRateUp )
+      if (var == egEnergyCorr::Scale::ConvFakeRateUp && m_esmodel != egEnergyCorr::es2022_R21_Precision)
 	alpha =  m_convFakeRate->GetBinContent( m_convFakeRate->FindBin(aeta) );
-      else if( var==egEnergyCorr::Scale::ConvFakeRateDown )
+      else if (var == egEnergyCorr::Scale::ConvFakeRateDown && m_esmodel != egEnergyCorr::es2022_R21_Precision)
 	alpha = -m_convFakeRate->GetBinContent( m_convFakeRate->FindBin(aeta) );
-      else if( var==egEnergyCorr::Scale::ConvRadiusUp )
-	alpha =  m_convRadius->GetBinContent( m_convRadius->FindBin(aeta, ET) );
-      else if( var==egEnergyCorr::Scale::ConvRadiusDown )
-	alpha = -m_convRadius->GetBinContent( m_convRadius->FindBin(aeta, ET) );
+      else if (var == egEnergyCorr::Scale::ConvRecoUp && m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	alpha =  m_convFakeRate->GetBinContent( m_convFakeRate->FindBin(aeta,ET) );
+      else if (var == egEnergyCorr::Scale::ConvRecoDown && m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	alpha = -m_convFakeRate->GetBinContent( m_convFakeRate->FindBin(aeta,ET) );
+      else if (var == egEnergyCorr::Scale::ConvRadiusUp)
+	alpha =  m_convRadius->GetBinContent( m_convRadius->FindBin(aeta, ET/GeV) );
+      else if (var == egEnergyCorr::Scale::ConvRadiusDown)
+	alpha = -m_convRadius->GetBinContent( m_convRadius->FindBin(aeta, ET/GeV) );
 
     }
 
@@ -3073,32 +3416,37 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
   }
 
-  double egammaEnergyCorrectionTool::getAlphaPedestal(double cl_eta, double energy, double eraw, PATCore::ParticleType::Type ptype, bool isRef,
-						      egEnergyCorr::Scale::Variation var, double varSF) const {
+  double egammaEnergyCorrectionTool::getAlphaPedestal(double cl_eta, double energy, double eraw,
+						      PATCore::ParticleType::Type ptype,
+						      bool isRef,
+						      egEnergyCorr::Scale::Variation var,
+						      double varSF) const {
     double alpha = 0.;
     if (var == egEnergyCorr::Scale::PedestalUp || var == egEnergyCorr::Scale::PedestalDown) {
       if (m_esmodel == egEnergyCorr::es2017) {
 	const double delta = getValueHistoAt(*m_pedestals_es2017, std::abs(cl_eta));
-	alpha = delta / (energy / cosh(cl_eta));
+	alpha = delta / (energy / std::cosh(cl_eta));
 	if (var == egEnergyCorr::Scale::PedestalDown) alpha *= -1;
       }
-      else if(m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2017_R21_PRE or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or  m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1){
+      else if(m_esmodel == egEnergyCorr::es2017_summer || m_esmodel == egEnergyCorr::es2017_summer_improved ||
+	      m_esmodel == egEnergyCorr::es2017_summer_final || m_esmodel == egEnergyCorr::es2017_R21_PRE ||
+	      m_esmodel == egEnergyCorr::es2015_5TeV || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	      m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	      m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	      m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision){
 	//Et uncertainty band: 10 MeV for the corrected cluster
-	alpha = 10. / (energy / cosh(cl_eta));
+	alpha = 10. / (energy / std::cosh(cl_eta));
 	if (var == egEnergyCorr::Scale::PedestalDown) alpha *= -1;
       }
       else {
 	// observed pedestal corrected as a systematic on MC for now.
 	// TODO : correct for it in the data
 
-
-
 	double pedestal = getLayerPedestal(cl_eta, ptype, 0, var, varSF) +
 	  getLayerPedestal(cl_eta, ptype, 1, var, varSF) +
 	  getLayerPedestal(cl_eta, ptype, 2, var, varSF) +
 	  getLayerPedestal(cl_eta, ptype, 3, var, varSF);
 
-
 	if( isRef )
 	  alpha = pedestal/energy*1.06; // approximate average ratio between calibrated and raw
 	else
@@ -3115,7 +3463,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 						      egEnergyCorr::Scale::Variation var, double varSF) const {
 
     double pedestal = 0.;
-    double aeta = fabs(cl_eta);
+    double aeta = std::abs(cl_eta);
 
     if( var==egEnergyCorr::Scale::PedestalUp || var==egEnergyCorr::Scale::PedestalDown ) {
 
@@ -3147,7 +3495,7 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
   bool egammaEnergyCorrectionTool::isInCrack( double cl_eta ) const {
 
-    if( fabs(cl_eta)>=1.35 && fabs(cl_eta)<=1.55)
+    if( std::abs(cl_eta)>=1.35 && std::abs(cl_eta)<=1.55)
       return true;
 
     return false;
@@ -3176,20 +3524,29 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
     double pileupNoise;
 
-    // release 21 for <mu> =32 (combined 2015-2016-2017 dataset), pileup noise = f(Et) for superclusters
-    if (m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or m_esmodel == egEnergyCorr::es2018_R21_v1) {
-       double et = energy/cosh(eta);
-       if (et<5000.) et=5000.;
-       if (et>50000.) et=50000.;
-       pileupNoise=sqrt(32.)*(60.+40.*log(et/10000.)/log(5.));
+    // release 21 for <mu> = 32 (combined 2015-2016-2017 dataset), pileup noise = f(Et) for superclusters
+    // This is a guess for low mu data... This needs some thoughts. The corresponding uncertainty has been switched off
+    if (m_esmodel == egEnergyCorr::es2017_R21_v0       || m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1  || m_esmodel == egEnergyCorr::es2018_R21_v0 ||
+	m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+      double avgmu = 32;
+      if (m_esmodel == egEnergyCorr::es2022_R21_Precision)
+	avgmu = 34.;
+      else if (m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0)
+	avgmu = 2.;
+      double et = energy/std::cosh(eta);
+      if (et<5000.) et=5000.;
+      if (et>50000.) et=50000.;
+      pileupNoise = std::sqrt(avgmu)*(60.+40.*std::log(et/10000.)/std::log(5.));
     }
     else {
-      // approximate pileup noise addition to the total noise in MeV   for <mu_data> (2012) = 20
+      // approximate pileup noise addition to the total noise in MeV for <mu_data> (2012) = 20
       // converted photons and electrons
       pileupNoise=240.;
       // unconverted photons, different values in barrel and end-cap
       if (particle_type==1) {
-      if (fabs(eta)<1.4) pileupNoise=200.;
+	if (std::abs(eta)<1.4) pileupNoise=200.;
       }
     }
     return pileupNoise;
@@ -3209,18 +3566,17 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 							     int resol_type,
                                                              bool fast) const {
 
-    double pileupNoise =  pileUpTerm(energy,eta, particle_type);
-    double et = energy/cosh(eta);
+    double pileupNoise = pileUpTerm(energy,eta, particle_type);
+    double et = energy/std::cosh(eta);
 
     resolution = m_resolution_tool->getResolution(particle_type,energy,eta,resol_type);
-    //std::cout << " resolution from tool " << resolution << std::endl;
-    double smearingZ=dataConstantTerm(m_use_etaCalo_scales ? etaCalo : eta);
-    double esmearingZ=dataConstantTermError(m_use_etaCalo_scales ? etaCalo : eta);
-    double resolution2=resolution*resolution+smearingZ*smearingZ + (pileupNoise*pileupNoise)/(et*et);
-    resolution=sqrt(resolution2);
+    double smearingZ   = dataConstantTerm(m_use_etaCalo_scales ? etaCalo : eta);
+    double esmearingZ  = dataConstantTermError(m_use_etaCalo_scales ? etaCalo : eta);
+    double resolution2 = resolution*resolution + smearingZ*smearingZ + (pileupNoise*pileupNoise)/(et*et);
+    resolution = std::sqrt(resolution2);
+    ATH_MSG_DEBUG(boost::format("Nominal relative resolution:        %.7f") % resolution);
 
-
-    double_t sum_sigma_resolution2=0.;
+    double sum_sigma_resolution2=0.;
     double sum_deltaDown=0.;
     double sum_deltaUp=0.;
 
@@ -3235,55 +3591,55 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 	// systematics on Z smearing measurement
 	if (isys==0) {
 	  double d1 = (smearingZ+esmearingZ)*(smearingZ+esmearingZ) - smearingZ*smearingZ;
-	  double d2 = smearingZ*smearingZ- (smearingZ-esmearingZ)*(smearingZ-esmearingZ);
+	  double d2 = smearingZ*smearingZ - (smearingZ-esmearingZ)*(smearingZ-esmearingZ);
 	  double d = 0.5*(d1+d2);
 	  sigma2up = d1;
 	  sigma2down = -d2;
 	  sigma2 = d;
-    ATH_MSG_DEBUG(boost::format("sys resolution Zsmearing: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution Zsmearing:           %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
-	// systematics on intrinsic resolution
+	// systematics on intrinsic resolution (3 is to get the true unconverted photon resolution : really intrinsic)
 	if (isys==1) {
-	  double resolutionZ=m_resolution_tool->getResolution(3,40000.*cosh(eta),eta,resol_type);
+	  double resolutionZ = m_resolution_tool->getResolution(3,40000.*std::cosh(eta),eta,resol_type);
 	  double deltaSigma2 = (1.1*resolutionZ)*(1.1*resolutionZ)-resolutionZ*resolutionZ;
 	  double resolution1 = m_resolution_tool->getResolution(3,energy,eta,resol_type);
 	  sigma2up = (1.1*resolution1)*(1.1*resolution1)-resolution1*resolution1 - deltaSigma2;
 	  deltaSigma2 = (0.9*resolutionZ)*(0.9*resolutionZ)-resolutionZ*resolutionZ;
-	  sigma2down= (0.9*resolution1)*(0.9*resolution1)-resolution1*resolution1-deltaSigma2;
+	  sigma2down = (0.9*resolution1)*(0.9*resolution1)-resolution1*resolution1-deltaSigma2;
 	  sigma2 = 0.5*(sigma2up-sigma2down);
-    ATH_MSG_DEBUG(boost::format("sys resolution intrinsic: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution intrinsic:           %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from configA ID material
 	if (isys==2) {
-    double sigmaA= m_getMaterialDelta->getDelta(particle_type,energy,eta,1,0);
+	  double sigmaA = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,0);
 	  sigma2 = sigmaA*sigmaA;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-    ATH_MSG_DEBUG(boost::format("sys resolution configA ID material: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution configA ID material: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from material presampler-layer 1 in barrel (based on half config M )
-	if (isys==3 ) {
-	  if( fabs(eta)<1.45) {
+	if (isys==3) {
+	  if (std::abs(eta)<1.45) {
 	    double sigmaM = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,3);
 	    sigma2 = 0.5*sigmaM*sigmaM;
 	  } else sigma2=0.;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-    ATH_MSG_DEBUG(boost::format("sys resolution presampler-layer1: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution presampler-layer1:   %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematic from material in barrel-endcap gap (using full config X for now)
 	if (isys==4) {
-	  if (fabs(eta)>1.52 && fabs(eta)<1.82) {
-	    double sigmaX =  m_getMaterialDelta->getDelta(particle_type,energy,eta,1,3);
+	  if (std::abs(eta)>1.52 && std::abs(eta)<1.82) {
+	    double sigmaX = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,3);
 	    sigma2 = sigmaX*sigmaX;
 	  } else sigma2=0.;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-    ATH_MSG_DEBUG(boost::format("sys resolution barrel-endcap gap: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution barrel-endcap gap:   %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from material in cryostat area (using half config EL, FIXME: could use clever eta dependent scaling)
@@ -3292,23 +3648,25 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 	  sigma2 = 0.5*sigmaEL*sigmaEL;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-    ATH_MSG_DEBUG(boost::format("sys resolution cryostat area: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution cryostat area:       %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from pileup noise  on total noise (200 MeV in quadrature, somewhat conservative)
 	if (isys==6) {
-   
-          double et = energy/cosh(eta);
+          double et = energy/std::cosh(eta);
           double sigmaPileUp=0.;
           double sigmaZ=0.;
           // release 21 - 10% uncertainty on pileup noise
-          if (m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1) {
-              double deltaNoise = sqrt(1.1*1.1-1.0)*pileupNoise;  // uncertainty in quadrature 1.1*noise - noise
+          if (m_esmodel == egEnergyCorr::es2017_R21_v0 || m_esmodel == egEnergyCorr::es2017_R21_v1 ||
+	      m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1 ||
+	      m_esmodel == egEnergyCorr::es2022_R21_Precision) {
+              double deltaNoise = std::sqrt(1.1*1.1-1.0)*pileupNoise;  // uncertainty in quadrature 1.1*noise - noise
               sigmaPileUp = deltaNoise/et;   // sigmaE/E impact
               sigmaZ = deltaNoise/40000.;    // sigmaE/E for Z->ee electrons (absorbed in smearing correction)
           }
-          // no pileup noise uncertainty for es2017_R21_ofc0_v1
-          else if (m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1) {
+          // no pileup noise uncertainty for es2017_R21_ofc0_v1 and low mu
+          else if (m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+		   m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0) {
             sigmaPileUp=0.;
             sigmaZ=0.;
           }
@@ -3317,80 +3675,76 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 	    double deltaPileupNoise=100.; // MeV
 	    if (std::abs(eta)>=1.4 && std::abs(eta)<1.8) deltaPileupNoise=200.; // larger systematic in this eta bin
 	    double scaleNcells=1;
-	    if (particle_type==1 && std::abs(eta)<1.4) scaleNcells = sqrt(3./5.);   // cluster=3X5 instead of 3x7, rms scales with cluster area
+	    if (particle_type==1 && std::abs(eta)<1.4) scaleNcells = std::sqrt(3./5.);   // cluster=3X5 instead of 3x7, rms scales with cluster area
 	    sigmaPileUp = deltaPileupNoise*scaleNcells/et;
 	    sigmaZ = deltaPileupNoise/(40000.); // effect for Z->ee at Et=40 GeV
           }
-	  sigma2=sigmaPileUp*sigmaPileUp-sigmaZ*sigmaZ;
+	  sigma2 = sigmaPileUp*sigmaPileUp-sigmaZ*sigmaZ;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-    ATH_MSG_DEBUG(boost::format("sys resolution pileup noise: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution pileup noise:        %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from material in IBL+PP0 for barrel
-	if (isys==7 && fabs(eta)<1.5  && (m_esmodel==egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1)) {
-	  double  sigmaE = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,5);
+	if (isys==7 && std::abs(eta)<1.5  &&
+	    (m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	     m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	     m_esmodel == egEnergyCorr::es2015_5TeV   || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	     m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision)) {
+	  double sigmaE = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,5);
 	  sigma2 = sigmaE*sigmaE;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-	  ATH_MSG_DEBUG(boost::format("sys resolution ibl material: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
+	  ATH_MSG_DEBUG(boost::format("sys resolution pp0 material:        %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
 	// systematics from material in IBL+PP0 for end-cap
-	if (isys==8 && fabs(eta)>1.5 && (m_esmodel==egEnergyCorr::es2017 or m_esmodel == egEnergyCorr::es2017_summer or m_esmodel == egEnergyCorr::es2017_summer_improved or m_esmodel == egEnergyCorr::es2017_summer_final or m_esmodel == egEnergyCorr::es2015_5TeV or m_esmodel == egEnergyCorr::es2017_R21_v0 or m_esmodel == egEnergyCorr::es2017_R21_v1 or m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 or m_esmodel == egEnergyCorr::es2018_R21_v0 or  m_esmodel == egEnergyCorr::es2018_R21_v1)) {
-	  double sigmaE =  m_getMaterialDelta->getDelta(particle_type,energy,eta,1,5);
+	if (isys==8 && std::abs(eta)>1.5 &&
+	    (m_esmodel == egEnergyCorr::es2017 || m_esmodel == egEnergyCorr::es2017_summer ||
+	     m_esmodel == egEnergyCorr::es2017_summer_improved || m_esmodel == egEnergyCorr::es2017_summer_final ||
+	     m_esmodel == egEnergyCorr::es2015_5TeV   || m_esmodel == egEnergyCorr::es2017_R21_v0 ||
+	     m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision)) {
+	  double sigmaE = m_getMaterialDelta->getDelta(particle_type,energy,eta,1,5);
 	  // scale factor 2.3 in X0 => sqrt(2) in resolution or 2 in resolution**2
 	  sigma2 = 2.3*sigmaE*sigmaE;
 	  sigma2up = sigma2;
 	  sigma2down = -1.*sigma2;
-	  ATH_MSG_DEBUG(boost::format("sys resolution pp0 material: %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
-
+	  ATH_MSG_DEBUG(boost::format("sys resolution ibl material:        %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
 	}
 
         // AF2 resolution systematics for es2017_R21_v1 model (neglected before that...)
-
-        if (isys==9 && (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 || m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_v1) && fast) {
-           const double ptGeV = et/1e3;
-           if(particle_type == 0) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_electron,eta,ptGeV,true,true,true,true);
-           if(particle_type == 1) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_unconverted,eta,ptGeV,true,true,true,true);
-           if(particle_type == 2) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_converted,eta,ptGeV,true,true,true,true);
-           sigma2up = -1.*sigma2;  // AF2 resolution worse than full Sim, sigma2up gives back AF2 resolution
-           sigma2down = sigma2;
+        if (isys==9 &&
+	    (m_esmodel == egEnergyCorr::es2017_R21_v1 || m_esmodel == egEnergyCorr::es2017_R21_ofc0_v1 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v0 || m_esmodel == egEnergyCorr::es2018_R21_lowmu_v0 ||
+	     m_esmodel == egEnergyCorr::es2018_R21_v1 || m_esmodel == egEnergyCorr::es2022_R21_Precision) &&
+	    fast) {
+	  const double ptGeV = et/1e3;
+	  if(particle_type == 0) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_electron,eta,ptGeV,true,true,true,true);
+	  if(particle_type == 1) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_unconverted,eta,ptGeV,true,true,true,true);
+	  if(particle_type == 2) sigma2 = getValueHistAt(*m_G4OverAFII_resolution_converted,eta,ptGeV,true,true,true,true);
+	  sigma2up = -1.*sigma2;  // AF2 resolution worse than full Sim, sigma2up gives back AF2 resolution
+	  sigma2down = sigma2;
+	  ATH_MSG_DEBUG(boost::format("sys resolution AF2:                 %.7f %.7f %.7f") % sigma2 % sigma2up % sigma2down);
         }
 
-
-//  old method to use max of up and down for All
-/*
-	double rr1 = sqrt(resolution2+sigma2);   // nominal (data) + average error
-	double rr2=0.;
-	if((resolution2-sigma2) > 0.) rr2 = sqrt(resolution2-sigma2);  // max(0, nominal (data) - average error)
-	double deltaSigma_sys;
-	if ((rr1-resolution) > (resolution-rr2) ) deltaSigma_sys = rr1-resolution;
-	else deltaSigma_sys = resolution-rr2;
-	deltaSigma_sys = deltaSigma_sys / resolution;
-*/
-
-// use average of up and down for symmetric uncertainty for All
-
+	// use average of up and down for symmetric uncertainty for All
 	double rr1=0.;
-	if((resolution2+sigma2up)>0.) rr1 = sqrt(resolution2+sigma2up);   // nominal (data) + up error
+	if((resolution2+sigma2up)>0.) rr1 = std::sqrt(resolution2+sigma2up);   // nominal (data) + up error
 	double rr2=0.;
-        if((resolution2+sigma2down) > 0.) rr2 = sqrt(resolution2+sigma2down);  // max(0, nominal (data) + down error
-        double deltaSigma_sys;
-        deltaSigma_sys = 0.5*(rr1-rr2);        // average of up and down uncertainties
-        deltaSigma_sys = deltaSigma_sys / resolution;   // relative resolution uncertainty
+        if((resolution2+sigma2down) > 0.) rr2 = std::sqrt(resolution2+sigma2down);  // max(0, nominal (data) + down error
+        double deltaSigma_sys = 0.5*(rr1-rr2) / resolution; // average of up and down uncertainties, and relative resolution uncertainty
 
 	sum_sigma_resolution2 += deltaSigma_sys*deltaSigma_sys;
 
-	if ((resolution2+sigma2up)>0.) rr1=sqrt(resolution2+sigma2up);
-	else rr1=0.;
 	double deltaSigmaUp = (rr1-resolution)/resolution;
-	//std::cout << " relative resolution change Up " << deltaSigmaUp << std::endl;
+	ATH_MSG_VERBOSE("relative resolution change Up " << deltaSigmaUp);
 
-	if ((resolution2+sigma2down)>0.) rr2=sqrt(resolution2+sigma2down);
-	else rr2=0.;
 	double deltaSigmaDown = (rr2-resolution)/resolution;
-	//std::cout << " relative resolution change Down " << deltaSigmaDown << std::endl;
+	ATH_MSG_VERBOSE("relative resolution change Down " << deltaSigmaDown);
 	
 	sum_deltaUp += deltaSigmaUp;
 	sum_deltaDown += deltaSigmaDown;
@@ -3399,16 +3753,17 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
 
     }
 
-    resolution = resolution *energy;  // to return final resolution in MeV
-    resolution_error = sqrt(sum_sigma_resolution2)*resolution;   // to return resolution uncertainty in MeV
+    resolution = resolution*energy;                                 // to return final resolution in MeV
+    resolution_error = std::sqrt(sum_sigma_resolution2)*resolution; // to return resolution uncertainty in MeV
 
-    resolution_error_up = sum_deltaUp*resolution;
+    resolution_error_up   = sum_deltaUp*resolution;
     resolution_error_down = sum_deltaDown*resolution;
 
-    
-    //std::cout << " Resolution (MeV): " << resolution << "   Resolution Error (MeV): " << resolution_error
-    //	      << " Z smearing " << smearingZ << " +- " << esmearingZ << std::endl;
-
+    ATH_MSG_VERBOSE("Resolution (MeV): " << resolution
+		    << " Resolution Error (MeV): " << resolution_error
+		    << " down " << resolution_error_down << " up " << resolution_error_up
+		    << " Z smearing " << smearingZ << " +- " << esmearingZ
+		    << " using mask " << syst_mask);
   }
 
   string egammaEnergyCorrectionTool::variationName(egEnergyCorr::Scale::Variation& var) const {
@@ -3445,6 +3800,8 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     case egEnergyCorr::Scale::S12Down: return "S12Down";
     case egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Up: return "S12ExtraLastEtaBinRun2Up";
     case egEnergyCorr::Scale::S12ExtraLastEtaBinRun2Down: return "S12ExtraLastEtaBinRun2Down";
+    case egEnergyCorr::Scale::topoClusterThresUp: return "topoClusterThresUp";
+    case egEnergyCorr::Scale::topoClusterThresDown: return "topoClusterThresDown";
     case egEnergyCorr::Scale::MatIDUp: return "MatIDUp";
     case egEnergyCorr::Scale::MatIDDown: return "MatIDDown";
     case egEnergyCorr::Scale::MatCryoUp: return "MatCryoUp";
@@ -3455,14 +3812,20 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     case egEnergyCorr::Scale::L1GainDown: return "L1GainDown";
     case egEnergyCorr::Scale::L2GainUp: return "L2GainUp";
     case egEnergyCorr::Scale::L2GainDown: return "L2GainDown";
+    case egEnergyCorr::Scale::ADCLinUp: return "ADCLinUp";
+    case egEnergyCorr::Scale::ADCLinDown: return "ADCLinDown";
     case egEnergyCorr::Scale::LeakageUnconvUp: return "LeakageUnconvUp";
     case egEnergyCorr::Scale::LeakageUnconvDown: return "LeakageUnconvDown";
     case egEnergyCorr::Scale::LeakageConvUp: return "LeakageConvUp";
     case egEnergyCorr::Scale::LeakageConvDown: return "LeakageConvDown";
+    case egEnergyCorr::Scale::LeakageElecUp: return "LeakageElecUp";
+    case egEnergyCorr::Scale::LeakageElecDown: return "LeakageElecDown";
     case egEnergyCorr::Scale::ConvEfficiencyUp: return "ConvEfficiencyUp";
     case egEnergyCorr::Scale::ConvEfficiencyDown: return "ConvEfficiencyDown";
     case egEnergyCorr::Scale::ConvFakeRateUp: return "ConvFakeRateUp";
     case egEnergyCorr::Scale::ConvFakeRateDown: return "ConvFakeRateDown";
+    case egEnergyCorr::Scale::ConvRecoUp: return "ConvRecoUp";
+    case egEnergyCorr::Scale::ConvRecoDown: return "ConvRecoDown";
     case egEnergyCorr::Scale::ConvRadiusUp: return "ConvRadiusUp";
     case egEnergyCorr::Scale::ConvRadiusDown: return "ConvRadiusDown";
     case egEnergyCorr::Scale::PedestalUp: return "PedestalUp";
@@ -3479,6 +3842,8 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     case egEnergyCorr::Scale::E4ScintillatorDown: return "E4ScintillatorDown";
     case egEnergyCorr::Scale::MatPP0Up: return "MatPP0Up";
     case egEnergyCorr::Scale::MatPP0Down: return "MatPP0Down";
+    case egEnergyCorr::Scale::af2Up: return "af2Up";
+    case egEnergyCorr::Scale::af2Down: return "af2Down";
     case egEnergyCorr::Scale::Wtots1Up: return "Wtots1Up";
     case egEnergyCorr::Scale::Wtots1Down: return "Wtots1Down";
     case egEnergyCorr::Scale::LastScaleVariation: return "LastScaleVariation";
@@ -3517,13 +3882,11 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     }
   }
 
-
   double egammaEnergyCorrectionTool::get_ZeeSyst(double eta) const
   {
-    const auto ieta = m_zeeSyst->GetXaxis()->FindFixBin(eta);
-    auto value_histo = m_zeeSyst->GetBinContent(ieta);
- 
-    return value_histo;
+    const int ieta = m_zeeSyst->GetXaxis()->FindFixBin(eta);
+
+    return m_zeeSyst->GetBinContent(ieta);
   }
 
   const TAxis& egammaEnergyCorrectionTool::get_ZeeStat_eta_axis() const
@@ -3531,6 +3894,4 @@ double egammaEnergyCorrectionTool::getMaterialEffect(egEnergyCorr::Geometry geo,
     return *m_zeeNom->GetXaxis(); 
   }
 
-
-
 } // egRescaler
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/get_MaterialResolutionEffect.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/get_MaterialResolutionEffect.cxx
index adb445caa47699d2dd283b356ddc9b4c8d50fde1..0c3306665e37a5b4d919438c002510cc64b70aeb 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/get_MaterialResolutionEffect.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/Root/get_MaterialResolutionEffect.cxx
@@ -104,7 +104,7 @@ double get_MaterialResolutionEffect::getDelta(int particle_type, double energy,
 
    float aeta=fabs(eta);
    double energyGeV = energy*0.001;
-   double et = energyGeV/cosh(eta);
+   double et = energyGeV/std::cosh(eta);
 
 // IBL+PP0
    if (isyst==5) {
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/README.txt b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fbb40a704b839470652681f0d6207013da3c0da1
--- /dev/null
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/README.txt
@@ -0,0 +1,7 @@
+instructions to rerun:
+using asetup 21.2,latest,AnalysisBase
+
+then in the python directory:
+pip install --user -r plot_requirements.txt 
+
+then running the plot_paper_2017.sh script
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py
index 0f67fa07e3a9f23a3395547f6960add252d7315c..5c01a0c9294554d269196559dc6ede8fac403751 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py
@@ -30,9 +30,10 @@ rcParams['mathtext.default'] = 'rm'
 rcParams['font.sans-serif'] = 'helvetica, Helvetica, Nimbus Sans L, Mukti Narrow, FreeSans'
 
 # axes
+# all commented lines should stay to remember available options
 rcParams['axes.labelsize'] = 20
-rcParams['xtick.minor.visible'] = True
-rcParams['ytick.minor.visible'] = True
+#rcParams['xtick.minor.visible'] = True
+#rcParams['ytick.minor.visible'] = True
 rcParams['xtick.direction'] = 'in'
 rcParams['ytick.direction'] = 'in'
 rcParams['xtick.labelsize'] = 19
@@ -42,8 +43,8 @@ rcParams['ytick.labelsize'] = 19
 rcParams['ytick.major.size'] = 14
 rcParams['ytick.minor.size'] = 7
 rcParams['lines.markersize'] = 8
-rcParams['ytick.right'] = True
-rcParams['xtick.top'] = True
+#rcParams['ytick.right'] = True
+#rcParams['xtick.top'] = True
 # rcParams['lines.markeredgewidth'] = 0. # not working, it changes other stuff
 
 # legend
@@ -403,13 +404,13 @@ def plot_all_syst_eta_slice(etabins, supersampling_eta=3, esmodel='es2012c', dec
                 ax.legend(bbox_to_anchor=(0., 1., 1, 0.2), mode='expand', borderaxespad=0.,
                           loc=3, frameon=True, fontsize=17 if only_up else 14, borderpad=1, ncol=1 if only_up else 2)
                 f.subplots_adjust(top=0.65)
-                plot_ATLAS(f, 0.2, 0.58, label=atlas_label)
+                #plot_ATLAS(f, 0.2, 0.58, label=atlas_label)
                 f.text(0.2, 0.2, beautify_particle(ptype), transform=ax.transAxes, fontsize=16)
                 f.text(0.2, 0.25, r'$%.2f < \eta < %.2f$' % (etamin, etamax), transform=ax.transAxes, fontsize=16)
             else:
                 ax.legend(loc=1, frameon=False, fontsize=13 if only_up else 9, borderpad=1, ncol=1 if only_up else 2)
 
-                plot_ATLAS(f, 0.16, 0.80, label=atlas_label, fontsize=19)
+                #plot_ATLAS(f, 0.16, 0.80, label=atlas_label, fontsize=19)
                 f.text(0.16, 0.74, beautify_particle(ptype), transform=ax.transAxes, fontsize=16)
                 f.text(0.16, 0.68, r'$%.2f < \eta < %.2f$' % (etamin, etamax), transform=ax.transAxes, fontsize=16)
 
@@ -1279,7 +1280,7 @@ def plot_resolution_error_bin(eta_min, eta_max, particle, esmodel, basedir, tool
     ax.legend(loc=3, bbox_to_anchor=(0., -0.5, 1, 0.2), mode="expand",
               ncol=4, borderaxespad=0., fontsize=10)
 
-    plot_ATLAS(fig, 0.16, 0.8, 'Internal', fontsize=19)
+    #plot_ATLAS(fig, 0.16, 0.8, 'Internal', fontsize=19)
 
     if kwargs['grid']:
         ax.grid()
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/test/ut_ElectronPhotonFourMomentumCorrection_maintest.py b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/test/ut_ElectronPhotonFourMomentumCorrection_maintest.py
index 03c110f32d60a5dcdda7e1ea2ad6fbbeeaf5d11d..5ea8c225a330b92df584146d5029c55169c4518e 100755
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/test/ut_ElectronPhotonFourMomentumCorrection_maintest.py
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/test/ut_ElectronPhotonFourMomentumCorrection_maintest.py
@@ -396,27 +396,28 @@ class TestEgammaCalibrationAndSmearingTool(unittest.TestCase):
                                         'EG_SCALE_LARCALIB_EXTRA2015PRE__1down', 'EG_SCALE_LARCALIB_EXTRA2015PRE__1up',
                                         'EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__1down', 'EG_SCALE_LARTEMPERATURE_EXTRA2015PRE__1up',
                                         'EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__1down', 'EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__1up']
-        _test_list_syst("es2015PRE", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
-        _test_list_syst("es2012c", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
-        _test_list_syst("es2016PRE", None, "1NP_v1", "1NP_v1", list_1NP_scale + list_1NP_resolution)
-        _test_list_syst("es2016PRE", None, "1NP_v1", "FULL_v1", list_1NP_scale + list_FULL_resolution)
-        _test_list_syst("es2015PRE", "1NPCOR_PLUS_UNCOR", None, None, list_1NP_resolution + list_1NPCOR_PLUS_UNCOR_scale)
-        _test_list_syst("es2015PRE", "1NP_v1", "1NPCOR_PLUS_UNCOR", None, list_1NP_resolution + list_1NPCOR_PLUS_UNCOR_scale)
-        _test_list_syst("es2015c_summer", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
-
-        _test_list_syst("es2015PRE", "FULL_ETACORRELATED_v1", None, None, 58)
-        _test_list_syst("es2012c", "FULL_ETACORRELATED_v1", None, None, 54)
-        _test_list_syst("es2016PRE", "FULL_ETACORRELATED_v1", None, None, 62)
-        _test_list_syst("es2015c_summer", "FULL_ETACORRELATED_v1", None, None, 60)
-        _test_list_syst("es2016data_mc15c",  "FULL_ETACORRELATED_v1", None, None, 68)
-        _test_list_syst("es2012c", "FULL_v1", None, None, 148)
-        _test_list_syst("es2012c", None, "FULL_v1", "FULL_v1", 148)
-        _test_list_syst("es2015PRE", "FULL_v1", None, None, 158)
-        _test_list_syst("es2015PRE", None, "FULL_v1", "FULL_v1", 158)
-        _test_list_syst("es2015PRE", None, None, None, 158)
+        # _test_list_syst("es2015PRE", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
+        # _test_list_syst("es2012c", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
+        # _test_list_syst("es2016PRE", None, "1NP_v1", "1NP_v1", list_1NP_scale + list_1NP_resolution)
+        # _test_list_syst("es2016PRE", None, "1NP_v1", "FULL_v1", list_1NP_scale + list_FULL_resolution)
+        # _test_list_syst("es2015PRE", "1NPCOR_PLUS_UNCOR", None, None, list_1NP_resolution + list_1NPCOR_PLUS_UNCOR_scale)
+        # _test_list_syst("es2015PRE", "1NP_v1", "1NPCOR_PLUS_UNCOR", None, list_1NP_resolution + list_1NPCOR_PLUS_UNCOR_scale)
+        # _test_list_syst("es2015c_summer", "1NP_v1", None, None, list_1NP_scale + list_1NP_resolution)
+
+        # _test_list_syst("es2015PRE", "FULL_ETACORRELATED_v1", None, None, 58)
+        # _test_list_syst("es2012c", "FULL_ETACORRELATED_v1", None, None, 54)
+        # _test_list_syst("es2016PRE", "FULL_ETACORRELATED_v1", None, None, 62)
+        # _test_list_syst("es2015c_summer", "FULL_ETACORRELATED_v1", None, None, 60)
+        # _test_list_syst("es2016data_mc15c",  "FULL_ETACORRELATED_v1", None, None, 68)
+        # _test_list_syst("es2012c", "FULL_v1", None, None, 148)
+        # _test_list_syst("es2012c", None, "FULL_v1", "FULL_v1", 148)
+        # _test_list_syst("es2015PRE", "FULL_v1", None, None, 158)
+        # _test_list_syst("es2015PRE", None, "FULL_v1", "FULL_v1", 158)
+        # _test_list_syst("es2015PRE", None, None, None, 158)
+        _test_list_syst("es2022_R21_Precision", None, None, None, 156)
 
         # these works, but generate FATALS, as expected
-        _test_list_syst("es2016PRE", "1NP_v1", "1NP_v1", "1NP_v1", [], success=False)
+        # _test_list_syst("es2016PRE", "1NP_v1", "1NP_v1", "1NP_v1", [], success=False)
 
 
 
diff --git a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/util/testMomentumSystematics.cxx b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/util/testMomentumSystematics.cxx
index 13a792906026de34afc75cfc6db3d4de437f3b5f..af91c2f3b69cd1c197a9fea490217046af777f38 100644
--- a/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/util/testMomentumSystematics.cxx
+++ b/PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/util/testMomentumSystematics.cxx
@@ -2,6 +2,8 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
+#include <iostream>
+
 #include <ElectronPhotonFourMomentumCorrection/egammaEnergyCorrectionTool.h>
 
 #include "TProfile.h"
diff --git a/Reconstruction/egamma/egammaLayerRecalibTool/Root/egammaLayerRecalibTool.cxx b/Reconstruction/egamma/egammaLayerRecalibTool/Root/egammaLayerRecalibTool.cxx
index 95c9413a419854b6f2c30cedf7fb6af7757cef2b..9acfd178f53189986940106f794bbdc76a118399 100644
--- a/Reconstruction/egamma/egammaLayerRecalibTool/Root/egammaLayerRecalibTool.cxx
+++ b/Reconstruction/egamma/egammaLayerRecalibTool/Root/egammaLayerRecalibTool.cxx
@@ -214,6 +214,9 @@ void egammaLayerRecalibTool::add_scale(const std::string& tuneIn)
   std::string tune = resolve_alias(tuneIn);
 
   if (tune.empty()) { }
+  else if ("es2022_21.0_Precision" == tune) {
+    add_scale("run2_alt_with_layer2_r21_Precision");
+  }
   else if ("es2018_21.0_v0" == tune) {
     add_scale("run2_alt_with_layer2_r21_v1");
   }
@@ -237,6 +240,10 @@ void egammaLayerRecalibTool::add_scale(const std::string& tuneIn)
     add_scale(new ScaleE3(InputModifier::SUBTRACT), new GetAmountPileupE3(m_pileup_tool));
   }
   //Run 2
+  else if ("run2_alt_with_layer2_r21_Precision"==tune) {
+    add_scale("layer2_alt_el_mu_comb_r21_v0");
+    add_scale("ps_mu_r21_v0");
+  }
   else if ("run2_alt_with_layer2_r21_v1"==tune) {
     add_scale("layer2_alt_run2_r21_v1");
     add_scale("ps_2016_r21_v0");
@@ -602,6 +609,14 @@ void egammaLayerRecalibTool::add_scale(const std::string& tuneIn)
     add_scale(new ScaleE1(InputModifier::ZEROBASED_ALPHA),
 	      new GetAmountHisto1DErrorDown(*histo));
   }
+ else if("layer2_alt_el_mu_comb_r21_v0"==tune) {
+    const std::string file = PathResolverFindCalibFile("egammaLayerRecalibTool/v7/egammaLayerRecalibTunes.root");
+    TFile f(file.c_str());
+    TH1D* histo = static_cast<TH1D*>(f.Get("hE1E2_emu_run2_rel21_v0"));
+    assert(histo);
+    add_scale(new ScaleE2(InputModifier::ONEBASED),
+         new GetAmountHisto1D(*histo));
+  }
   else if("layer2_alt_run2_r21_v1"==tune) {
     const std::string file = PathResolverFindCalibFile("egammaLayerRecalibTool/v6/egammaLayerRecalibTunes.root");
     TFile f(file.c_str());
@@ -770,6 +785,14 @@ void egammaLayerRecalibTool::add_scale(const std::string& tuneIn)
     add_scale(new ScaleE0(InputModifier::ONEBASED_ALPHA),
               new GetAmountHisto1D(*histo_ps_tot_error));
   }
+  else if ("ps_mu_r21_v0" == tune) {
+    const std::string file = PathResolverFindCalibFile("egammaLayerRecalibTool/v7/egammaLayerRecalibTunes.root");
+    TFile f(file.c_str());
+    TH1F* histo_ps_tot_error = static_cast<TH1F*>(f.Get("hPS_MuonLowMu_rel21"));
+    assert(histo_ps_tot_error);
+    add_scale(new ScaleE0(InputModifier::ONEBASED_ALPHA),
+              new GetAmountHisto1D(*histo_ps_tot_error));
+  }
   else if ("ps_2016_v1" == tune) {
     const std::string file = PathResolverFindCalibFile("egammaLayerRecalibTool/v4/egammaLayerRecalibTunes.root");
     TFile f(file.c_str());