diff --git a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.cxx b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.cxx
index 2dbe767cab13b00f36d76d91660dfa36236edc52..b1d1dd2031d91136e332079d8c3df97a37a7f68d 100644
--- a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.cxx
+++ b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.cxx
@@ -52,6 +52,7 @@ G4bool EcalSensorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* /*ROhist*/)
       return false;
   }
   edep *= CLHEP::MeV;
+
   //
   // Get the Touchable History:
   //
@@ -101,6 +102,23 @@ G4bool EcalSensorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* /*ROhist*/)
   lP2[1] = localPosition2[1]*CLHEP::mm;
   lP2[0] = localPosition2[0]*CLHEP::mm;
 
+  // Birk's Law Correction
+
+  const G4Track*              const track    = aStep->GetTrack      () ;
+  const G4ParticleDefinition* const particle = track->GetDefinition () ;
+  //const double                      charge   = particle->GetPDGCharge  () ; 
+  const G4StepPoint* const          preStep  = aStep->GetPreStepPoint () ;
+  const G4MaterialCutsCouple* const material = preStep->GetMaterialCutsCouple () ;
+
+
+  //double ecorrected = edep;
+
+  double ecorrected = edep * birkCorrection( particle , track->GetKineticEnergy(), material ) ;
+
+  // Non-uniformity correction
+
+  ecorrected *= localNonUniformity(lP1[0], lP1[1]) ;
+
   // Now Navigate the history to know in what detector the step is:
   // and finally set the ID of det element in which the hit is.
   //
@@ -115,7 +133,7 @@ G4bool EcalSensorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* /*ROhist*/)
   FaserTrackHelper trHelp(aStep->GetTrack());
   m_HitColl->Emplace(lP1,
                      lP2,
-                     edep,
+                     ecorrected,
                      aStep->GetPreStepPoint()->GetGlobalTime(),//use the global time. i.e. the time from the beginning of the event
                      trHelp.GetParticleLink(),
                      row,module);
diff --git a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.h b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.h
index 3e4db72dec2759e8e9c7b67bdadb5fc280d0204f..d558c0e74e1a55a1e0b3680d7f4831dc3ba66341 100644
--- a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.h
+++ b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSD.h
@@ -20,6 +20,11 @@
 class G4Step;
 class G4TouchableHistory;
 
+// G4 needed classes
+#include "Geant4/G4EnergyLossTables.hh"
+#include "Geant4/G4Material.hh"
+#include "Geant4/G4MaterialCutsCouple.hh"
+
 class EcalSensorSD : public G4VSensitiveDetector
 {
 public:
@@ -40,13 +45,268 @@ public:
       same SD classes as the standard simulation. */
   template <class... Args> void AddHit(Args&&... args){ m_HitColl->Emplace( args... ); }
 
+  /// Set the first coefficient of Birks's law   
+  void birk_c1 (double c1) { m_birk_c1 = c1 ; }   
+  /// Set the second coefficient of Birks's law   
+  void birk_c2 (double c2) { m_birk_c2 = c2; }   
+  /// Set the correction to the first coefficient of Birks's law   
+  void birk_c1cor (double c1cor) { m_birk_c1correction = c1cor; }
+
+  /// Amplitudes of the local non uniformity correction
+  void local_non_uniformity (double local) { m_a_local_outer_ecal = local ; }
+  /// Amplitudes of the global non uniformity correction
+  void global_non_uniformity (double global) { m_a_global_outer_ecal = global ; }
+
+  /// Correction for light reflection at the edges
+  void reflection_height(double h) { m_a_reflection_height = h ; }
+  void reflection_width(double w) { m_a_reflection_width = w ; }
+
 private:
   void indexMethod(const G4TouchableHistory *myTouch, int &station, int &plate);
   static const uint32_t kModuleDepth { 3 };
   static const uint32_t kFiberDepth  { 5 };
+
 protected:
   // The hits collection
   SG::WriteHandle<CaloHitCollection> m_HitColl;
+
+private:
+  // the first coefficient of Birk's law                    (c1)   
+  double m_birk_c1             ;   
+  // the second coefficient of Birk's law                   (c2)   
+  double m_birk_c2             ;   
+  // the correction to the first coefficient of Birk's law  (c1')   
+  double m_birk_c1correction   ;
+  
+  // Amplitudes of the local non uniformity correction
+  double m_a_local_outer_ecal  ;
+  // Amplitudes of the global non uniformity correction
+  double m_a_global_outer_ecal  ;
+  // Correction for light reflection at the edges
+  double  m_a_reflection_height ;
+  double  m_a_reflection_width  ;
+
+protected:
+  /// the first coefficient of Birks's law   
+  inline double birk_c1 () const { return m_birk_c1 ; }   
+  /// the second coefficient of Birks's law   
+  inline double birk_c2 () const { return m_birk_c2 ; }   
+  /// the correction to the first coefficient of Birks's law   
+  inline double birk_c1cor () const   { return m_birk_c1correction ; }
+  
+  /** Correction factor from Birk's Law
+   *  @param step current G4step
+   *  @return the correction factor
+   */
+  inline double birkCorrection ( const G4Step* step ) const ;
+  
+  /** Birk's correction for given particle with given kinetic energy
+   *  for the given material
+   *  @param  particle pointer to particle definition
+   *  @param  Ekine    particle kinetic energy
+   *  @param  maerial  pointer ot teh material
+   */
+  inline double  birkCorrection
+  ( const G4ParticleDefinition* particle ,
+    const double                eKine    ,
+    const G4MaterialCutsCouple* material ) const ;
+  
+  /** evaluate the correction for Birk's law
+   *  @param charge   the charge of the particle
+   *  @param dEdX     the nominal dEdX in the material
+   *  @param material the pointer ot teh material
+   *  @return the correction coefficient
+   */
+  inline double  birkCorrection
+  ( const double      charge   ,
+    const double      dEdX     ,
+    const G4Material* material ) const ;
+  
+  /** evaluate the correction for Birk's law
+   *  @param charge   the charge of the particle
+   *  @param dEdX     the nominal dEdX in the material
+   *  @param density  the density ot the material
+   *  @return the correction coefficient
+   */
+  inline double  birkCorrection
+  ( const double      charge   ,
+    const double      dEdX     ,
+    const double      density  ) const ;
+  
+  /** Correction due to the local non uniformity due to the light
+   *  collection efficiency in cell
+   */
+  inline double localNonUniformity (double x, double y) const ;
+
+  /** The fractions of energy deposited in consequitive time-bins
+   *  in the given Ecal/Hcal cell
+   *  @see CaloSensDet
+   *  @param time global time of energy deposition
+   *  @param cell cellID of the cell
+   *  @param slot (out) the first time bin
+   *  @param fracs (out) the vector of fractions for subsequent time-slots;
+   *  @return StatuscCode
+   */
+//   StatusCode timing
+//   ( const double            time      ,
+//     Fractions& fractions ) const;
+
+  
 };
 
+// ============================================================================
+/** evaluate the correction for Birk's law
+ *  @param charge   the charge of the particle
+ *  @param dEdX     the nominal dEdX in the material
+ *  @param density
+ *  @return the correction coefficient
+ */
+// ============================================================================
+inline double  EcalSensorSD::birkCorrection
+( const double      charge   ,
+  const double      dEdX     ,
+  const double      density  ) const
+{
+  const double C1 =
+    fabs( charge )  < 1.5 ? birk_c1() : birk_c1() * birk_c1cor() ;
+  const double C2 = birk_c2() ;
+
+  const double alpha = dEdX/ density ;
+
+  return 1.0 / ( 1.0 + C1 * alpha + C2 * alpha * alpha ) ;
+}
+
+// ============================================================================
+/** evaluate the correction for Birk's law
+ *  @param charge   the charge of the particle
+ *  @param dEdX     the nominal dEdX in the material
+ *  @param material the pointer ot teh material
+ *  @return the correction coefficient
+ */
+// ============================================================================
+inline double  EcalSensorSD::birkCorrection
+( const double      charge   ,
+  const double      dEdX     ,
+  const G4Material* material ) const
+{
+  if ( 0 == material )
+    { std::cerr << "birkCorrection(): invalid material " << std::endl; return 1. ; } // RETURN
+  return birkCorrection( charge , dEdX , material->GetDensity() ) ;
+}
+
+// ============================================================================
+/** Birk's correction for given particle with given kinetic energy
+ *  for the given material
+ *  @param  particle pointer to particle definition
+ *  @param  Ekine    particle kinetic energy
+ *  @param  maerial  pointer ot teh material
+ */
+// ============================================================================
+inline double EcalSensorSD::birkCorrection
+( const G4ParticleDefinition* particle ,
+  const double                eKine    ,
+  const G4MaterialCutsCouple* material ) const
+{
+  if (  0 == particle || 0 == material )
+    { std::cerr << "birkCorrection(): invalid parameters " << std::endl; return 1.0 ; } // RETURN
+
+  const double charge = particle -> GetPDGCharge() ;
+  if ( fabs ( charge ) < 0.1                      ) { return 1.0 ; } // EEUTRN
+
+  // get the nominal dEdX
+  const double dEdX  =
+    G4EnergyLossTables::GetDEDX ( particle , eKine , material ) ;
+
+  // make an actual evaluation
+  return birkCorrection
+    ( charge ,
+      dEdX   ,
+      material->GetMaterial()->GetDensity() ) ;
+}
+
+// ============================================================================
+// Birk's Law
+// ============================================================================
+/** Correction factor from Birk's Law
+ *  Factor = 1/(1+C1*dEdx/rho+C2*(dEdx/rho)^2)
+ *  Where :
+ *      - C1 = 0.013 g/MeV/cm^2 [Ref NIM 80 (1970) 239]
+ *      - C2 = 9.6.10^-6 g^2/MeV^2/cm^4
+ *      - dEdx in MeV/cm
+ *      - rho = density in g/cm^3
+ */
+// ============================================================================
+inline double EcalSensorSD::birkCorrection ( const G4Step* step ) const
+{
+  if ( !step ) { return 1 ; }                               // RETURN
+
+  // Track
+  const G4Track* track  = step->GetTrack() ;
+  const double charge   = track->GetDefinition()->GetPDGCharge()  ;
+
+  // Only for charged tracks
+  if ( fabs( charge ) < 0.1 ) { return 1 ; }                 // RETURN
+
+  // make an actual evaluation
+  return birkCorrection
+    ( track->GetDefinition         () ,
+      track->GetKineticEnergy      () ,
+      track->GetMaterialCutsCouple () ) ;
+}
+// ============================================================================
+
+inline double EcalSensorSD::localNonUniformity (double x, double y) const
+{
+
+  // Only for ECal for the moment
+  double correction = 1. ;
+
+  // Find the position of the step relative to the centre of the cell
+  // Done before passing in so set centres x0 = y0 = 0
+  double x0       = 0;
+  double y0       = 0;
+
+
+  // Distance between fibers
+  // and correction amplitude
+  double d        = 15.25 * CLHEP::mm ;
+  double A_local  = m_a_local_outer_ecal ; 
+  double A_global = m_a_global_outer_ecal ;
+
+  // Cell size
+  double cellSize = 121.9 * CLHEP::mm; 
+
+  float lowTolerance = 1e-20;
+
+  // Local uniformity is product of x and y sine-like functions
+  // The Amplitude of the sin-like function is a function of x and y
+  if ( A_local > lowTolerance )
+    correction += A_local / 2. * ( 1. - cos( 2. * CLHEP::pi * (x-x0)/d ) ) *
+      ( 1. - cos( 2. * CLHEP::pi * (y-y0)/d ) ) ;
+
+  double rX(0.) , rY(0.) , hCell(0.) ;
+
+  // Global non uniformity
+  if ( A_global > lowTolerance ) {
+    rX = x - x0 ;
+    rY = y - y0 ;
+    hCell = cellSize / 2. ;
+    correction +=
+      A_global * ( hCell - rX ) * ( rX + hCell ) / ( hCell * hCell )
+      * ( hCell - rY ) * ( rY + hCell ) / ( hCell * hCell ) ;
+  }
+
+  // Light Reflexion on the edges
+  if ( m_a_reflection_height > lowTolerance ) {
+    rX = rX / m_a_reflection_width ;
+    rY = rY / m_a_reflection_width ;
+    hCell = hCell / m_a_reflection_width ;
+    correction += m_a_reflection_height *
+      ( exp( - fabs ( rX + hCell ) ) + exp( - fabs ( rX - hCell ) )
+        + exp( - fabs ( rY + hCell ) ) + exp( - fabs ( rY - hCell ) ) ) ;
+  }
+
+  return correction ;
+}
+
 #endif //ECALG4_SD_ECALSENSORSD_H
diff --git a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.cxx b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.cxx
index 0a82737011ee04aa5412ba586ca536af5ece0de4..f2715e28a99a32d357948f4d9fb0dbbb1359ca30 100644
--- a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.cxx
+++ b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.cxx
@@ -18,8 +18,23 @@
 
 EcalSensorSDTool::EcalSensorSDTool(const std::string& type, const std::string& name, const IInterface* parent)
   : SensitiveDetectorBase( type , name , parent )
+  , m_birk_c1 ( 0.013  * CLHEP::g/CLHEP::MeV/CLHEP::cm2 ) // 1st coef. of Birk's   
+  , m_birk_c2 ( 9.6E-6 * CLHEP::g*CLHEP::g/CLHEP::MeV/CLHEP::MeV/CLHEP::cm2/CLHEP::cm2 ) // 2nd coef. of Birk's law 
+  , m_birk_c1correction  ( 0.57142857)  //correction of c1 for 2e charged part.  
+  , m_a_local_outer_ecal ( 0. )
+  , m_a_global_outer_ecal  ( 0.03  ) // global non uniformity amplitude
+  , m_a_reflection_height ( 0.09 ) // reflection on the edges - height
+  , m_a_reflection_width  ( 6. * CLHEP::mm ) // reflection on the edges - width
 {
 
+  declareProperty ( "BirkC1"               ,  m_birk_c1               ) ;   
+  declareProperty ( "BirkC1cor"            ,  m_birk_c1correction     ) ;   
+  declareProperty ( "BirkC2"               ,  m_birk_c2               ) ;
+  declareProperty ( "LocalNonUnifomity"    ,  m_a_local_outer_ecal  ) ;
+  declareProperty ( "GlobalNonUnifomity"   ,  m_a_global_outer_ecal ) ;
+  declareProperty ( "ReflectionHeight"     ,  m_a_reflection_height   ) ;  
+  declareProperty ( "ReflectionWidth"      ,  m_a_reflection_width    ) ;
+
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -27,6 +42,17 @@ EcalSensorSDTool::EcalSensorSDTool(const std::string& type, const std::string& n
 G4VSensitiveDetector* EcalSensorSDTool::makeSD() const
 {
   ATH_MSG_DEBUG( "Creating Ecal SD: " << name() );
-  return new EcalSensorSD(name(), m_outputCollectionNames[0]);
+
+  EcalSensorSD* ecsd = new EcalSensorSD(name(), m_outputCollectionNames[0]);
+
+  ecsd->birk_c1(m_birk_c1);
+  ecsd->birk_c1cor(m_birk_c1correction);
+  ecsd->birk_c2(m_birk_c2);
+  ecsd->local_non_uniformity(m_a_local_outer_ecal);
+  ecsd->global_non_uniformity(m_a_global_outer_ecal);
+  ecsd->reflection_height(m_a_reflection_height);
+  ecsd->reflection_width(m_a_reflection_width);
+
+  return ecsd;
 }
 
diff --git a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.h b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.h
index ceb5b94581a3a04b4b708b7d21cafc45ce3548a7..2ddc736d53fda5285c0310134b31050f925f96cd 100644
--- a/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.h
+++ b/Calorimeter/CaloG4/EcalG4_SD/src/EcalSensorSDTool.h
@@ -21,7 +21,8 @@ class G4VSensitiveDetector;
 
 class EcalSensorSDTool : public SensitiveDetectorBase
 {
- public:
+
+public:
   // Constructor
   EcalSensorSDTool(const std::string& type, const std::string& name, const IInterface *parent);
 
@@ -31,6 +32,22 @@ class EcalSensorSDTool : public SensitiveDetectorBase
 protected:
   // Make me an SD!
   G4VSensitiveDetector* makeSD() const override final;
+
+private:
+  // the first coefficient of Birk's law                    (c1)   
+  double m_birk_c1             ;   
+  // the second coefficient of Birk's law                   (c2)   
+  double m_birk_c2             ;   
+  // the correction to the first coefficient of Birk's law  (c1')   
+  double m_birk_c1correction   ;
+  
+  // Amplitudes of the local non uniformity correction
+  double m_a_local_outer_ecal  ;
+  // Amplitudes of the global non uniformity correction
+  double m_a_global_outer_ecal  ;
+  // Correction for light reflection at the edges
+  double  m_a_reflection_height ;
+  double  m_a_reflection_width  ;
 };
 
 #endif //ECALG4_SD_ECALSENSORSDTOOL_H
diff --git a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
index d63b9c4c07c564d563559b77351868751bf12363..f99ce4b4a9d68c0df89d918aa96d26d53a96efbc 100644
--- a/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
+++ b/Control/CalypsoExample/SimHitExample/src/CaloSimHitAlg.cxx
@@ -15,20 +15,20 @@ StatusCode CaloSimHitAlg::initialize()
     // letter at end of TH1 indicated variable type (D double, F float etc)
     // first string is root object name, second is histogram title
 
-    m_eloss = new TH1D("eLoss", "Calo Hit Energy Loss fraction;Fraction;Events", 1000, 0, 0.0001); 
-    m_elossTL = new TH1D("eLossTL", "Calo Hit Energy Loss Fraction Top Left Module", 1000, 0, 0.0001);
-    m_elossTR = new TH1D("eLossTR", "Calo Hit Energy Loss Fraction Top Right Module", 1000, 0, 0.0001);
-    m_elossBR = new TH1D("eLossBR", "Calo Hit Energy Loss Fraction Bottom Right Module", 1000, 0, 0.0001);
-    m_elossBL = new TH1D("eLossBL", "Calo Hit Energy Loss Fraction Bottom Left Module", 1000, 0, 0.0001);
-
-    m_elossTot = new TH1D("eLossTot", "Total Energy Fraction Deposited in Calorimeter", 1000, 0, 1);   
-    m_elossTLTot = new TH1D("eLossTLTot", "Total Energy Fraction Deposited in Top Left Module", 1000, 0, 1);
-    m_elossTRTot = new TH1D("eLossTRTot", "Total Energy Fraction Deposited in Top Right Module", 1000, 0, 1);
-    m_elossBRTot = new TH1D("eLossBRTot", "Total Energy Fraction Deposited in Bottom Right Module", 1000, 0, 1);
-    m_elossBLTot = new TH1D("eLossBLTot", "Total Energy Fraction Deposited in Bottom Left Module", 1000, 0, 1);    
-
-    m_module = new TH2D("module", "Calo Hit Module", 2, -0.5, 1.5, 2, -0.5, 1.5 );
-    m_modulePos = new TH2D("modulePos", "Calo Hit Module Position", 13, -130, 130, 13, -130, 130 );
+    m_eloss = new TH1D("eLoss", "Calo Hit Energy Loss Fraction;Fraction;Events", 1000, 0, 0.0001); 
+    m_elossTL = new TH1D("eLossTL", "Calo Hit Energy Loss Fraction Top Left Module;Fraction;Events", 1000, 0, 0.0001);
+    m_elossTR = new TH1D("eLossTR", "Calo Hit Energy Loss Fraction Top Right Module;Fraction;Events", 1000, 0, 0.0001);
+    m_elossBR = new TH1D("eLossBR", "Calo Hit Energy Loss Fraction Bottom Right Module;Fraction;Events", 1000, 0, 0.0001);
+    m_elossBL = new TH1D("eLossBL", "Calo Hit Energy Loss Fraction Bottom Left Module;Fraction;Events", 1000, 0, 0.0001);
+
+    m_elossTot = new TH1D("eLossTot", "Total Energy Fraction Deposited in Calorimeter;Fraction;Events", 1000, 0, 1);   
+    m_elossTLTot = new TH1D("eLossTLTot", "Total Energy Fraction Deposited in Top Left Module;Fraction;Events", 1000, 0, 1);
+    m_elossTRTot = new TH1D("eLossTRTot", "Total Energy Fraction Deposited in Top Right Module;Fraction;Events", 1000, 0, 1);
+    m_elossBRTot = new TH1D("eLossBRTot", "Total Energy Fraction Deposited in Bottom Right Module;Fraction;Events", 1000, 0, 1);
+    m_elossBLTot = new TH1D("eLossBLTot", "Total Energy Fraction Deposited in Bottom Left Module;Fraction;Events", 1000, 0, 1);    
+
+    m_module = new TH2D("module;x;y", "Calo Hit Module", 2, -0.5, 1.5, 2, -0.5, 1.5 );
+    m_modulePos = new TH2D("modulePos;x;y", "Calo Hit Module Position", 13, -130, 130, 13, -130, 130 );
         
 
     ATH_CHECK(histSvc()->regHist("/HIST/eloss", m_eloss));