diff --git a/LArCalorimeter/LArCalibUtils/python/LArHVScaleConfig.py b/LArCalorimeter/LArCalibUtils/python/LArHVScaleConfig.py
index a71c08b764ab149f37389e121a761142ad0bdc8a..e0f03e161930353ee168e602710d07ebe2abcee9 100644
--- a/LArCalorimeter/LArCalibUtils/python/LArHVScaleConfig.py
+++ b/LArCalorimeter/LArCalibUtils/python/LArHVScaleConfig.py
@@ -39,24 +39,18 @@ def LArHVScaleCfg(configFlags):
                                          HVPAthologyKey="LArHVPathology")
         result.addCondAlgo(hvpath)
 
-        LArHVCondAlg=CompFactory.LArHVCondAlg
-        if configFlags.GeoModel.Run != "RUN1":
-           hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",OutputHVData="LArHVData")
-        else:   
-           hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",OutputHVData="LArHVData",doR=False)
-        result.addCondAlgo(hvcond)
-
         from LArConfiguration.LArElecCalibDBConfig import LArElecCalibDbCfg
         result.merge(LArElecCalibDbCfg(configFlags,["HVScaleCorr",]))
 
-        LArHVScaleCorrCondAlg=CompFactory.LArHVScaleCorrCondAlg
-        hvscalecorrkey = "LArHVScaleCorrRecomputed"
-        if configFlags.Input.isMC:
-            hvscalecorrkey = "LArHVScaleCorr"
+        LArHVCondAlg=CompFactory.LArHVCondAlg
+        if configFlags.GeoModel.Run != "RUN1":
+           hvcond = LArHVCondAlg(HVPathologies="LArHVPathology")
+        else:   
+           hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",doR=False)
 
-        hvscale = LArHVScaleCorrCondAlg(keyHVdata="LArHVData",keyOutputCorr=hvscalecorrkey)
-        hvscale.UndoOnlineHVCorr=True
-        result.addCondAlgo(hvscale)
+        hvcond.UndoOnlineHVCorr=True
+        hvcond.keyOutputCorr= "LArHVScaleCorrRecomputed"
+        result.addCondAlgo(hvcond)
 
     return result
 
diff --git a/LArCalorimeter/LArExample/LArConditionsCommon/python/LArHVDB.py b/LArCalorimeter/LArExample/LArConditionsCommon/python/LArHVDB.py
index 5451ab88542481472caa95d0c9ae1fa99c9345d9..446b7707191040cb26a4756a8d1abd1899429f0f 100644
--- a/LArCalorimeter/LArExample/LArConditionsCommon/python/LArHVDB.py
+++ b/LArCalorimeter/LArExample/LArConditionsCommon/python/LArHVDB.py
@@ -24,15 +24,12 @@ if not conddb.isMC and not conddb.isOnline:
 
     from LArRecUtils.LArRecUtilsConf import LArHVCondAlg
     if conddb.dbdata != 'COMP200': 
-      hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",OutputHVData="LArHVData")
+      hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",keyOutputCorr="LArHVScaleCorrRecomputed")
     else:  
-      hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",OutputHVData="LArHVData",doR=False)
-    condseq += hvcond
+      hvcond = LArHVCondAlg(HVPathologies="LArHVPathology",keyOutputCorr="LArHVScaleCorrRecomputed",doR=False)
 
-    from LArRecUtils.LArRecUtilsConf import LArHVScaleCorrCondAlg
-    hvscale = LArHVScaleCorrCondAlg(keyHVdata="LArHVData",keyOutputCorr="LArHVScaleCorrRecomputed")
-    hvscale.UndoOnlineHVCorr=True
-    condseq += hvscale
+    hvcond.UndoOnlineHVCorr=True
+    condseq += hvcond
 
 if conddb.isMC:
     conddb.addFolderWithTag("LAR_OFL","/LAR/Identifier/HVLineToElectrodeMap","LARHVLineToElectrodeMap-001",className="AthenaAttributeList")
diff --git a/LArCalorimeter/LArRecConditions/LArRecConditions/LArHVCorr.h b/LArCalorimeter/LArRecConditions/LArRecConditions/LArHVCorr.h
index 2b95df64bdc67fe16b9c178c556d6da9192b32e7..0124f2ac348582a73f67afbeeccbaf7329fe141b 100644
--- a/LArCalorimeter/LArRecConditions/LArRecConditions/LArHVCorr.h
+++ b/LArCalorimeter/LArRecConditions/LArRecConditions/LArHVCorr.h
@@ -39,6 +39,6 @@ class LArHVCorr : public ILArHVScaleCorr {
 
 #include "AthenaKernel/CondCont.h"
 CLASS_DEF( LArHVCorr, 52206080, 1)
-CONDCONT_DEF( LArHVCorr, 24667986 );
+CONDCONT_DEF( LArHVCorr, 24667986, ILArHVScaleCorr);
 
 #endif
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
index 5532162a42581f4421115f692f1662f94e1a3886..28f968ba039b0cb50c8b4fd94a330a4eb808930a 100755
--- a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
+++ b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.cxx
@@ -3,15 +3,9 @@
 */
 
 #include "./LArHVCondAlg.h" 
-#include "GaudiKernel/IToolSvc.h"
-#include "StoreGate/ReadCondHandle.h"
-#include "LArElecCalib/ILArHVPathologyDbTool.h"
 #include "LArRecConditions/LArHVPathologiesDb.h"
 #include "CaloDetDescr/CaloDetectorElements.h"
 #include "CaloGeoHelpers/CaloPhiRange.h"
-#include "CaloIdentifier/LArEM_ID.h"
-#include "CaloIdentifier/LArHEC_ID.h"
-#include "CaloIdentifier/LArFCAL_ID.h"
 #include "CaloIdentifier/CaloCell_ID.h"
 #include "CaloDetDescr/CaloDetDescrManager.h"
 #include "LArReadoutGeometry/EMBCell.h"
@@ -40,85 +34,70 @@
 
 #include "CoralBase/Blob.h"
 
-//#include <iostream> 
 #include <cmath> 
 #include <cstdlib>
-#include "AthenaKernel/errorcheck.h"
-
-#include "AthenaKernel/IOVInfiniteRange.h"
-
-#define VDIFF_MAX 0.01 // maximum voltage difference allowed to be treated as equal
-#define WDIFF_MAX 0.0001 // maximum weight difference allowed to be treated as equal
-#define IDIFF_MAX 0.1 // maximum current difference allowed to be treated as equal
 
 #define HV_NON_NOMINAL_TOLERANCE 10 // tolerance : 1V for HV
 #define DEAD_HV_THRESHOLD 10 // HV <10 V="dead"
-
+#define MAX_LAR_CELLS 182468
 
 // constructor 
 LArHVCondAlg::LArHVCondAlg( const std::string& name, ISvcLocator* pSvcLocator )
-  : AthReentrantAlgorithm(name,pSvcLocator),
-    m_larem_id(nullptr),
-    m_larhec_id(nullptr),
-    m_larfcal_id(nullptr),
-    m_electrodeID(nullptr),
-    m_hvLineID(nullptr),
-    m_condSvc("CondSvc",name)
+  : AthReentrantAlgorithm(name,pSvcLocator)
  {
   declareProperty("doHV",m_doHV=true,"create HV data");
   declareProperty("doR",m_doR=true,"Use R values with current to improve HV");
-  declareProperty("doAffected",m_doAffected=true,"create affected region info");
-  declareProperty("doAffectedHV",m_doAffectedHV=true,"include HV non nominal regions info");
- 
 }
 
-// destructor 
-LArHVCondAlg::~LArHVCondAlg()
-{ }
-
 //initialize
 StatusCode LArHVCondAlg::initialize(){
-  const CaloCell_ID* idHelper = nullptr;
-  ATH_CHECK( detStore()->retrieve (idHelper, "CaloCell_ID") );
+  ATH_CHECK( detStore()->retrieve (m_calocellID, "CaloCell_ID") );
 
-  m_larem_id   = idHelper->em_idHelper();
-  m_larhec_id   = idHelper->hec_idHelper();
-  m_larfcal_id   = idHelper->fcal_idHelper();
+  m_larem_id   = m_calocellID->em_idHelper();
+  m_larhec_id   = m_calocellID->hec_idHelper();
+  m_larfcal_id   = m_calocellID->fcal_idHelper();
 
   ATH_CHECK(detStore()->retrieve(m_electrodeID));
-
   ATH_CHECK(detStore()->retrieve(m_hvLineID));
+  ATH_CHECK(detStore()->retrieve(m_onlineID));
+
+  m_doR= m_useCurrentEMB || m_useCurrentFCAL1 || m_useCurrentOthers;
 
-  ATH_CHECK( detStore()->retrieve(m_onlineID));
 
   // Read Handles
+  ATH_CHECK(m_cablingKey.initialize());
   ATH_CHECK(m_pathologiesKey.initialize (m_doHV || m_doAffectedHV));
   ATH_CHECK(m_DCSFolderKeys.initialize (m_doHV || m_doAffectedHV));
-  ATH_CHECK( m_cablingKey.initialize());
-  ATH_CHECK( m_BFKey.initialize() );
+  ATH_CHECK(m_cablingKey.initialize());
+  ATH_CHECK(m_BFKey.initialize() );
   ATH_CHECK(m_hvMappingKey.initialize (m_doHV || m_doAffectedHV));
-  ATH_CHECK( m_hvRKey.initialize(m_doR && (m_doHV || m_doAffectedHV)));
+  ATH_CHECK(m_hvRKey.initialize(m_doR && (m_doHV || m_doAffectedHV)));
+  ATH_CHECK(m_onlineHVScaleCorrKey.initialize(m_undoOnlineHVCorr));
 
-  // Write Handle
-  
-  // Register write handle
-  ATH_CHECK( m_condSvc.retrieve() );
-  ATH_CHECK(m_hvDataKey.initialize());
-  ATH_CHECK(m_outKey.initialize());
+  // Write Handles
+
+  ATH_CHECK(m_outputHVScaleCorrKey.initialize());
+  ATH_CHECK(m_affectedKey.initialize());
 
   if(m_doHV || m_doAffectedHV) {
-    if (m_condSvc->regHandle(this, m_hvDataKey).isFailure()) {
-      ATH_MSG_ERROR("unable to register WriteCondHandle " << m_hvDataKey.fullKey() << " with CondSvc");
+    if (m_condSvc->regHandle(this, m_outputHVScaleCorrKey).isFailure()) {
+      ATH_MSG_ERROR("unable to register WriteCondHandle " << m_outputHVScaleCorrKey.fullKey() << " with CondSvc");
       return StatusCode::FAILURE;
     }
   }
   if(m_doAffected) {
-     if (m_condSvc->regHandle(this, m_outKey).isFailure()) {
-       ATH_MSG_ERROR("unable to register WriteCondHandle " << m_outKey.fullKey() << " with CondSvc");
+     if (m_condSvc->regHandle(this, m_affectedKey).isFailure()) {
+       ATH_MSG_ERROR("unable to register WriteCondHandle " << m_affectedKey.fullKey() << " with CondSvc");
        return StatusCode::FAILURE;
      }
   }
 
+
+  ATH_CHECK( m_condSvc.retrieve() );
+
+
+  m_scaleTool=std::make_unique<LArHVScaleCorrTool>(m_calocellID,msg(),m_fixHVStrings); 
+
   ATH_MSG_DEBUG("Configured with doHV " << m_doHV << " doAffected " << m_doAffected << " doAffectedHV " << m_doAffectedHV);
 
   return StatusCode::SUCCESS;
@@ -131,7 +110,7 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
   bool doHVData=false;
   bool doAffected=false;
 
-  SG::WriteCondHandle<LArHVData> writeHandle{m_hvDataKey, ctx};
+  SG::WriteCondHandle<LArHVCorr> writeHandle{m_outputHVScaleCorrKey, ctx};
   if(m_doHV || m_doAffectedHV) {
     if (writeHandle.isValid()) {
       ATH_MSG_DEBUG("Found valid write LArHVData handle");
@@ -140,7 +119,7 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
     }
   } 
 
-  SG::WriteCondHandle<CaloAffectedRegionInfoVec> writeAffectedHandle{m_outKey, ctx};
+  SG::WriteCondHandle<CaloAffectedRegionInfoVec> writeAffectedHandle{m_affectedKey, ctx};
   if(m_doAffected){
     if (writeAffectedHandle.isValid()) {
       ATH_MSG_DEBUG("Found valid write LArAffectedRegions handle");
@@ -149,12 +128,26 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
     }
   }
 
+  if (!doHVData && !doAffected) {
+    //Nothing to do, bail out. 
+    return StatusCode::SUCCESS;
+  }
+
   ATH_MSG_DEBUG("Executing with doHV " << doHVData << " doAffected " << doAffected );
 
   std::vector<const CondAttrListCollection*> attrvec;
   const LArHVIdMapping* hvCabling{nullptr};
   const float* rValues{nullptr};
+  const ILArHVScaleCorr *onlHVCorr{nullptr};
+
 
+  SG::ReadCondHandle<LArOnOffIdMapping> larCablingHdl(m_cablingKey, ctx);
+  const LArOnOffIdMapping* cabling=*larCablingHdl;
+  if(!cabling) {
+     ATH_MSG_ERROR("Could not get LArOnOffIdMapping !!");
+     return StatusCode::FAILURE;
+  }
+  writeHandle.addDependency(larCablingHdl);
   if(doHVData || (doAffected && m_doAffectedHV) ) {
     SG::ReadCondHandle<LArHVIdMapping> mappingHdl{m_hvMappingKey, ctx};
     hvCabling = *mappingHdl;
@@ -165,6 +158,17 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
     writeHandle.addDependency(mappingHdl);
     writeAffectedHandle.addDependency(mappingHdl);
     ATH_MSG_DEBUG("Range of HV-Cabling " << mappingHdl.getRange());
+
+    // Online HVScaleCorr (if needed to subtract)
+
+    if(m_undoOnlineHVCorr) {
+      SG::ReadCondHandle<ILArHVScaleCorr> onlHVCorrHdl(m_onlineHVScaleCorrKey, ctx);
+      onlHVCorr = *onlHVCorrHdl;
+      if(!onlHVCorr) {
+	ATH_MSG_ERROR("Do not have online HV corr. conditions object, but asked to undo !!!!");
+	return StatusCode::FAILURE;
+      }
+    }
     // get handles to DCS Database folders
     for (const auto& fldkey: m_DCSFolderKeys ) {
       SG::ReadCondHandle<CondAttrListCollection> dcsHdl(fldkey, ctx);
@@ -196,10 +200,10 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
       rValues = static_cast<const float*>(rBlob.startingAddress());
     }
   }
- 
-  std::vector<float> voltage;
-  std::vector<float> current;
-  std::vector<unsigned int> hvlineidx;
+
+
+
+  voltagePerLine_t voltagePerLine;  
  
   if(doHVData) {
     // Fill pathology info
@@ -280,18 +284,39 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
     }//doPathology
     // now call filling of HV values
     if(doHVData || (doAffected && m_doAffectedHV)) {
-      ATH_CHECK(fillUpdatedHVChannelsVec(voltage, current, hvlineidx, attrvec));
+      ATH_CHECK(dcs2LineVoltage(voltagePerLine, attrvec));
     }
-    // try to get old cond. object
-    const LArHVData* hvdataOld = nullptr;
     
-    std::unique_ptr<LArHVData> hvdata = std::make_unique<LArHVData>();
+
+    voltagePerCell_t voltageVec(MAX_LAR_CELLS);
+    
+    ATH_CHECK(fillPathAndCellHV(voltageVec, hvCabling, voltagePerLine, pathologyContainer, hasPathologyEM, hasPathologyHEC, hasPathologyFCAL, rValues));
   
-    ATH_CHECK(fillPayload(hvdata.get(), hvdataOld, hvCabling, voltage, current, hvlineidx, pathologyContainer, hasPathologyEM, hasPathologyHEC, hasPathologyFCAL, rValues));
+    const CaloDetDescrManager* calodetdescrmgr = nullptr;
+    ATH_CHECK( detStore()->retrieve(calodetdescrmgr) );
+    
+    std::vector<float> vScale;
+    vScale.resize(MAX_LAR_CELLS,(float)1.0);
+    for (unsigned i=0;i<MAX_LAR_CELLS;++i) {
+      IdentifierHash hash(i);
+      const CaloDetDescrElement* dde= calodetdescrmgr->get_element(hash); 
+      vScale[i]=m_scaleTool->getHVScale(dde,voltageVec[i]);
+      if(onlHVCorr) { // undo the online one
+	const float hvonline = onlHVCorr->HVScaleCorr(cabling->createSignalChannelIDFromHash(hash));
+	if (hvonline>0. && hvonline<100.) vScale[i]=vScale[i]/hvonline;
+      }
+    }
   
- 
-    ATH_CHECK(writeHandle.record(std::move(hvdata)));
+    std::unique_ptr<LArHVCorr> hvCorr = std::make_unique<LArHVCorr>(std::move(vScale), cabling, m_calocellID);
+
+    if(writeHandle.record(std::move(hvCorr)).isFailure()) {
+      ATH_MSG_ERROR("Could not record LArHVCorr object with " << writeHandle.key()
+		    << " with EventRange " << writeHandle.getRange() << " into Conditions Store");
+      return StatusCode::FAILURE;
+    }
+
     ATH_MSG_INFO("recorded new " << writeHandle.key() << " with range " << writeHandle.getRange() << " into Conditions Store");
+  
   } // doHVData
 
   if(doAffected) {
@@ -313,15 +338,13 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
        writeAffectedHandle.addDependency(cablingHdl);
        ATH_MSG_DEBUG("Range of LArCabling " << cablingHdl.getRange() << ", intersection: " << writeAffectedHandle.getRange());
 
-   
-       //CaloAffectedRegionInfoVec *vAffected = new CaloAffectedRegionInfoVec();
        std::unique_ptr<CaloAffectedRegionInfoVec> vAffected = std::make_unique<CaloAffectedRegionInfoVec>();
        if (m_doAffectedHV) {
-         ATH_CHECK(searchNonNominalHV_EMB(vAffected.get(), hvCabling, voltage, hvlineidx));
-         ATH_CHECK(searchNonNominalHV_EMEC_OUTER(vAffected.get(), hvCabling, voltage, hvlineidx));
-         ATH_CHECK(searchNonNominalHV_EMEC_INNER(vAffected.get(), hvCabling, voltage, hvlineidx));
-         ATH_CHECK(searchNonNominalHV_HEC(vAffected.get(), hvCabling, voltage, hvlineidx));
-         ATH_CHECK(searchNonNominalHV_FCAL(vAffected.get(), hvCabling, voltage, hvlineidx));
+         ATH_CHECK(searchNonNominalHV_EMB(vAffected.get(), hvCabling, voltagePerLine));
+         ATH_CHECK(searchNonNominalHV_EMEC_OUTER(vAffected.get(), hvCabling, voltagePerLine));
+         ATH_CHECK(searchNonNominalHV_EMEC_INNER(vAffected.get(), hvCabling, voltagePerLine));
+         ATH_CHECK(searchNonNominalHV_HEC(vAffected.get(), hvCabling, voltagePerLine));
+         ATH_CHECK(searchNonNominalHV_FCAL(vAffected.get(), hvCabling, voltagePerLine));
        }
    
    
@@ -339,26 +362,19 @@ StatusCode LArHVCondAlg::execute(const EventContext& ctx) const {
 
 
 StatusCode LArHVCondAlg::finalize() {
-  //ATH_MSG_INFO("# of actual voltage changes:" << m_updatedElectrodes.size()); 
   return StatusCode::SUCCESS;
 }
 
 
-StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
-				     , const LArHVData* hvdataOld
-				     , const LArHVIdMapping* hvCabling
-				     , std::vector<float> &voltage
-				     , std::vector<float> &current
-				     , std::vector<unsigned int> &hvlineidx 
-				     , const LArHVPathology& pathologies
-				     , pathVec& hasPathologyEM
-				     , pathVec& hasPathologyHEC
-				     , pathVec& hasPathologyFCAL
-                                     , const float* rValues) const
+StatusCode LArHVCondAlg::fillPathAndCellHV(voltagePerCell_t& hvdata
+					   , const LArHVIdMapping* hvCabling
+					   , const voltagePerLine_t& voltage
+					   , const LArHVPathology& pathologies
+					   , pathVec& hasPathologyEM
+					   , pathVec& hasPathologyHEC
+					   , pathVec& hasPathologyFCAL
+					   , const float* rValues) const
 {
-  LArHVData::hvMap &hvmap = hvdata->m_voltage;
-  std::set<Identifier> &updatedCells = hvdata->m_updatedCells;
-
   const CaloDetDescrManager* calodetdescrmgr = nullptr;
   ATH_CHECK( detStore()->retrieve(calodetdescrmgr) );
 
@@ -366,254 +382,217 @@ StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
 
   const float uAkOhm = 1.e-3; // current is uA, rValues kOhm, result should be V
 
-  updatedCells.clear();
-  hvmap.clear();
 
-  std::vector<LArHVData::HV_t> v;
   // loop over all EM Identifiers
   for (auto id: m_larem_id->channel_ids()) {
-      v.clear();
-      if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) > 0) { // LAr EMB
-         unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
-         bool hasPathology=false; 
-         if (index<hasPathologyEM.size()) {
-          if (hasPathologyEM[index].size()) {
-           hasPathology=true;
-           listElec = getElecList(id,pathologies);
-          }
-         }
-         const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(id));
-         if (!embElement) std::abort();
-         const EMBCellConstLink cell = embElement->getEMBCell();
-         unsigned int nelec = cell->getNumElectrodes();
-         unsigned int ngap = 2*nelec;
-         double wt = 1./ngap;
-         v.clear();
-         for (unsigned int i=0;i<nelec;i++) {
-             const EMBHVElectrode& electrode = cell->getElectrode(i);
-             //   " " << electrode->getModule()->getEtaIndex() << " " << electrode->getModule()->getPhiIndex() << 
-             //   " " << electrode->getModule()->getSectorIndex() << " " << electrode->getElectrodeIndex() << std::endl;
-             for (unsigned int igap=0;igap<2;igap++) {
-	       unsigned int hvline = electrode.hvLineNo(igap,hvCabling);
-	       const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-	       if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-		 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Assuming 0 voltage !");
-		 //return StatusCode::FAILURE;
-                 // Do not bomb, but assume the HV=0
-                 double hv=0;
-                 double curr=0;
-                 addHV(v,hv,curr,wt);
-	       } else {
-                 unsigned idx = itrLine - hvlineidx.begin(); 
-                 double hv=voltage[idx];
-                 double curr=current[idx];
-                 if(rValues) { // modify the current record
-                    const EMBHVModule &hvmod = electrode.getModule();
-                    unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(0,
-                                                                            hvmod.getSideIndex(),
-                                                                            hvCabling->getCellModule(id),
-                                                                            hvmod.getPhiIndex(),
-                                                                            hvmod.getEtaIndex(),
-                                                                            igap,
-                                                                            electrode.getElectrodeIndex() ));
-                    if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
-                    ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" curr. " << curr << " R: "<<rValues[ridx]);
-                 }
-                 if (hasPathology) {
-                    ATH_MSG_VERBOSE( "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]);
-                    msg(MSG::VERBOSE) << "Original hv: "<<hv<<" ";
-                    for (unsigned int ii=0;ii<listElec.size();ii++) {
-                       if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
-                          if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
-                             hv=0.;
-                             curr = 0.;
-                          } else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) { 
-                             curr = 0.;
-                          } else {
-                             hv=((hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
-                             curr=0.;
-                          }
-                       }
-                    }
-                    msg(MSG::VERBOSE) << "set hv: "<<hv<<endmsg;
-                 }
-                 addHV(v,hv,curr,wt);
-               } 
-             }
-         }        
-         hvmap.insert(std::make_pair(id,v));
-      } else if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) == 0) { // EMBPS
-
-         const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(id));
-         if (!embElement) std::abort();
-         const EMBCellConstLink cell = embElement->getEMBCell();
- 
-         const EMBPresamplerHVModule& hvmodule =  cell->getPresamplerHVModule ();
+    const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
+    voltageCell_t& v=hvdata[hash];
+    if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) > 0) { // LAr EMB
+      unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
+      bool hasPathology=false; 
+      if (index<hasPathologyEM.size()) {
+	if (hasPathologyEM[index].size()) {
+	  hasPathology=true;
+	  listElec = getElecList(id,pathologies);
+	}
+      }
+      const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(hash));
+      if (!embElement) std::abort();
+      const EMBCellConstLink cell = embElement->getEMBCell();
+      unsigned int nelec = cell->getNumElectrodes();
+      unsigned int ngap = 2*nelec;
+      float wt = 1./ngap;
+      for (unsigned int i=0;i<nelec;i++) {
+	const EMBHVElectrode& electrode = cell->getElectrode(i);
+	//   " " << electrode->getModule()->getEtaIndex() << " " << electrode->getModule()->getPhiIndex() << 
+	//   " " << electrode->getModule()->getSectorIndex() << " " << electrode->getElectrodeIndex() << std::endl;
+	for (unsigned int igap=0;igap<2;igap++) {
+	  float hv=0;
+	  float curr=0;
+	  unsigned int hvline = electrode.hvLineNo(igap,hvCabling);
+	  auto hvIt=voltage.find(hvline);
+	  if(hvIt != voltage.end()) { //Found HV line
+	    hv=hvIt->second.hv;
+	    if(rValues &&  m_useCurrentEMB) { // modify the current record
+	      curr=hvIt->second.curr;
+	      const EMBHVModule &hvmod = electrode.getModule();
+	      unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(0,
+										      hvmod.getSideIndex(),
+										      hvCabling->getCellModule(id),
+										      hvmod.getPhiIndex(),
+										      hvmod.getEtaIndex(),
+										      igap,
+										      electrode.getElectrodeIndex() ));
+	      if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
+	      ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
+	    }//end if rValues
+	    if (hasPathology) {
+	      ATH_MSG_VERBOSE( "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]);
+	      msg(MSG::VERBOSE) << "Original hv: "<<hv<<" ";
+	      for (unsigned int ii=0;ii<listElec.size();ii++) {
+		if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
+		  if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
+		    hv=0.;
+		    curr = 0.;
+		  } else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) { 
+		    curr = 0.;
+		  } else {
+		    hv=((hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
+		    curr=0.;
+		  }
+		}
+	      }
+	      msg(MSG::VERBOSE) << "set hv: "<<hv<<endmsg;
+	    }//end if has patology
+	  
+	  }//end got hv
+	  else {
+	    ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+	  }
+	  addHV(v,hv-curr,wt);
+	}//end loop over gaps
+      }//end loop over electrodes
+    } else if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) == 0) { // EMBPS
+
+      const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(hash));
+      if (!embElement) std::abort();
+      const EMBCellConstLink cell = embElement->getEMBCell();
+      const EMBPresamplerHVModule& hvmodule =  cell->getPresamplerHVModule ();
  
-         double wt = 0.5;
-         for (unsigned int igap=0;igap<2;igap++) {
-	       unsigned int hvline = hvmodule.hvLineNo(igap,hvCabling);
-	       const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-	       if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-	     ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
-	     //return StatusCode::FAILURE;
-             double hv=0;
-             double curr=0;
-	     addHV(v,hv,curr,wt);
-	   } else {
-	     unsigned idx = itrLine - hvlineidx.begin();
-	     double hv=voltage[idx];
-	     double curr=current[idx];
-             if(rValues) { // modify the current record
-                unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(1,
-                                                                        hvmodule.getSideIndex(),
-                                                                        hvCabling->getCellModule(id),
-                                                                        0, // not used in EMBPS
-                                                                        hvmodule.getEtaIndex(),
-                                                                        igap,
-                                                                        0 // not used in EMBPS
-                                                              ));
-                if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0;
-                ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" curr. " << curr << " R: "<<rValues[ridx]);
-             }
-	     addHV(v,hv,curr,wt);
-           }
-         }
-
-      } else if (abs(m_larem_id->barrel_ec(id))>1 && m_larem_id->sampling(id) > 0){ // LAr EMEC
-         unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
-         bool hasPathology=false;
-         if (index<hasPathologyEM.size()) {
-          if (hasPathologyEM[index].size()) {
-           hasPathology=true;
-           listElec = getElecList(id, pathologies);
-          }
-         }
+      float wt = 0.5;
+      for (unsigned int igap=0;igap<2;igap++) {
+	float hv=0;
+	float curr=0;
+	unsigned hvline = hvmodule.hvLineNo(igap,hvCabling);
+	auto hvIt=voltage.find(hvline);
+	if(hvIt != voltage.end()) {  //Found HV line
+	  hv=hvIt->second.hv;
+	  if(rValues && m_useCurrentOthers) { // modify the current record
+	    curr=hvIt->second.curr;
+	    unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(1,
+										    hvmodule.getSideIndex(),
+										    hvCabling->getCellModule(id),
+										    0, // not used in EMBPS
+										    hvmodule.getEtaIndex(),
+										    igap,
+										    0 // not used in EMBPS
+										    ));
+	    if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0;
+	    ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
+	  }//end have rValue
+	}//end have voltage
+	else {
+	  ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+	}
+	addHV(v,hv-curr,wt);
+      }//end loop over gaps
+    } else if (abs(m_larem_id->barrel_ec(id))>1 && m_larem_id->sampling(id) > 0){ // LAr EMEC
+      unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
+      bool hasPathology=false;
+      if (index<hasPathologyEM.size()) {
+	if (hasPathologyEM[index].size()) {
+	  hasPathology=true;
+	  listElec = getElecList(id, pathologies);
+	}
+      }
  
-         const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(id));
-         if (!emecElement) std::abort();
-         const EMECCellConstLink cell = emecElement->getEMECCell();
-         unsigned int nelec = cell->getNumElectrodes();
-         unsigned int ngap = 2*nelec;
-         double wt = 1./ngap;
-         for (unsigned int i=0;i<nelec;i++) {
-             const EMECHVElectrode& electrode = cell->getElectrode(i);
-             for (unsigned int igap=0;igap<2;igap++) {
-	       unsigned int hvline = electrode.hvLineNo(igap,hvCabling);
-	       const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                 if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-                   ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
-                   //return StatusCode::FAILURE;
-                   double hv=0;
-                   double curr=0;
-                   addHV(v,hv,curr,wt);
-                 } else {
-                   unsigned idx = itrLine - hvlineidx.begin(); 
-                   double hv=voltage[idx];
-                   double curr=current[idx];
-                   if(rValues) { // modify the current record
-                      const EMECHVModule &hvmod = electrode.getModule();
-                      unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(2,
-                                                                        hvmod.getSideIndex(),
-                                                                        hvCabling->getCellModule(id),
-                                                                        hvmod.getPhiIndex(),
-                                                                        hvmod.getEtaIndex(),
-                                                                        hvmod.getSectorIndex(),
-                                                                        electrode.getElectrodeIndex() ));
-                      if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
-                      ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" curr. " << curr << " R: "<<rValues[ridx]);
-                   }
-                   if (hasPathology) {
-                      msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]<<endmsg;
-                      for (unsigned int ii=0;ii<listElec.size();ii++) {
-                         if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
-                            if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
-                               hv=0.;
-                               curr = 0.;
-                            } else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) { 
-                               curr = 0.;
-                            } else {
-                               hv=((hasPathologyEM[index][listElec[ii]]&0xFFF0)>>4);
-                               curr=0.;
-                            }
-                         }
-                      }
-                   }
-                   addHV(v,hv,curr,wt);
-                 }
-             }
-         }
+      const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(hash));
+      if (!emecElement) std::abort();
+      const EMECCellConstLink cell = emecElement->getEMECCell();
+      unsigned int nelec = cell->getNumElectrodes();
+      unsigned int ngap = 2*nelec;
+      float wt = 1./ngap;
+      for (unsigned int i=0;i<nelec;i++) {
+	const EMECHVElectrode& electrode = cell->getElectrode(i);
+	for (unsigned int igap=0;igap<2;igap++) {
+	float hv=0;
+	float curr=0;
+	unsigned  hvline = electrode.hvLineNo(igap,hvCabling);
+	auto hvIt=voltage.find(hvline);
+	if(hvIt != voltage.end()) { //Found HV line
+	  hv=hvIt->second.hv;
+	  if(rValues && m_useCurrentOthers) { // modify the current record
+	    curr=hvIt->second.curr;
+	    const EMECHVModule &hvmod = electrode.getModule();
+	    unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(2,
+										    hvmod.getSideIndex(),
+										    hvCabling->getCellModule(id),
+										    hvmod.getPhiIndex(),
+										    hvmod.getEtaIndex(),
+										    hvmod.getSectorIndex(),
+										    electrode.getElectrodeIndex() ));
+	    if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
+	    ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
+	  }
+	  if (hasPathology) {
+	    msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]<<endmsg;
+	    for (unsigned int ii=0;ii<listElec.size();ii++) {
+	      if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
+		if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
+		  hv=0.;
+		  curr = 0.;
+		} else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) { 
+		  curr = 0.;
+		} else {
+		  hv=((hasPathologyEM[index][listElec[ii]]&0xFFF0)>>4);
+		  curr=0.;
+		}
+	      }
+	    }
+	  }//end hasPatology
+	}//end have voltage
+	else {
+	  ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+	}
+	addHV(v,hv-curr,wt);
+	}//end loop over gaps
+      }//end loop over electrodes
  
-      } else if (abs(m_larem_id->barrel_ec(id))>1 &&  m_larem_id->sampling(id)==0) { // EMECPS
+    } else if (abs(m_larem_id->barrel_ec(id))>1 &&  m_larem_id->sampling(id)==0) { // EMECPS
 
-         const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(id));
-         if (!emecElement) std::abort();
-         const EMECCellConstLink cell = emecElement->getEMECCell();
+      const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(hash));
+      if (!emecElement) std::abort();
+      const EMECCellConstLink cell = emecElement->getEMECCell();
+      const EMECPresamplerHVModule& hvmodule = cell->getPresamplerHVModule ();
  
-         const EMECPresamplerHVModule& hvmodule = cell->getPresamplerHVModule ();
- 
-         double wt = 0.5; 
-         for (unsigned int igap=0;igap<2;igap++) {
-	   unsigned int hvline = hvmodule.hvLineNo(igap,hvCabling);
-	   const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-             if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-	       ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
-                //return StatusCode::FAILURE;
-               double hv=0;
-               double curr=0;
-               addHV(v,hv,curr,wt);
-             } else {
-               unsigned idx = itrLine - hvlineidx.begin(); 
-               double hv=voltage[idx];
-               double curr=current[idx];
-	       if(rValues) { // modify the current record
-		 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(3,
-											 hvmodule.getSideIndex(),
-											 hvCabling->getCellModule(id),
-											 0, // not used in EMECPS
-											 0,
-											 igap,
-											 0 // not used in EMECPS
-											 ));
-		 if(curr >0.) curr *= uAkOhm * rValues[ridx]; else curr=0.;
-		 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" curr. " << curr << " R: "<<rValues[ridx]);
-	       }
-	       addHV(v,hv,curr,wt);
-             }
-         }
-
-      } else { // something wrong
-         ATH_MSG_ERROR("This could not be, what happened with EM identifiers ?");
-         return StatusCode::FAILURE;
-      }
+      double wt = 0.5; 
+      for (unsigned int igap=0;igap<2;igap++) {
+	float hv=0;
+	float curr=0;
+	unsigned int hvline = hvmodule.hvLineNo(igap,hvCabling);
+	auto hvIt=voltage.find(hvline);
+	if(hvIt != voltage.end()) { //Found HV line
+	  hv=hvIt->second.hv;
+	  if(rValues && m_useCurrentOthers) { // modify the current record
+	    curr=hvIt->second.curr;
+	    unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(3,
+										    hvmodule.getSideIndex(),
+										    hvCabling->getCellModule(id),
+										    0, // not used in EMECPS
+										    0,
+										    igap,
+										    0 // not used in EMECPS
+										    ));
+	    if(curr >0.) curr *= uAkOhm * rValues[ridx]; else curr=0.;
+	    ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
+	  }//end if rValues
+	   
+	}//end have hv-value
+	else {
+	    ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+	}
+	addHV(v,hv-curr,wt);
+      }//end loop over gaps
+    } else { // something wrong
+      ATH_MSG_ERROR("This could not be, what happened with EM identifiers ?");
+      return StatusCode::FAILURE;
+    }
+  } // end loop over EM-identifiers
 
-      hvmap.emplace(id,v);
-      if(!hvdataOld) { // all cells are updated
-         updatedCells.emplace(id);
-      } else { // check if it was changed
-	std::vector< LArHVData::HV_t > oldv=hvdataOld->getHV(id);
-	if (oldv.size()==0) return StatusCode::FAILURE;
-         if(v.size() == oldv.size()) {
-            unsigned int found=0;
-            for(unsigned int i=0;i<v.size();++i) {
-               for(unsigned int j=0; j<v.size(); ++j) {
-                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX  
-                               && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX ) {
-                     ++found;
-                     break;
-                  }
-               }
-            }   
-            if(found != v.size()) updatedCells.emplace(id);
 
-         } else { // different, changed
-            updatedCells.emplace(id);
-         }
-      }
-  } // loop over EM
   // LAr HEC
   for( auto id: m_larhec_id->channel_ids()) {
-    v.clear();
+    const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
     unsigned int index = (unsigned int)(m_larhec_id->channel_hash(id));
     bool hasPathology=false;
     if (index<hasPathologyHEC.size()) {
@@ -622,192 +601,147 @@ StatusCode LArHVCondAlg::fillPayload(LArHVData* hvdata
       listElec = getElecList(id, pathologies);
      }
     }
-    const HECDetectorElement* hecElement = dynamic_cast<const HECDetectorElement*>(calodetdescrmgr->get_element(id));
+    const HECDetectorElement* hecElement = dynamic_cast<const HECDetectorElement*>(calodetdescrmgr->get_element(hash));
     if (!hecElement) std::abort();
     const HECCellConstLink cell = hecElement->getHECCell();
     unsigned int nsubgaps = cell->getNumSubgaps();
-    double wt = 1./nsubgaps;
+    float wt = 1./nsubgaps;
+    voltageCell_t& v=hvdata[hash];
     for (unsigned int i=0;i<nsubgaps;i++) {
-        const HECHVSubgap& subgap = cell->getSubgap(i);
-	unsigned int hvline = subgap.hvLineNo(hvCabling);
-        const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-        if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-           ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0");
-           //return StatusCode::FAILURE;
-           double hv=0;
-           double curr=0;
-           addHV(v,hv,curr,wt);
-        } else {
-           unsigned idx = itrLine - hvlineidx.begin(); 
-           double hv=voltage[idx];
-           double curr=current[idx];
-           if(rValues) { // modify the current record
-              const HECHVModule &hvmod = subgap.getModule();
-              unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(4,
-                                                                hvmod.getSideIndex(),
-                                                                hvCabling->getCellModule(id),
-                                                                0, // not used in HEC
-                                                                hvmod.getSamplingIndex(),
-                                                                subgap.getSubgapIndex(),
-                                                                0 // not used in HEC
-                                                                 ));
-              if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
-              ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" cur. " << curr << " R: "<<rValues[ridx]);
-           }
-           if (hasPathology) {
-              msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larhec_id->print_to_string(id)<<" "<<hasPathologyHEC[index]<<endmsg;
-              for (unsigned int ii=0;ii<listElec.size();ii++) {
-                 if (listElec[ii]==i && listElec[ii]<hasPathologyHEC[index].size() && hasPathologyHEC[index][listElec[ii]]) {
-                      if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
-                         hv=0.;
-                         curr = 0.;
-                      } else if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
-                         curr = 0.;
-                      } else {
-                         hv=((hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
-                         curr=0.;
-                      }
-                 }
-              }
-           }
- 
-           addHV(v,hv,curr,wt);
-        }
-    }
-    hvmap.emplace(id,v);
-    if(!hvdataOld) { // all cells are updated
-       updatedCells.emplace(id);
-    } else { // check if it was changed
-      std::vector< LArHVData::HV_t > oldv=hvdataOld->getHV(id);
-      if (oldv.size()==0) return StatusCode::FAILURE;
-       if(v.size() == oldv.size()) {
-          unsigned int found=0;
-          for(unsigned int i=0;i<v.size();++i) {
-             for(unsigned int j=0; j<v.size(); ++j) {
-                if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX  
-                       && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
-                   ++found;
-                   break;
-                }
-             }
-          }   
-          if(found != v.size()) updatedCells.emplace(id);
-
-       } else { // different, changed
-          updatedCells.emplace(id);
-       }
-    }
-   } // loop over FCAL
-   for(auto id: m_larfcal_id->channel_ids()) { // LAr FCAL
-      v.clear();
-      unsigned int index = (unsigned int)(m_larfcal_id->channel_hash(id));
-      bool hasPathology=false;
-      if (index<hasPathologyFCAL.size()) {
-       if (hasPathologyFCAL[index].size()) {
+      float hv=0;
+      float curr=0;
+      const HECHVSubgap& subgap = cell->getSubgap(i);
+      unsigned int hvline = subgap.hvLineNo(hvCabling);
+      auto hvIt=voltage.find(hvline);
+      if(hvIt != voltage.end()) { //Found HV line
+	hv=hvIt->second.hv;
+	if(rValues && m_useCurrentOthers) { // modify the current record
+	  curr=hvIt->second.curr;
+	  const HECHVModule &hvmod = subgap.getModule();
+	  unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(4,
+										  hvmod.getSideIndex(),
+										  hvCabling->getCellModule(id),
+										  0, // not used in HEC
+										  hvmod.getSamplingIndex(),
+										  subgap.getSubgapIndex(),
+										  0 // not used in HEC
+										  ));
+	  if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
+	  ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" cur. " << curr << " R: "<<rValues[ridx]);
+	}
+	if (hasPathology) {
+	  msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larhec_id->print_to_string(id)<<" "<<hasPathologyHEC[index]<<endmsg;
+	  for (unsigned int ii=0;ii<listElec.size();ii++) {
+	    if (listElec[ii]==i && listElec[ii]<hasPathologyHEC[index].size() && hasPathologyHEC[index][listElec[ii]]) {
+	      if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
+		hv=0.;
+		curr = 0.;
+	      } else if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
+		curr = 0.;
+	      } else {
+		hv=((hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
+		curr=0.;
+	      }
+	    }
+	  }
+	}//end have pathology
+      } //end have voltage
+      else {
+	ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+      }
+      addHV(v,hv-curr,wt); 
+    }//end loop over subgaps
+  }//end loop over HEC-IDs
+
+
+  for(auto id: m_larfcal_id->channel_ids()) { // LAr FCAL
+    unsigned int index = (unsigned int)(m_larfcal_id->channel_hash(id));
+    const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
+    bool hasPathology=false;
+    if (index<hasPathologyFCAL.size()) {
+      if (hasPathologyFCAL[index].size()) {
         hasPathology=true;
         listElec = getElecList(id, pathologies);
-       }
       }
-      const FCALDetectorElement* fcalElement = dynamic_cast<const FCALDetectorElement*>(calodetdescrmgr->get_element(id));
-      if (!fcalElement) std::abort();
-      const FCALTile* tile = fcalElement->getFCALTile();
-      unsigned int nlines = tile->getNumHVLines();
-      unsigned int nlines_found=0;
+    }
+
+    const FCALDetectorElement* fcalElement = dynamic_cast<const FCALDetectorElement*>(calodetdescrmgr->get_element(hash));
+    if (!fcalElement) std::abort();
+    const FCALTile* tile = fcalElement->getFCALTile();
+    unsigned int nlines = tile->getNumHVLines();
+    unsigned int nlines_found=0;
+    for (unsigned int i=0;i<nlines;i++) {
+      const FCALHVLine* line = tile->getHVLine(i);
+      if (line) nlines_found++;
+    }
+    if (nlines_found>0) {
+      float wt = 1./nlines_found;
+      voltageCell_t& v=hvdata[hash]; 
       for (unsigned int i=0;i<nlines;i++) {
-        const FCALHVLine* line = tile->getHVLine(i);
-        if (line) nlines_found++;
-      }
-      if (nlines_found>0) {
-        double wt = 1./nlines_found;
-        for (unsigned int i=0;i<nlines;i++) {
-          const FCALHVLine* line = tile->getHVLine(i);
-          if (!line) continue;
-	  unsigned int ihvline = line->hvLineNo(hvCabling);
-          const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), ihvline);
-          if(itrLine == hvlineidx.end() || *itrLine != ihvline) { // error, could not find HVline index
-           ATH_MSG_WARNING("Do not have hvline: "<<ihvline<<" in LArHVData mapping ! Set voltage to 0 !");
-           //return StatusCode::FAILURE;
-           double hv=0;
-           double curr=0;
-           addHV(v,hv,curr,wt);
-          } else {
-           unsigned idx = itrLine - hvlineidx.begin(); 
-           double hv=voltage[idx];
-           double curr=current[idx];
-           if(rValues) { // modify the current record
-              const FCALHVModule& hvmod = line->getModule();
-              unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(5,
-                                                                hvmod.getSideIndex(),
-                                                                hvCabling->getCellModule(id),
-                                                                0, // not used in FCAL
-                                                                hvmod.getSamplingIndex(),
-                                                                hvmod.getSectorIndex(),
-                                                                line->getLineIndex()
-                                                                 ));
-              if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
-              ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<idx<<" curr." << curr << " R: "<<rValues[ridx]);
-           }
-           if (hasPathology) {
-              msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larfcal_id->print_to_string(id)<<" "<<hasPathologyFCAL[index]<<endmsg;
-              for (unsigned int ii=0;ii<listElec.size();ii++) {
-                 if (listElec[ii]==i && listElec[ii]<hasPathologyFCAL[index].size() && hasPathologyFCAL[index][listElec[ii]]) {
-                      if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskHV){
-                         hv=0.;
-                         curr = 0.;
-                      } else if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
-                         curr = 0.;
-                      } else {
-                         hv=((hasPathologyFCAL[index][listElec[ii]]&0xFFF0)>>4);
-                         curr=0.;
-                      }
-                 }
-              }
-           }
-           addHV(v,hv,curr,wt);
-          }
-        }
-      }
-      hvmap.emplace(id,v);
-      if(!hvdataOld) { // all cells are updated
-         updatedCells.emplace(id);
-      } else { // check if it was changed
-	std::vector< LArHVData::HV_t > oldv=hvdataOld->getHV(id);
-	if (oldv.size()==0) return StatusCode::FAILURE;
-         if(v.size() == oldv.size()) {
-            unsigned int found=0;
-            for(unsigned int i=0;i<v.size();++i) {
-               for(unsigned int j=0; j<v.size(); ++j) {
-                  if(fabs(v[i].hv - oldv[j].hv) < VDIFF_MAX && fabs(v[i].current - oldv[j].current) < IDIFF_MAX 
-                           && fabs(v[i].weight - oldv[j].weight) < WDIFF_MAX) {
-                     ++found;
-                     break;
-                  }
-               }
-            }   
-            if(found != v.size()) updatedCells.emplace(id);
- 
-         } else { // different, changed
-            updatedCells.emplace(id);
-         }
-      }
-   } // loop over FCAL
+	const FCALHVLine* line = tile->getHVLine(i);
+	if (!line) continue;
+	unsigned int hvline = line->hvLineNo(hvCabling);
+	float hv=0;
+	float curr=0;
+	auto hvIt=voltage.find(hvline);
+	if(hvIt != voltage.end()) { //Found HV line
+	  hv=hvIt->second.hv;
+	  bool useCurrent= (m_larfcal_id->module(id)==1 && m_useCurrentFCAL1) || (m_larfcal_id->module(id)!=1 && m_useCurrentOthers);
+	  if(rValues && useCurrent) { // modify the current record
+	    curr=hvIt->second.curr;
+	    const FCALHVModule& hvmod = line->getModule();
+	    unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(5,
+										    hvmod.getSideIndex(),
+										    hvCabling->getCellModule(id),
+										    0, // not used in FCAL
+										    hvmod.getSamplingIndex(),
+										    hvmod.getSectorIndex(),
+										    line->getLineIndex()
+										    ));
+	    if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
+	    ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr." << curr << " R: "<<rValues[ridx]);
+	  }
+	  if (hasPathology) {
+	    msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larfcal_id->print_to_string(id)<<" "<<hasPathologyFCAL[index]<<endmsg;
+	    for (unsigned int ii=0;ii<listElec.size();ii++) {
+	      if (listElec[ii]==i && listElec[ii]<hasPathologyFCAL[index].size() && hasPathologyFCAL[index][listElec[ii]]) {
+		if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskHV){
+		  hv=0.;
+		  curr = 0.;
+		} else if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
+		  curr = 0.;
+		} else {
+		  hv=((hasPathologyFCAL[index][listElec[ii]]&0xFFF0)>>4);
+		  curr=0.;
+		}
+	      }
+	    }
+	  }//end if have pathology
+	}//end got voltage
+		else {
+	    ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
+	}
+	addHV(v,hv-curr,wt);
+
+      }//end loop over lines
+    }//end if found line
+  }// end loop over fcal ids
   
   return StatusCode::SUCCESS; 
 }
 
-void LArHVCondAlg::addHV(std::vector< LArHVData::HV_t > & v , double hv, double curr, double wt) const
-{
-         bool found=false;
-         for (unsigned int i=0;i<v.size();i++) {
-	   if (std::fabs(hv-v[i].hv) < 0.1 && std::fabs (curr-v[i].current)<0.1) {
-               found=true;  
-               v[i].weight += wt;
-               break;
-             }
-         }
-         if (!found) {
-	   v.emplace_back(hv,curr,wt);
-         }     // not already in the list
+void LArHVCondAlg::addHV(voltageCell_t& v , float hv, float wt) const {
+  bool found=false;
+  for (unsigned int i=0;i<v.size();i++) {
+    if (std::fabs(hv-v[i].hv) <0.1) {
+      found=true;  
+      v[i].weight += wt;
+      break;
+    }
+  }
+  if (!found) {
+    v.emplace_back(hv,wt);
+  }     // not already in the list
 }
 
 
@@ -827,16 +761,11 @@ std::vector<unsigned int> LArHVCondAlg::getElecList(const Identifier& id, const
 
 
 
-StatusCode LArHVCondAlg::fillUpdatedHVChannelsVec(std::vector<float> &voltageCache, std::vector<float> &currentCache, std::vector<unsigned int> &hvlineidx, std::vector<const CondAttrListCollection* > fldvec) const {
+StatusCode LArHVCondAlg::dcs2LineVoltage(voltagePerLine_t& result, const std::vector<const CondAttrListCollection* > fldvec) const {
 
-  //const unsigned nHVCoolChannels=453+4384;
 
-  //Loop over the list of DCS folders
+  result.clear();
 
-  voltageCache.clear();
-  currentCache.clear();
-  hvlineidx.clear();
-  std::vector<std::tuple<unsigned int, float, float>> sorttmp;
   ATH_MSG_DEBUG("Got "<<fldvec.size()<<" DCS HV folders");
   for(auto attrlist : fldvec) { // loop over all DCS folders
     CondAttrListCollection::const_iterator citr=attrlist->begin(); 
@@ -852,23 +781,19 @@ StatusCode LArHVCondAlg::fillUpdatedHVChannelsVec(std::vector<float> &voltageCac
       float current=0.;
       if (!attrc.isNull()) current=attrc.data<float>(); //Ignore NULL values
       ATH_MSG_VERBOSE("read voltage: "<<voltage<<" and current: "<<current );
-      sorttmp.emplace_back(chan, voltage, current);
+      auto empl=result.emplace(chan,DCS_t{voltage,current});
+      if (!empl.second) {
+	ATH_MSG_WARNING("DCS channel " << chan << " encountered twice!");
+      }
     }//end loop over attributeListCollection
   }
-  std::sort(sorttmp.begin(), sorttmp.end());
-  for (const auto& tup: sorttmp) {
-    hvlineidx.push_back(std::get<0>(tup));
-    voltageCache.push_back(std::get<1>(tup));
-    currentCache.push_back(std::get<2>(tup));
-  }
   return StatusCode::SUCCESS;
 }
 
 //=========================================================================================
 StatusCode LArHVCondAlg::searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffected
 						, const LArHVIdMapping* hvCabling
-						, const std::vector<float> &voltage
-						, const std::vector<unsigned int> &hvlineidx) const {  // deals with LAr HV, EMBarrel
+						, const voltagePerLine_t& voltage) const {  // deals with LAr HV, EMBarrel
 
   ATH_MSG_DEBUG(" start HV_EMB ");
   const LArHVManager *manager = nullptr;
@@ -899,14 +824,12 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffe
 	      double hv[2];
 	      for (unsigned int iGap=0;iGap<2;iGap++) { // EMB : 2, TRY TO FIND AUTOMATICALLY NB OF GAPS
 		unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
-                const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
+		auto hvIt=voltage.find(hvline);
+		if(hvIt == voltage.end()) { 
                   ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
                   continue;
-                  //return StatusCode::FAILURE;
-                }
-                //unsigned idx = itrLine - hvlineidx.begin(); 
-		hv[iGap]=voltage[itrLine - hvlineidx.begin()];
+		}
+		hv[iGap]=hvIt->second.hv;
 	      } //end for iGap
 
               ATH_MSG_VERBOSE(" electrode HV " << ielec << " " << electrode.getPhi() << " "<< hv[0] << " " << hv[1] );
@@ -988,14 +911,13 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffe
             double hv[2];
             for (int iGap=0;iGap<2;iGap++) {
 	      unsigned int hvline = hvMod.hvLineNo(iGap,hvCabling);
-	      const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-                  ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
-                  continue;
-                  //return StatusCode::FAILURE;
-                }
-		hv[iGap]=fabs(voltage[itrLine - hvlineidx.begin()]);
-            }
+	      auto hvIt=voltage.find(hvline);
+	      if(hvIt == voltage.end()) { 
+		ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
+		continue;
+	      }
+	      hv[iGap]=hvIt->second.hv;
+	    }
             float eta_min=hvMod.getEtaMin();
             float eta_max=hvMod.getEtaMax();
             float phi_min=CaloPhiRange::fix(hvMod.getPhiMin());
@@ -1028,9 +950,8 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffe
 }
 //=========================================================================================
 StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec *vAffected
-						       , const LArHVIdMapping* hvCabling						       
-						       , const std::vector<float> &voltage
-						       , const std::vector<unsigned int> &hvlineidx) const { // deals with LAr HV, EM EndCap OUTER
+						       , const LArHVIdMapping* hvCabling
+						       , const voltagePerLine_t& voltage) const { // deals with LAr HV, EM EndCap OUTER
 
   const LArHVManager *manager = nullptr;
 
@@ -1066,13 +987,12 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec
 	      double hv[2];
 	      for (unsigned int iGap=0;iGap<2;iGap++) { //EMEC : 2 gaps, TRY TO FIND AUTOMATICALLY NB OF GAPS
 		unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
-		const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                  if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-		    ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
-                    continue;
-                     //return StatusCode::FAILURE;
-                  }
-		  hv[iGap]=voltage[itrLine - hvlineidx.begin()];
+		auto hvIt=voltage.find(hvline);
+		if(hvIt == voltage.end()) { 
+                  ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
+                  continue;
+		}
+		hv[iGap]=hvIt->second.hv;
 	      } //end for iGap
 
 	      //------------------
@@ -1156,14 +1076,13 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec
             double hv[2];
             for (int iGap=0;iGap<2;iGap++) {
 	      unsigned int hvline = hvMod.hvLineNo(iGap,hvCabling);
-	      const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
+	      auto hvIt=voltage.find(hvline);
+		if(hvIt == voltage.end()) { 
                   ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
                   continue;
-                  //return StatusCode::FAILURE;
-                }
-		hv[iGap]=fabs(voltage[itrLine - hvlineidx.begin()]);
-            }
+		}
+		hv[iGap]=hvIt->second.hv;
+            }//end loop over gaps
             float eta_min=hvMod.getEtaMin(); 
             float eta_max=hvMod.getEtaMax();
             float phi_min=CaloPhiRange::fix(hvMod.getPhiMin());
@@ -1190,7 +1109,7 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec
       }        // loop over iphi EMECPS
     }    // lop over EMECPS side
   } else {
-     ATH_MSG_ERROR("DO not have MEC HV manager !");
+     ATH_MSG_ERROR("DO not have EMEC HV manager !");
      return StatusCode::FAILURE;
   }
   return StatusCode::SUCCESS;
@@ -1198,8 +1117,7 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec
 //=========================================================================================
 StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_INNER(CaloAffectedRegionInfoVec *vAffected
 						       , const LArHVIdMapping* hvCabling
-						       , const std::vector<float> &voltage
-						       , const std::vector<unsigned int> &hvlineidx) const { // deals with LAr HV, EM EndCap INNER
+						       , const voltagePerLine_t& voltage) const { // deals with LAr HV, EM EndCap INNER
   const LArHVManager *manager = nullptr;
 
   ATH_MSG_VERBOSE(" start loop over EMEC_INNER ");
@@ -1232,13 +1150,12 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_INNER(CaloAffectedRegionInfoVec
 	      double hv[2];
 	      for (unsigned int iGap=0;iGap<2;iGap++) { 
 		unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
-		const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-                  if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-		    ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
-                    continue;
-                     //return StatusCode::FAILURE;
-                  }
-		  hv[iGap]=voltage[itrLine - hvlineidx.begin()];
+		auto hvIt=voltage.find(hvline);
+		if(hvIt == voltage.end()) { 
+                  ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
+                  continue;
+		}
+		hv[iGap]=hvIt->second.hv;
 	      } //end for iGap
 
 	      //------------------
@@ -1322,8 +1239,7 @@ StatusCode LArHVCondAlg::searchNonNominalHV_EMEC_INNER(CaloAffectedRegionInfoVec
 //=========================================================================================
 StatusCode LArHVCondAlg::searchNonNominalHV_HEC(CaloAffectedRegionInfoVec *vAffected
 						, const LArHVIdMapping* hvCabling
-						, const std::vector<float> &voltage
-						, const std::vector<unsigned int> &hvlineidx) const { // deals with LAr HV, HEC
+						, const voltagePerLine_t& voltage) const { // deals with LAr HV, HEC
   
   ATH_MSG_DEBUG(" in HEC ");
   const LArHVManager *manager = nullptr;
@@ -1356,13 +1272,12 @@ StatusCode LArHVCondAlg::searchNonNominalHV_HEC(CaloAffectedRegionInfoVec *vAffe
 	  for (unsigned int iGap=0;iGap<hvMod.getNumSubgaps();iGap++) {
 	    const HECHVSubgap& subgap=hvMod.getSubgap(iGap);
 	    unsigned int hvline = subgap.hvLineNo(hvCabling);
-            const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), hvline);
-            if(itrLine == hvlineidx.end() || *itrLine != hvline) { // error, could not find HVline index
-              ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuminh missing DCS data !");
-              continue;
-              //return StatusCode::FAILURE;
-            }
-	    if(iGap<4) hv[iGap]=voltage[itrLine - hvlineidx.begin()];
+	    auto hvIt=voltage.find(hvline);
+	    if(hvIt == voltage.end()) { 
+	      ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
+	      continue;
+	    }
+	    if(iGap<4) hv[iGap]=hvIt->second.hv;
 	  }// end for iGap
 
 	  //------------------
@@ -1402,8 +1317,7 @@ StatusCode LArHVCondAlg::searchNonNominalHV_HEC(CaloAffectedRegionInfoVec *vAffe
 //=========================================================================================
 StatusCode LArHVCondAlg::searchNonNominalHV_FCAL(CaloAffectedRegionInfoVec *vAffected
 						 , const LArHVIdMapping* hvCabling
-						 , const std::vector<float> &voltage
-						 , const std::vector<unsigned int> &hvlineidx) const { // deals with LAr HV, FCAL
+						 , const voltagePerLine_t& voltage) const { // deals with LAr HV, FCAL
 
   ATH_MSG_DEBUG( " inFCAL ");
   const LArHVManager *manager = nullptr;
@@ -1438,13 +1352,12 @@ StatusCode LArHVCondAlg::searchNonNominalHV_FCAL(CaloAffectedRegionInfoVec *vAff
 	  for (unsigned int iLine=0;iLine<hvMod.getNumHVLines();iLine++) {
 	    const FCALHVLine& hvline = hvMod.getHVLine(iLine);
 	    unsigned int ihvline = hvline.hvLineNo(hvCabling);
-            const std::vector<unsigned int>::const_iterator itrLine=std::lower_bound(hvlineidx.begin(), hvlineidx.end(), ihvline);
-            if(itrLine == hvlineidx.end() || *itrLine != ihvline) { // error, could not find HVline index
-              ATH_MSG_WARNING("Do not have hvline: "<<ihvline<<" in LArHVData ! Assuming missing DCS data !");
-              continue;
-              //return StatusCode::FAILURE;
-            }
-	    if (iLine<4) hv[iLine] = voltage[itrLine - hvlineidx.begin()];
+	    auto hvIt=voltage.find(ihvline);
+	    if(hvIt == voltage.end()) { 
+	      ATH_MSG_WARNING("Do not have hvline: "<<ihvline<<" in LArHVData ! Assuming missing DCS data");
+	      continue;
+	    }
+	    if (iLine<4) hv[iLine]=hvIt->second.hv;
           }
 	  //------------------
 	  //take decisions according to all the gaps HV :
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.h b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.h
index 3a9f5b47462806ff902c4ae54c00c03f30968ec9..caf150899192d2ee3d68a0f32bc2df09f2021f2c 100755
--- a/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.h
+++ b/LArCalorimeter/LArRecUtils/src/LArHVCondAlg.h
@@ -1,3 +1,4 @@
+//Dear emacs, this is -*-c++-*-
 /*
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
@@ -7,7 +8,6 @@
 
 */
 
-
 #ifndef LARHVCONDALG_H
 #define LARHVCONDALG_H
 
@@ -18,20 +18,26 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "LArRecConditions/LArHVPathology.h"
 #include "LArRecConditions/LArHVData.h"
+
+#include "LArRawConditions/LArHVScaleCorrComplete.h"
+
 #include "CaloConditions/CaloAffectedRegionInfoVec.h"
 #include "LArRecConditions/LArBadChannelCont.h"
 #include "LArCabling/LArOnOffIdMapping.h"
 #include "LArRecConditions/LArHVIdMapping.h"
+#include "LArRecConditions/LArHVCorr.h"
 
 #include "StoreGate/ReadCondHandleKey.h"
 #include "StoreGate/WriteCondHandleKey.h"
 #include "StoreGate/CondHandleKeyArray.h"
 #include "GaudiKernel/ICondSvc.h"
 
+#include "LArHVScaleCorrTool.h"
 
 // forward declaration
 class CondAttrListCollection;
 class AthenaAttributeList;
+class CaloCell_ID;
 class LArEM_ID;
 class LArHEC_ID;
 class LArFCAL_ID;
@@ -49,110 +55,138 @@ class LArHVCondAlg: public AthReentrantAlgorithm
 
   LArHVCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
 
-  virtual ~LArHVCondAlg() override;
+  virtual ~LArHVCondAlg() = default;
 
   virtual StatusCode initialize() override;
   virtual StatusCode finalize() override;
   StatusCode execute(const EventContext& ctx) const override;
 
 
-  private:
+private:
 
   // Conditions keys read:
-
   SG::ReadCondHandleKey<LArHVPathology> m_pathologiesKey { this, "HVPathologies", "LArHVPathology", "Key for HV pathologies in Cond. store"};
-
-  SG::ReadCondHandleKeyArray<CondAttrListCollection>  m_DCSFolderKeys { this, "DCSFolderNames", {"/LAR/DCS/HV/BARREl/I16", "/LAR/DCS/HV/BARREL/I8"}, "DCS folders with HV values"};
-
+  SG::ReadCondHandleKeyArray<CondAttrListCollection>  m_DCSFolderKeys { this, "DCSFolderNames", {"/LAR/DCS/HV/BARREl/I16", "/LAR/DCS/HV/BARREL/I8"}, 
+									  "DCS folders with HV values"};
   SG::ReadCondHandleKey<LArBadFebCont> m_BFKey{this, "MissingFEBKey", "LArBadFeb", "SG key for missing FEB object"};
-
   SG::ReadCondHandleKey<LArOnOffIdMapping> m_cablingKey{this, "OnOffMap", "LArOnOffIdMap", "SG key for mapping object"};
-
   SG::ReadCondHandleKey<LArHVIdMapping> m_hvMappingKey {this, "HVMappingKey", "LArHVIdMap", "Key for mapping object" };
-
   SG::ReadCondHandleKey<AthenaAttributeList>   m_hvRKey{this, "RvaluesKey", "/LAR/HVPathologiesOfl/Rvalues", "Cool folder with HV R values"};
 
   // Conditions keys write:
-  SG::WriteCondHandleKey<LArHVData> m_hvDataKey {this, "OutputHVData", "LArHVData", "Key for output HV data object"};
+  SG::WriteCondHandleKey<CaloAffectedRegionInfoVec> m_affectedKey{this, "OutputKey", "LArAffectedRegionInfo", "SG key for output"};
+
+  SG::ReadCondHandleKey<ILArHVScaleCorr> m_onlineHVScaleCorrKey{this, "keyOnlineHVCorr", "LArHVScaleCorr",
+                                                                "Input key for HVScaleCorr from conditions database (used online)"};
+
+  SG::WriteCondHandleKey<LArHVCorr> m_outputHVScaleCorrKey{this, "keyOutputCorr", "LArHVScaleCorrRecomputed","Output key for LArHVScaleCorr"};
+
+  //Other properties:
   
-  SG::WriteCondHandleKey<CaloAffectedRegionInfoVec> m_outKey{this, "OutputKey", "LArAffectedRegionInfo", "SG key for output"};
+  Gaudi::Property<bool> m_undoOnlineHVCorr{this,"UndoOnlineHVCorr",true,"Undo the HVCorr done online"};
+  Gaudi::Property<bool> m_useCurrentEMB{this,"UseCurrentsInHVEM",false,"Use currents in EMB as well"};
+  Gaudi::Property<bool> m_useCurrentFCAL1{this,"UseCurrentsInHVFCAL1",false,"Use currents in FCAL1 as well"};
+  Gaudi::Property<bool> m_useCurrentOthers{this,"UseCurrentsInHVOthers", "Use currents in other partitions as well"};
+
+  Gaudi::Property<bool> m_doAffected{this,"doAffected",true,"create affected region info"};
+  Gaudi::Property<bool> m_doAffectedHV{this,"doAffectedHV",true,"include HV non nominal regions info"};
+
+  ServiceHandle<ICondSvc> m_condSvc{this,"CondSvc","CondSvc"};
+
+  Gaudi::Property<std::vector<std::string> > m_fixHVStrings{this,"fixHVCorr"};
 
   // other members:
-  
-  const LArEM_ID* m_larem_id;
-  const LArHEC_ID* m_larhec_id;
-  const LArFCAL_ID* m_larfcal_id;
-  const LArElectrodeID* m_electrodeID;
-  const LArHVLineID* m_hvLineID;
-  const LArOnlineID* m_onlineID;
-  ServiceHandle<ICondSvc> m_condSvc;
+  const CaloCell_ID* m_calocellID=nullptr;
+  const LArEM_ID* m_larem_id=nullptr;
+  const LArHEC_ID* m_larhec_id=nullptr;
+  const LArFCAL_ID* m_larfcal_id=nullptr;
+  const LArElectrodeID* m_electrodeID=nullptr;
+  const LArHVLineID* m_hvLineID=nullptr;
+  const LArOnlineID* m_onlineID=nullptr;
+
+  std::unique_ptr<const LArHVScaleCorrTool> m_scaleTool;
 
   bool m_doHV;
   bool m_doR;
-  bool m_doAffected;
-  bool m_doAffectedHV;
-
-  // private methods:
-  
-  // for the LArHVData construction:
 
+  //Internal representation of voltage & current per HV-Line (read for DCS)
+  struct DCS_t {
+    DCS_t(float ihv, float icurr) : hv(ihv),curr(icurr) {};
+    DCS_t() = delete;
+    float hv;
+    float curr;
+  };
+  typedef std::unordered_map<unsigned,DCS_t> voltagePerLine_t;
+
+  // //Internal representation of voltage & current per cell: 
+  // struct HV_t {
+  //   HV_t(float ihv, float iweight) : hv(ihv), weight(iweight) {};
+  //   float hv; //voltage, potentially current*R corrected
+  //   float weight;
+  // };
+  // typedef std::vector<HV_t> voltageCell_t;
+
+  typedef LArHVScaleCorrTool::HV_t HV_t;
+  typedef LArHVScaleCorrTool::voltageCell_t voltageCell_t;
+
+  typedef std::vector<voltageCell_t> voltagePerCell_t;
+
+  ///Internal strucutre for HV pathologies
   typedef std::vector<std::vector<unsigned short> > pathVec;
 
-  StatusCode fillPayload(LArHVData *hvdata
-			 , const LArHVData* hvdataOld
-			 , const LArHVIdMapping* hvCabling
-			 , std::vector<float> &voltage
-			 , std::vector<float> &current
-			 , std::vector<unsigned int> &hvlineidx
-			 , const LArHVPathology& pathologies
-			 , pathVec& hasPathologyEM
-			 , pathVec& hasPathologyHEC
-			 , pathVec& hasPathologyFCAL
-                         , const float* rValues) const;
+  /// Add voltage/weight for a sub-gap of a cell 
+  void addHV(voltageCell_t& v, float hv, float weight) const;
+
+  /// Read HV from DCS, store them in internal data structure per HV-line (Step 1)
+  StatusCode  dcs2LineVoltage(voltagePerLine_t& result, const std::vector<const CondAttrListCollection* > fldvec) const;
+
+  /// Read the voltage per HV line and store it in structure per readout-cell (resolve the many-HV-lines-to-many-cells mapping). Simulanitously fill the pathologies
+  StatusCode fillPathAndCellHV(voltagePerCell_t& hvdata
+			       , const LArHVIdMapping* hvCabling
+			       , const voltagePerLine_t& voltage
+			       , const LArHVPathology& pathologies
+			       , pathVec& hasPathologyEM
+			       , pathVec& hasPathologyHEC
+			       , pathVec& hasPathologyFCAL
+			       , const float* rValues) const;
 
-  void addHV(std::vector< LArHVData::HV_t > & v, double hv, double curr, double wt) const;
 
   std::vector<unsigned int> getElecList(const Identifier& id, const LArHVPathology& pathologies) const;
-  StatusCode fillUpdatedHVChannelsVec(std::vector<float> &voltage, std::vector<float> &current, std::vector<unsigned int> &hvlineidx, std::vector<const CondAttrListCollection* > fldvec) const;
 
-  // for the LArAffectedRegions construction
 
+
+
+
+  // for the LArAffectedRegions construction
   void extendPhiRegion(float phi, float & phi_min, float & phi_max) const;
 
   StatusCode updateMethod(CaloAffectedRegionInfoVec *vAffected, const LArBadFebCont* bfCont, const LArOnOffIdMapping* cabling) const;
 
   StatusCode searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffected
 				    , const LArHVIdMapping* hvCabling
-				    , const std::vector<float> &voltage
-				    , const std::vector<unsigned int> &hvlineidx) const;
+				    , const voltagePerLine_t& voltage) const;
 
   StatusCode searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec *vAffected
 					   , const LArHVIdMapping* hvCabling
-					   , const std::vector<float> &voltage
-					   , const std::vector<unsigned int> &hvlineidx) const;
+					   , const voltagePerLine_t& voltage) const;
 
   StatusCode searchNonNominalHV_EMEC_INNER(CaloAffectedRegionInfoVec *vAffected
 					   , const LArHVIdMapping* hvCabling
-					   , const std::vector<float> &voltage
-					   , const std::vector<unsigned int> &hvlineidx) const;
+					   , const voltagePerLine_t& voltage) const;
 
   StatusCode searchNonNominalHV_HEC(CaloAffectedRegionInfoVec *vAffected
 				    , const LArHVIdMapping* hvCabling
-				    , const std::vector<float> &voltage
-				    , const std::vector<unsigned int> &hvlineidx) const;
+				    , const voltagePerLine_t& voltage) const;
+
 
   StatusCode searchNonNominalHV_FCAL(CaloAffectedRegionInfoVec *vAffected
 				     , const LArHVIdMapping* hvCabling
-				     , const std::vector<float> &voltage
-				     , const std::vector<unsigned int> &hvlineidx) const;
+				     , const voltagePerLine_t& voltage) const;
+
   float HV_nominal(const char *identification,const float eta) const;
   std::vector<int> returnProblem(const float eta, const float phi, const float delta_eta, const float delta_phi);
 
 };
 
-//inline 
-//const std::vector<HWIdentifier>&  LArHVCondAlg::getUpdatedElectrodes() { 
-//  return m_updatedElectrodes;
-//}
 
 #endif
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.cxx b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.cxx
deleted file mode 100644
index 86c679a8991bd6d0a0967bc23dcf5a34d15602d8..0000000000000000000000000000000000000000
--- a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.cxx
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "LArHVScaleCorrCondAlg.h"
-#include "AthenaKernel/errorcheck.h"
-#include "GaudiKernel/ThreadLocalContext.h"
-#include "CaloDetDescr/CaloDetDescrElement.h"
-
-#include "AthenaPoolUtilities/CondAttrListCollection.h"
-#include "AthenaPoolUtilities/AthenaAttributeList.h"
-#include "CoralBase/Blob.h"
-
-#include "GaudiKernel/IChronoStatSvc.h"
-#include "CLHEP/Units/SystemOfUnits.h"
-#include "LArIdentifier/LArElectrodeID.h"
-
-#include <cmath>
-#include <bitset>
-
-using CLHEP::microsecond;
-using CLHEP::second;
-
-LArHVScaleCorrCondAlg::LArHVScaleCorrCondAlg(const std::string& name, ISvcLocator* pSvcLocator) 
-  : 
-    AthAlgorithm(name, pSvcLocator ), m_condSvc("CondSvc",name),
-    m_lar_on_id(nullptr), 	    
-    m_calocell_id(nullptr),	
-    m_larem_id(nullptr),
-    m_larhec_id(nullptr),
-    m_larfcal_id(nullptr),	
-    m_electrodeID(nullptr)
-{
-  m_T0 = 90.371;   // parameter for vdrift
-
-  declareProperty("fixHVCorr",    m_fixHVStrings);
-  declareProperty("UndoOnlineHVCorr",m_undoOnlineHVCorr=true,"Undo the HVCorr done online");
-  declareProperty("UseCurrentsInHVEMB",  m_useCurrentEMB=false, "Use currents in EMB as well");
-  declareProperty("UseCurrentsInHVFCAL1",  m_useCurrentFCAL1=false, "Use currents in FCAL1 as well");
-  declareProperty("UseCurrentsInHVOthers",  m_useCurrentOthers=false, "Use currents in other partitions as well");
-}
-
-
-LArHVScaleCorrCondAlg::~LArHVScaleCorrCondAlg() {
-}
-
-StatusCode LArHVScaleCorrCondAlg::initialize() {
-  ATH_MSG_DEBUG("LArHVScaleCorrCondAlg initialize() begin");
-  
-  // CondSvc
-  ATH_CHECK( m_condSvc.retrieve() );
-
-  // retrieve id helpers
-  ATH_CHECK(detStore()->retrieve(m_lar_on_id,"LArOnlineID"));
-  ATH_CHECK(detStore()->retrieve(m_calocell_id,"CaloCell_ID"));
-
-  m_larem_id   = m_calocell_id->em_idHelper();
-  m_larhec_id   = m_calocell_id->hec_idHelper();
-  m_larfcal_id   = m_calocell_id->fcal_idHelper();
-
-  ATH_CHECK(detStore()->retrieve(m_electrodeID));
-
-  ATH_CHECK(this->buildFixHVList());
-
-  //Initialize hash-ranges
-  //FIXME: Hardcoded numbers are not ideal
-  //But the identifier helpers don't provide them. 
-
-  const unsigned A=1; 
-  const unsigned C=0;
-  //Offline hash ranges:
-  m_hashRanges[A].resize(NHVPARTITION);
-  m_hashRanges[C].resize(NHVPARTITION);
-  m_hashRanges[C][EMECIW]=std::make_pair<IdentifierHash,IdentifierHash>(0,896);
-  m_hashRanges[C][EMECPS]=std::make_pair<IdentifierHash,IdentifierHash>(896,1664);
-  m_hashRanges[C][EMECOW]=std::make_pair<IdentifierHash,IdentifierHash>(1664,31872);
-  m_hashRanges[C][EMBPS]=std::make_pair<IdentifierHash,IdentifierHash>(31872,35776);
-  m_hashRanges[C][EMB]=std::make_pair<IdentifierHash,IdentifierHash>(35776,86656);
-  m_hashRanges[A][EMBPS]=std::make_pair<IdentifierHash,IdentifierHash>(86656,90560);
-  m_hashRanges[A][EMB]=std::make_pair<IdentifierHash,IdentifierHash>(90560,141440);
-  m_hashRanges[A][EMECPS]=std::make_pair<IdentifierHash,IdentifierHash>(141440,142208);
-  m_hashRanges[A][EMECOW]=std::make_pair<IdentifierHash,IdentifierHash>(142208,172416);
-  m_hashRanges[A][EMECIW]=std::make_pair<IdentifierHash,IdentifierHash>(172416,173312);
-  m_hashRanges[C][HEC]=std::make_pair<IdentifierHash,IdentifierHash>(173312,176128);
-  m_hashRanges[A][HEC]=std::make_pair<IdentifierHash,IdentifierHash>(176128,178944);
-  m_hashRanges[C][FCAL]=std::make_pair<IdentifierHash,IdentifierHash>(178944,180706);
-  m_hashRanges[A][FCAL]=std::make_pair<IdentifierHash,IdentifierHash>(180706,182468);
-
-  m_completeRange.push_back(std::make_pair<IdentifierHash,IdentifierHash>(0,182468));
-
-
-  ATH_MSG_INFO( "Will re-compute HV correction for channels with updated voltage" );
-
-  ATH_CHECK(m_cablingKey.initialize());
-  ATH_CHECK(m_hvKey.initialize());
-  if(m_undoOnlineHVCorr) ATH_CHECK(m_onlineHVScaleCorrKey.initialize());
-
-  ATH_CHECK(m_outputHVScaleCorrKey.initialize());
-
-  // Register write handle
-  ATH_CHECK(m_condSvc->regHandle(this, m_outputHVScaleCorrKey)); 
-
-  ATH_MSG_DEBUG("LArHVScaleCorrCondAlg initialize() end");
-  return StatusCode::SUCCESS;
-}
-
-StatusCode LArHVScaleCorrCondAlg::execute() {
-  
-  const EventContext& ctx = Gaudi::Hive::currentContext();
-  // test validity of write handle
-  SG::WriteCondHandle<ILArHVScaleCorr>  writeHandle(m_outputHVScaleCorrKey, ctx);
-  if (writeHandle.isValid()) {
-    ATH_MSG_DEBUG( "Found valid " << writeHandle.fullKey() << " handle.");
-    return StatusCode::SUCCESS;
-  }
-
-  // get DCS HVData
-  SG::ReadCondHandle<LArHVData> hvDataHdl(m_hvKey, ctx);
-  const LArHVData *hvdata = *hvDataHdl;
-  
-  // Define validity of the output cond object
-  EventIDRange rangeW;
-  if(!hvDataHdl.range(rangeW)) {
-    ATH_MSG_ERROR("Failed to retrieve validity range for " << hvDataHdl.key());
-    return StatusCode::FAILURE;
-  }
-
-  ATH_MSG_DEBUG("Range LArHVData " << rangeW);
-
-  // Online HVScaleCorr (if needed to subtract)
-  const ILArHVScaleCorr *onlHVCorr = nullptr;
-  if(m_undoOnlineHVCorr) {
-     SG::ReadCondHandle<ILArHVScaleCorr> onlHVCorrHdl(m_onlineHVScaleCorrKey, ctx);
-     // onlHVCorr = dynamic_cast<const LArHVScaleCorrFlat*>(*onlHVCorrHdl);
-     onlHVCorr = *onlHVCorrHdl;
-     if(!onlHVCorr) {
-         ATH_MSG_ERROR("Do not have online HV corr. conditions object, but asked to undo !!!!");
-         return StatusCode::FAILURE;
-     }
-     EventIDRange rangeIn;
-     if (!onlHVCorrHdl.range(rangeIn)) {
-       ATH_MSG_ERROR("Failed to retrieve validity range for " << onlHVCorrHdl.key());
-	 return StatusCode::FAILURE;
-       }
-     rangeW=EventIDRange::intersect(rangeW,rangeIn);
-     ATH_MSG_DEBUG("Range of online HV Scale " << rangeIn << ", intersection: " << rangeW);
-
-  } 
-
-  SG::ReadCondHandle<LArOnOffIdMapping> larCablingHdl(m_cablingKey, ctx);
-  const LArOnOffIdMapping* cabling=*larCablingHdl;
-  if(!cabling) {
-     ATH_MSG_ERROR("Could not get LArOnOffIdMapping !!");
-     return StatusCode::FAILURE;
-  }
-
-
-  std::vector<float> vScale;
-  vScale.resize(182468,(float)1.0);
-
-  ATH_MSG_DEBUG("LArHVScaleCorrCondAlg execute()"); 
-  const std::set<Identifier>& updatedCells=hvdata->getUpdatedCells();
-  if (updatedCells.size()) {
-    const HASHRANGEVEC hashranges=this->cellsIDsToPartition(updatedCells);
-    StatusCode sc=this->getScale(hashranges, vScale, hvdata, onlHVCorr, cabling);
-    if (sc.isFailure()) {
-      ATH_MSG_ERROR( " LArHVScaleCorrCondAlg::LoadCalibration error in getScale" );
-      return sc;
-    }
-  }
-  else {
-    ATH_MSG_DEBUG("No real voltage change, no update necessary");
-    return StatusCode::SUCCESS;
-  }
-
-  // and now record output object
-  std::unique_ptr<LArHVCorr> hvCorr = std::make_unique<LArHVCorr>(std::move(vScale), cabling, m_calocell_id );
-  //LArHVScaleCorrFlat * hvCorr = new LArHVScaleCorrFlat(vScale);
-  const EventIDRange crangeW(rangeW);
-  if(writeHandle.record(crangeW,hvCorr.release()).isFailure()) {
-           ATH_MSG_ERROR("Could not record LArHVCorr object with " << writeHandle.key()
-                         << " with EventRange " << crangeW << " into Conditions Store");
-           return StatusCode::FAILURE;
-  }
-
-  ATH_MSG_INFO("recorded new " << writeHandle.key() << " with range " << crangeW << " into Conditions Store");
-  
-  return StatusCode::SUCCESS;
-}
-
-
-StatusCode LArHVScaleCorrCondAlg::finalize()
-{
-  return StatusCode::SUCCESS;
-}
-
-
-// *** compute global ADC2MeV factor from subfactors *** 
-
-StatusCode LArHVScaleCorrCondAlg::getScale(const HASHRANGEVEC& hashranges, 
-					   std::vector<float> &vScale, const LArHVData *hvdata, 
-					   const ILArHVScaleCorr *onlHVCorr, const LArOnOffIdMapping* cabling) const {
-
-
-  const CaloDetDescrManager* calodetdescrmgr = nullptr;
-  ATH_CHECK( detStore()->retrieve(calodetdescrmgr) );
-
-  unsigned nChannelsUpdates=0;
-
-  HASHRANGEVEC::const_iterator rit=hashranges.begin();
-  HASHRANGEVEC::const_iterator rit_e=hashranges.end();
-  for (;rit!=rit_e;++rit) {
-    for (size_t idx=rit->first;idx<rit->second;++idx) {
-      const IdentifierHash oflHash(idx);
-      float mycorr;
-      float mynorm;
-
-      double d=.2;  // nominal gap  in cm
-      double nominal=2000.;  // nominal HV  in Volts
-      double T=88.;  // temperature  in Kelvin
-
-      bool isbarrelEM=false;
-      bool isFCAL1=false;
-
-      unsigned int subdet=99;
-      unsigned int layer=99;
-      const CaloDetDescrElement* calodde = calodetdescrmgr->get_element(oflHash);
-      if (!calodde) {
-	ATH_MSG_WARNING( "No DDE found for cell " << oflHash );
-        continue;
-      }
-      const Identifier offid=calodde->identify();
-      const float eta_raw = calodde->eta_raw();
-      const float phi_raw = calodde->phi_raw();
-
-
-      // EM calorimeter
-      if (m_larem_id->is_lar_em(offid)) {
-	// barrel
-	if (abs(m_larem_id->barrel_ec(offid))==1) {
-	  subdet=0;
-	  layer = m_larem_id->sampling(offid);
-	  // EMB
-	  if (m_larem_id->sampling(offid)>0) {
-	    d=0.209;
-	    nominal=2000.;
-	    T=88.37;
-	    isbarrelEM=true;
-	  }
-	  // EMBPS
-	  else {
-	    nominal = 2000.;
-	    T = 88.37;
-	    const int ieta=m_larem_id->eta(offid);
-	    if (ieta>=0 && ieta<16)        d = 0.196; //cm
-	    else if (ieta>=16 && ieta<32)  d = 0.193; //cm
-	    else if (ieta>=32 && ieta<48)  d = 0.2; //cm
-	    else  d = 0.190; //cm
-	  }
-	}
-	// endcap
-	else {
-	  subdet=1;
-	  layer = m_larem_id->sampling(offid);
-	  // End-Cap pre-sampler
-	  if (abs(m_larem_id->barrel_ec(offid))==2 && m_larem_id->sampling(offid)==0){
-	    T = 88.65; // temperature remainder Calorimeter
-	    nominal = -2000.;
-	    d = 0.2; 
-	  }
-	  //EMEC      
-	  else {
-	    T = 88.65;
-	    float aeta_raw = std::fabs(eta_raw);
-	    double Zsamp;
-	    if ( m_larem_id->sampling(offid)==1 && m_larem_id->region(offid)>=0 )  Zsamp = 3760.; //mm
-	    else if ( m_larem_id->sampling(offid)==2 && m_larem_id->region(offid)<=1 )  Zsamp = 3880.; //mm
-	    else if(aeta_raw< 2.) Zsamp=4200.-40.*(aeta_raw-1.5);
-	    else Zsamp = 4180. - 160.*(aeta_raw-2.);
-	    nominal = EMEC_nominal(aeta_raw);
-	    d = EMEC_gap(aeta_raw, Zsamp)*0.1; //cm
-	  }//end EMEC
-	}//end endcap
-      }//end is-em
-      // Forward Calorimeter
-      else if ( m_larfcal_id->is_lar_fcal(offid)) {
-	subdet=3;
-	layer = m_larfcal_id->module(offid);
-	T = 88.65;
-	if (m_larfcal_id->module(offid)==1){ 
-	  d =0.0269; //cm
-	  nominal = 250.;
-	  isFCAL1=true;
-	}
-	else  if (m_larfcal_id->module(offid)==2){
-	  d =0.0376;//cm
-	  nominal = 375.;
-	}
-	else { 
-	  d =0.0508;//cm
-	  nominal = 500.;
-	}
-      }
-      // Hadronic Calorimeter
-      else if ( m_larhec_id->is_lar_hec(offid)) {
-	subdet=2;
-	layer = m_larhec_id->sampling(offid);
-	T = 88.65;
-	nominal = 1800.;
-	d = 0.196;//cm
-      }
-      T = T - m_T0;
-
-      const double E_nominal = champ_e(nominal,d);
-      const std::vector<LArHVData::HV_t>& hvlist=hvdata->getHV(offid);
-
-      if (hvlist.size() == 0) {
-	mycorr=1.;
-	mynorm=1.;
-	ATH_MSG_WARNING( " HV value no found for cell " << m_larem_id->show_to_string(offid) );
-      }
-
-      else {
-	// dump values
-	bool notfound=false;
-	for (unsigned int i=0;i<hvlist.size();i++) {
-	  //           log << MSG::DEBUG << " " << hvlist[i].hv;
-	  if (hvlist[i].hv<-10000) notfound=true;
-	}
-	//        log << MSG::DEBUG );
-
-	if (notfound) {
-	  ATH_MSG_WARNING( " At least one HV value not found in database for cell " << m_larem_id->show_to_string(offid) );
-	}
-
-	mycorr=0.;
-	mynorm=0.;
-	for (unsigned int i=0;i<hvlist.size();i++) {
-// barrel accordion
-	  if (isbarrelEM) {
-	    //const double corr = this->Scale_barrel(hvlist[i].hv)*hvlist[i].weight;
-	    //mycorr += corr;
-            if(m_useCurrentEMB) mycorr += this->Scale_barrel(hvlist[i].hv-hvlist[i].current)*hvlist[i].weight;
-            else mycorr += this->Scale_barrel(hvlist[i].hv)*hvlist[i].weight;
-	  }
-//FCAL module 1
-	  else if (isFCAL1) {
-	    //const double corr = this->Scale_FCAL1(hvlist[i].hv) * hvlist[i].weight;
-	    //mycorr+=corr;
-            if(m_useCurrentFCAL1) mycorr += this->Scale_FCAL1(hvlist[i].hv-hvlist[i].current) * hvlist[i].weight;
-            else mycorr += this->Scale_FCAL1(hvlist[i].hv) * hvlist[i].weight;
-	  }
-// other subdetectors
-	  else {
-	    double E;
-            if(m_useCurrentOthers) E = champ_e(hvlist[i].hv-hvlist[i].current,d);
-            else E = champ_e(hvlist[i].hv,d);
-
-	    // dont correct if E is very close to E nominal to avoid small glitches
-	    if (std::fabs(E_nominal)>1e-3) {
-	       const double deviation = std::fabs((E-E_nominal)/E_nominal);
-	       if (deviation<1e-3) E = E_nominal;
-	    }
-
-	    const double corr = Respo(E,E_nominal,T)*hvlist[i].weight;
-	    mycorr+= corr;
-	  }    
-	  mynorm += hvlist[i].weight;
-	}
-      }
-
-
-      if (mycorr>1e-2) mycorr = mynorm/mycorr;
-      else mycorr=1.;
-
-// Add protection against correction factor > 10
-      if (mycorr>10.) {
-          ATH_MSG_DEBUG("Correction factor > 10, ignore it... for cell " <<  m_larem_id->show_to_string(offid) << " " << mycorr);
-          mycorr=1.;
-      }   
-
-      for (unsigned int ii=0;ii<m_HVfix.size();ii++) {
-	if (subdet == m_HVfix[ii].subdet && layer >= m_HVfix[ii].layer_min && layer <= m_HVfix[ii].layer_max &&
-	    eta_raw >= m_HVfix[ii].eta_min && eta_raw < m_HVfix[ii].eta_max &&
-	    phi_raw >= m_HVfix[ii].phi_min && phi_raw < m_HVfix[ii].phi_max ) {
-	  ATH_MSG_DEBUG("Overwrite correction for cell " <<  m_larem_id->show_to_string(offid) << " " << m_HVfix[ii].corr);
-	  mycorr = m_HVfix[ii].corr;
-	}
-      }
-    
-      ++nChannelsUpdates;
-      if(onlHVCorr) { // undo the online one
-	float hvonline = onlHVCorr->HVScaleCorr(cabling->createSignalChannelID(offid));
-	if (hvonline>0. && hvonline<100.) mycorr = mycorr/hvonline;
-      }
-      vScale[idx]=mycorr;
-    }// end loop over cells 
-  }//end loop over ranges'
-  ATH_MSG_DEBUG("(re)computed HV scale corrections for " << nChannelsUpdates << " channels");
-  return StatusCode::SUCCESS;  
-}
-
-float LArHVScaleCorrCondAlg::champ_e(float hv, float d) const
-{
-  float e1;
-  if (hv < -3000.){ 
-    return -1000.;
-  }
-  else
-    e1 = fabs(hv)/(d*1e3);
-  if ( e1 < 0.01 ) e1 = 0.01;
-  return e1;
-}
-
-float LArHVScaleCorrCondAlg::vdrift(float e, float tempe) const
-{	    
-  const float T = tempe;                
-  static const float P[6] = {-0.01481,-0.0075,0.141,12.4,1.627,0.317};
-  if ( e < -999.) return 0.;
-  float vd = (P[0]*T+1)*( P[2]*e*log(1+ (P[3]/e)) + P[4]*pow(e,P[5])) + P[1]*T; // vdrift formula walcowialk mm/micro_s
-  return vd;
-}
-
-float LArHVScaleCorrCondAlg::InvCharge(float e) const
-// returns 1/charge from recombination effect
-{ 
-  float q = 1.;
-  if ( e > 2.) q=(1.+0.36/e);
-  else if (e>1e-6) q =(1.04+0.25/e);
-  return q;
-}
-
-float LArHVScaleCorrCondAlg::Respo(float e, float e_nominal,float tempe) const
-{ 
-  if (e < -999.) return 1.;
-  if (e < 0.01) return 0;
-  if ( e > e_nominal ) return 1;
-  float resp = (InvCharge(e_nominal)*vdrift(e,tempe))/(InvCharge(e)*vdrift(e_nominal,tempe));
-  return resp;
-}
-
-float LArHVScaleCorrCondAlg::t_drift(float e, float e_nominal, float d, float tempe) const
-{
-  if ( e < -999.) return (d*1e4)/vdrift(e_nominal, tempe) ;
-  if (e > e_nominal ) e = e_nominal;
-  return (d*1e4)/vdrift(e, tempe); // ns
-}
-
-float LArHVScaleCorrCondAlg::EMEC_nominal(const float aeta) const
-{
-  if ( aeta<1.5 ) return 2500.;
-  else if (aeta<1.6) return 2300.;
-  else if (aeta<1.8 ) return 2100.;
-  else if (aeta < 2.0 ) return 1700.;
-  else if (aeta < 2.1 ) return 1500.;
-  else if (aeta < 2.3 ) return 1250.;
-  else if (aeta < 2.5 ) return 1000.;
-  else if (aeta < 2.8 ) return 2300.;
-  else return 1800.;
-}
-
-float LArHVScaleCorrCondAlg::EMEC_gap(const float aeta, float Zeta) const
-{
-  float EMECg;
-  if (aeta<=2.5 ) EMECg = 0.9 +1.9*(  ( Zeta - 40. )/(10*sinh(aeta)) - 60.)/140.;
-  else EMECg = 1.8 + 1.3*(  ( Zeta - 40. )/(10*sinh(aeta)) - 30.)/40.;
-  return EMECg;
-}
-
-float LArHVScaleCorrCondAlg::Scale_FCAL1(const float hv) const
-{
-  if (hv<5.0) return 0;
-  const float R0=-2.612;
-  const float alpha=2.336;
-  const float beta=0.079;
-  const float scale=R0+alpha*pow(hv,beta);
-  return scale;
-}
-  
-
-
-float LArHVScaleCorrCondAlg::Scale_barrel(const float hv) const
-{
-   const float hvref[18]={1.,50.,100.,150.,200.,300.,400.,500.,600.,700.,800.,900.,1000.,1200.,1400.,1600.,1800.,2000.};
-   const float hvmax = 1998.;
-   const float facteur[18]={0.,0.1209,0.2135,0.2829,0.3390,0.4270,0.4961,0.5556,0.6065,0.6527,0.6906,
-			    0.7290,0.7626,0.8224,0.8754,0.9190,0.9606,1.};
-
-// 0 HV, returns 0 response
-   if (hv<-999.) {
-      return 0;
-   }
-   else if (hv<hvref[0]) {
-      float resp=facteur[0];
-      return resp;
-   }
-// 2000 HV, returns response=1
-   if (hv>hvmax) {
-      float resp=facteur[17];
-      return resp;
-   }
-
-// intermediate HV, find values between which to extrapolate
-   int i1,i2;
-   i1=1;
-   for (int i=0;i<18;i++) {
-    if (hv<hvref[i]) {
-       i1=i-1;
-       break;
-    }
-   }
-   i2=i1+1;
-   float resp=0.;
-
-// if lowHV>=50 V, logarithmic extrapolation
-   if (i1>0) {
-     const float b=(log(facteur[i2])-log(facteur[i1]))/(log(hvref[i2])-log(hvref[i1]));
-     const float a=log(facteur[i2])-b*log(hvref[i2]);
-     resp = exp(a+b*log(hv));
-   } 
-// if between 0 and 50 V, scales linearly
-   else {
-     resp=facteur[0]*(hv/hvref[0]);
-   }
-   return resp;
-}
-
-
-
-
-// *** Build list of correction to hardcode by jobOptions
-StatusCode LArHVScaleCorrCondAlg::buildFixHVList() {
-
-  m_HVfix.clear();
-  std::vector<std::string>::const_iterator itrStringID=m_fixHVStrings.begin();
-  for (;itrStringID!=m_fixHVStrings.end();++itrStringID) {
-    std::string theString=*itrStringID;
-    std::stringstream is;
-    is << theString << std::endl;
-  
-    unsigned int iDetector,ilayer_min,ilayer_max;
-    float eta_min,eta_max,phi_min,phi_max,corr;
-    is >> iDetector >> ilayer_min >> ilayer_max >> eta_min >> eta_max >> phi_min >> phi_max >> corr;
-
-    HVfix_t myfix;
-    myfix.subdet = iDetector;
-    myfix.layer_min = ilayer_min;
-    myfix.layer_max = ilayer_max;
-    myfix.eta_min = eta_min;
-    myfix.eta_max = eta_max;
-    myfix.phi_min = phi_min;
-    myfix.phi_max = phi_max;
-    myfix.corr = corr;
-    m_HVfix.push_back(myfix);
-  }
-
-  ATH_MSG_INFO( "  Number of regions with overwritten HV corrections from jobOptions " << m_HVfix.size() );
-
-
-  return StatusCode::SUCCESS;
-}
-
-
-LArHVScaleCorrCondAlg::HASHRANGEVEC LArHVScaleCorrCondAlg::cellsIDsToPartition(const std::set<Identifier>& cellsIDvec) const {
-  HASHRANGEVEC ranges;
-  if (cellsIDvec.size()>=m_electrodeID->electrodeHashMax()) {
-    ranges.push_back(std::make_pair<IdentifierHash,IdentifierHash>(0,182468));
-  }
-  else {
-    std::bitset<NHVPARTITION> hasPartition[2]; 
-    std::set<Identifier>::const_iterator it=cellsIDvec.begin();
-    std::set<Identifier>::const_iterator it_e=cellsIDvec.end();
-    for (;it!=it_e;++it) {
-      const Identifier elId=*it;
-      const int zside=m_calocell_id->pos_neg(elId);
-      const int sample=m_calocell_id->calo_sample(elId);
-      switch (sample) {
-         case 1: case 2: case 3: //EMB
-	hasPartition[zside].set(EMB);
-	break;
-      case 0: // EMBPS
-	hasPartition[zside].set(EMBPS);
-	break;
-      case 5: case 6: case 7: //EMEC
-	if (m_calocell_id->is_em_endcap_outer(elId))
-	  hasPartition[zside].set(EMECOW);
-	else
-	  hasPartition[zside].set(EMECIW);
-	break;
-      case 4: //EMECPS
-	hasPartition[zside].set(EMECPS);
-	break;
-      case 8: case 9: case 10: case 11: //HEC
-	hasPartition[zside].set(HEC);
-	break;
-      case 21: case 22: case 23:
-	hasPartition[zside].set(FCAL);
-	break;
-      default: //Ignore
-	break;
-      }//end switch statement
-    }//end loop over IDs
-    for (unsigned z=0;z<2;++z) { //Loop over detector sides
-      for (unsigned i=0;i<NHVPARTITION;++i) {
-	if (hasPartition[z].test(i))  ranges.push_back(m_hashRanges[z][i]);
-      } //end loop over partitions
-    }// end loop over sides
-  }//end else not complete
-  return ranges;
-}
-
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.h b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.h
deleted file mode 100644
index f66c00129ba15e21d17cb12ea65969676285c9e3..0000000000000000000000000000000000000000
--- a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrCondAlg.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-// Rewritten from LArHVScaleCorrTool
-
-#ifndef LARRECUTILS_LARHVSCALECORRCONDALG_H
-#define LARRECUTILS_LARHVSCALECORRCONDALG_H
-
-#include "AthenaBaseComps/AthAlgorithm.h"
-
-#include "GaudiKernel/ICondSvc.h"
-
-#include "StoreGate/DataHandle.h"
-#include "StoreGate/ReadCondHandleKey.h"
-#include "StoreGate/WriteCondHandleKey.h"
-
-#include "LArIdentifier/LArOnlineID.h"
-#include "CaloIdentifier/LArID.h"
-#include "CaloDetDescr/CaloDetDescrManager.h"
-#include "LArRecConditions/LArHVData.h"
-#include "LArRecConditions/LArHVIdMapping.h"
-#include "LArCabling/LArOnOffIdMapping.h"
-
-#include "LArRawConditions/LArHVScaleCorrComplete.h"
-#include "LArRawConditions/LArTdriftComplete.h"
-#include "LArCOOLConditions/LArHVScaleCorrFlat.h"
-#include "LArRecConditions/LArHVCorr.h"
-
-class LArElectrodeID;
-
-class LArHVScaleCorrCondAlg: public AthAlgorithm
-{
- public:
-  
-  // constructor
-  LArHVScaleCorrCondAlg(const std::string& name, ISvcLocator* pSvcLocator); 
-  
-  // destructor 
-  virtual ~LArHVScaleCorrCondAlg();
-  
-  virtual StatusCode initialize() override;
-  virtual StatusCode execute() override;
-  virtual StatusCode finalize() override;
-
- private:
-
-  ServiceHandle<ICondSvc> m_condSvc;
-  const LArOnlineID*    m_lar_on_id; 	
-  const CaloCell_ID*    m_calocell_id;	
-  const LArEM_ID*       m_larem_id;	
-  const LArHEC_ID*      m_larhec_id;	
-  const LArFCAL_ID*     m_larfcal_id;	
-  const LArElectrodeID* m_electrodeID;  
-
-  SG::ReadCondHandleKey<LArOnOffIdMapping>  m_cablingKey {this,"keyCabling", "LArOnOffIdMap", "Input key for Id mapping"} ;  
-  SG::ReadCondHandleKey<LArHVData> m_hvKey {this, "keyHVdata", "LArHVData", "Input key for HV data from DCS"};
-  SG::ReadCondHandleKey<ILArHVScaleCorr> m_onlineHVScaleCorrKey{this, "keyOnlineHVCorr", "LArHVScaleCorr","Input key for HVScaleCorr from conditions database (used online)"};
-
-  SG::WriteCondHandleKey<ILArHVScaleCorr> m_outputHVScaleCorrKey{this, "keyOutputCorr", "LArHVScaleCorrRecomputed","Output key for LArHVScaleCorr"};
-
-
-  float Scale_barrel(const float hv) const;
-  float Scale_FCAL1(const float hv) const;
-  float champ_e(float hv, float d) const;
-  float vdrift(float e,float tempe) const;  
-  float InvCharge(float e) const;  
-  float Respo(float e,float e_nominal,float tempe) const;  
-  float t_drift (float e, float e_nominal,float d, float tempe) const;  
-  float EMEC_nominal(const float eta_r) const;    
-  float EMEC_gap(const float eta_r, float Zeta) const;
-  StatusCode buildFixHVList();
-  float m_T0;
-
-  /*##########################################################################
-    definitions of new functions and variables                       units
-    ---------------------------------------------------------------------
-    d              gap distancia between cells in calorimeters       cm
-    nominal        subdetector nominal voltage                       volt
-    E              electric field in the cell                        kvolt/cm
-    E_nominal      nominal electric field in the cell                kvolt/cm
-    T              temperature of cryostat                           Kelvin
-    Zsamp          Z coordinate for samplings in EMEC                mm
-    champ_e        computes electric field                           kvolt/cm
-    vdrift         computes drift velocity                           mm/micro_s
-    Charge         computes recombination charge                     Coulomb
-    Respo          computes the correction factors to HV!=nominal    -
-    t_drift        computes drift times                              ns
-    EMEC_nominal   finds nominal voltages in EMEC                    volt
-    EMEC_gap       finds gap distances in EMEC                       mm
-    ########################################################################## 
-  */
-
-
-  bool m_undoOnlineHVCorr;
-  bool m_useCurrentEMB;
-  bool m_useCurrentFCAL1;
-  bool m_useCurrentOthers;
-
-  struct HVfix_t {
-    unsigned int subdet;   // 0-1-2-3 for EMB-EMEC-HEC-FCAL
-    unsigned int layer_min;
-    unsigned int layer_max;
-    float eta_min;
-    float eta_max;
-    float phi_min;
-    float phi_max;
-    float corr;
-  };
-
-  std::vector<HVfix_t> m_HVfix;    
-  std::vector<std::string> m_fixHVStrings;
-
-  enum HVPARTITION {FCAL=0,HEC,EMECIW,EMECOW,EMECPS,EMB,EMBPS,NHVPARTITION}; //x2 for the side  
-  typedef std::vector<std::pair<IdentifierHash,IdentifierHash> > HASHRANGEVEC;
-  HASHRANGEVEC m_hashRanges[2];//x2 for the side
-  HASHRANGEVEC m_completeRange;
-  HASHRANGEVEC cellsIDsToPartition(const std::set<Identifier>& cellsIDvec) const;
-  StatusCode getScale(const HASHRANGEVEC& hashranges, 
-		      std::vector<float> &vScale, const LArHVData* hvdata, const ILArHVScaleCorr *onlHVCorr, 
-		      const LArOnOffIdMapping* cabling) const;
-
-};
-
-#endif
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.cxx b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b3190fd38b0f0cd4700d309e2288b40e37f96c78
--- /dev/null
+++ b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.cxx
@@ -0,0 +1,344 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "LArHVScaleCorrTool.h"
+#include "CaloDetDescr/CaloDetDescrElement.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+
+#include <cmath>
+
+using CLHEP::microsecond;
+using CLHEP::second;
+
+LArHVScaleCorrTool::LArHVScaleCorrTool(const CaloCell_ID* calocell_id, MsgStream& msg, 
+				       const std::vector<std::string>& fixHVStrings) :
+  m_larem_id(calocell_id->em_idHelper()),
+  m_larhec_id(calocell_id->hec_idHelper()),
+  m_larfcal_id(calocell_id->fcal_idHelper()),
+  m_T0(90.371),
+  m_msg(msg) { 
+
+  buildFixHVList(fixHVStrings);
+  }
+
+  
+float LArHVScaleCorrTool::getHVScale(const CaloDetDescrElement* calodde,  const voltageCell_t& hvlist) const {
+
+  double d=.2;  // nominal gap  in cm
+  double nominal=2000.;  // nominal HV  in Volts
+  double T=88.;  // temperature  in Kelvin
+  
+  bool isbarrelEM=false;
+  bool isFCAL1=false;
+  
+  unsigned int subdet=99;
+  unsigned int layer=99;
+
+  const Identifier offid=calodde->identify();
+  const float eta_raw = calodde->eta_raw();
+  const float phi_raw = calodde->phi_raw();
+
+
+  // EM calorimeter
+  if (m_larem_id->is_lar_em(offid)) {
+    // barrel
+    if (abs(m_larem_id->barrel_ec(offid))==1) {
+      subdet=0;
+      layer = m_larem_id->sampling(offid);
+      // EMB
+      if (m_larem_id->sampling(offid)>0) {
+	d=0.209;
+	nominal=2000.;
+	T=88.37;
+	isbarrelEM=true;
+      }
+      // EMBPS
+      else {
+	nominal = 2000.;
+	T = 88.37;
+	const int ieta=m_larem_id->eta(offid);
+	if (ieta>=0 && ieta<16)        d = 0.196; //cm
+	else if (ieta>=16 && ieta<32)  d = 0.193; //cm
+	else if (ieta>=32 && ieta<48)  d = 0.2; //cm
+	else  d = 0.190; //cm
+      }
+    }
+    // endcap
+    else {
+      subdet=1;
+      layer = m_larem_id->sampling(offid);
+      // End-Cap pre-sampler
+      if (abs(m_larem_id->barrel_ec(offid))==2 && m_larem_id->sampling(offid)==0){
+	T = 88.65; // temperature remainder Calorimeter
+	nominal = -2000.;
+	d = 0.2; 
+      }
+      //EMEC      
+      else {
+	T = 88.65;
+	float aeta_raw = std::fabs(eta_raw);
+	double Zsamp;
+	if ( m_larem_id->sampling(offid)==1 && m_larem_id->region(offid)>=0 )  Zsamp = 3760.; //mm
+	else if ( m_larem_id->sampling(offid)==2 && m_larem_id->region(offid)<=1 )  Zsamp = 3880.; //mm
+	else if(aeta_raw< 2.) Zsamp=4200.-40.*(aeta_raw-1.5);
+	else Zsamp = 4180. - 160.*(aeta_raw-2.);
+	nominal = EMEC_nominal(aeta_raw);
+	d = EMEC_gap(aeta_raw, Zsamp)*0.1; //cm
+      }//end EMEC
+    }//end endcap
+  }//end is-em
+  // Forward Calorimeter
+  else if ( m_larfcal_id->is_lar_fcal(offid)) {
+    subdet=3;
+    layer = m_larfcal_id->module(offid);
+    T = 88.65;
+    if (m_larfcal_id->module(offid)==1){ 
+      d =0.0269; //cm
+      nominal = 250.;
+      isFCAL1=true;
+    }
+    else  if (m_larfcal_id->module(offid)==2){
+      d =0.0376;//cm
+      nominal = 375.;
+    }
+    else { 
+      d =0.0508;//cm
+      nominal = 500.;
+    }
+  }
+  // Hadronic Calorimeter
+  else if ( m_larhec_id->is_lar_hec(offid)) {
+    subdet=2;
+    layer = m_larhec_id->sampling(offid);
+    T = 88.65;
+    nominal = 1800.;
+    d = 0.196;//cm
+  }
+  T = T - m_T0;
+
+  const double E_nominal = champ_e(nominal,d);
+  
+  // dump values
+  bool notfound=false;
+  for (unsigned int i=0;i<hvlist.size();i++) {
+    if (hvlist[i].hv<-10000) notfound=true;
+  }
+
+  if (notfound) {
+    m_msg << MSG::WARNING << " At least one HV value not found in database for cell " << m_larem_id->show_to_string(offid) << endmsg;
+  }
+
+  double mycorr=0.;
+  double mynorm=0.;
+  for (unsigned int i=0;i<hvlist.size();i++) {
+    double E = champ_e(hvlist[i].hv,d);
+    
+    // dont correct if E is very close to E nominal to avoid small glitches
+    if (std::fabs(E_nominal)>1e-3) {
+      const double deviation = std::fabs((E-E_nominal)/E_nominal);
+      if (deviation<1e-3) E = E_nominal;
+    }
+
+    // barrel accordion
+    if (isbarrelEM) {
+      const double corr = this->Scale_barrel(hvlist[i].hv)*hvlist[i].weight;
+      mycorr += corr;
+    }
+    //FCAL module 1
+    else if (isFCAL1) {
+      const double corr = this->Scale_FCAL1(hvlist[i].hv) * hvlist[i].weight;
+      mycorr+=corr;
+    }
+    // other subdetectors
+    else {
+      const double corr = Respo(E,E_nominal,T)*hvlist[i].weight;
+      mycorr+= corr;
+    }
+    mynorm += hvlist[i].weight;
+  }//end loop over hvlist
+  
+
+  if (mycorr>1e-2) mycorr = mynorm/mycorr;
+  else mycorr=1.;
+  
+  // Add protection against correction factor > 10
+  if (mycorr>10.) {
+    m_msg << MSG::DEBUG << "Correction factor > 10, ignore it... for cell " <<  m_larem_id->show_to_string(offid) << " " << mycorr << endmsg;;
+    mycorr=1.;
+  }   
+
+  //Overwrite with hardcoded jobOption numbers if requested
+  for (unsigned int ii=0;ii<m_HVfix.size();ii++) {
+    if (subdet == m_HVfix[ii].subdet && layer >= m_HVfix[ii].layer_min && layer <= m_HVfix[ii].layer_max &&
+	eta_raw >= m_HVfix[ii].eta_min && eta_raw < m_HVfix[ii].eta_max &&
+	phi_raw >= m_HVfix[ii].phi_min && phi_raw < m_HVfix[ii].phi_max ) {
+      m_msg << MSG::DEBUG << "Overwrite correction for cell " <<  m_larem_id->show_to_string(offid) << " " << m_HVfix[ii].corr << endmsg;;
+      mycorr = m_HVfix[ii].corr;
+    }
+  }
+    
+  return mycorr;
+}
+
+float LArHVScaleCorrTool::champ_e(float hv, float d) const
+{
+  float e1;
+  if (hv < -3000.){ 
+    return -1000.;
+  }
+  else
+    e1 = fabs(hv)/(d*1e3);
+  if ( e1 < 0.01 ) e1 = 0.01;
+  return e1;
+}
+
+float LArHVScaleCorrTool::vdrift(float e, float tempe) const
+{	    
+  const float T = tempe;                
+  static const float P[6] = {-0.01481,-0.0075,0.141,12.4,1.627,0.317};
+  if ( e < -999.) return 0.;
+  float vd = (P[0]*T+1)*( P[2]*e*log(1+ (P[3]/e)) + P[4]*pow(e,P[5])) + P[1]*T; // vdrift formula walcowialk mm/micro_s
+  return vd;
+}
+
+float LArHVScaleCorrTool::InvCharge(float e) const
+// returns 1/charge from recombination effect
+{ 
+  float q = 1.;
+  if ( e > 2.) q=(1.+0.36/e);
+  else if (e>1e-6) q =(1.04+0.25/e);
+  return q;
+}
+
+float LArHVScaleCorrTool::Respo(float e, float e_nominal,float tempe) const
+{ 
+  if (e < -999.) return 1.;
+  if (e < 0.01) return 0;
+  if ( e > e_nominal ) return 1;
+  float resp = (InvCharge(e_nominal)*vdrift(e,tempe))/(InvCharge(e)*vdrift(e_nominal,tempe));
+  return resp;
+}
+
+float LArHVScaleCorrTool::t_drift(float e, float e_nominal, float d, float tempe) const
+{
+  if ( e < -999.) return (d*1e4)/vdrift(e_nominal, tempe) ;
+  if (e > e_nominal ) e = e_nominal;
+  return (d*1e4)/vdrift(e, tempe); // ns
+}
+
+float LArHVScaleCorrTool::EMEC_nominal(const float aeta) const
+{
+  if ( aeta<1.5 ) return 2500.;
+  else if (aeta<1.6) return 2300.;
+  else if (aeta<1.8 ) return 2100.;
+  else if (aeta < 2.0 ) return 1700.;
+  else if (aeta < 2.1 ) return 1500.;
+  else if (aeta < 2.3 ) return 1250.;
+  else if (aeta < 2.5 ) return 1000.;
+  else if (aeta < 2.8 ) return 2300.;
+  else return 1800.;
+}
+
+float LArHVScaleCorrTool::EMEC_gap(const float aeta, float Zeta) const
+{
+  float EMECg;
+  if (aeta<=2.5 ) EMECg = 0.9 +1.9*(  ( Zeta - 40. )/(10*sinh(aeta)) - 60.)/140.;
+  else EMECg = 1.8 + 1.3*(  ( Zeta - 40. )/(10*sinh(aeta)) - 30.)/40.;
+  return EMECg;
+}
+
+float LArHVScaleCorrTool::Scale_FCAL1(const float hv) const
+{
+  if (hv<5.0) return 0;
+  const float R0=-2.612;
+  const float alpha=2.336;
+  const float beta=0.079;
+  const float scale=R0+alpha*pow(hv,beta);
+  return scale;
+}
+  
+
+
+float LArHVScaleCorrTool::Scale_barrel(const float hv) const
+{
+   const float hvref[18]={1.,50.,100.,150.,200.,300.,400.,500.,600.,700.,800.,900.,1000.,1200.,1400.,1600.,1800.,2000.};
+   const float hvmax = 1998.;
+   const float facteur[18]={0.,0.1209,0.2135,0.2829,0.3390,0.4270,0.4961,0.5556,0.6065,0.6527,0.6906,
+			    0.7290,0.7626,0.8224,0.8754,0.9190,0.9606,1.};
+
+// 0 HV, returns 0 response
+   if (hv<-999.) {
+      return 0;
+   }
+   else if (hv<hvref[0]) {
+      float resp=facteur[0];
+      return resp;
+   }
+// 2000 HV, returns response=1
+   if (hv>hvmax) {
+      float resp=facteur[17];
+      return resp;
+   }
+
+// intermediate HV, find values between which to extrapolate
+   int i1,i2;
+   i1=1;
+   for (int i=0;i<18;i++) {
+    if (hv<hvref[i]) {
+       i1=i-1;
+       break;
+    }
+   }
+   i2=i1+1;
+   float resp=0.;
+
+// if lowHV>=50 V, logarithmic extrapolation
+   if (i1>0) {
+     const float b=(log(facteur[i2])-log(facteur[i1]))/(log(hvref[i2])-log(hvref[i1]));
+     const float a=log(facteur[i2])-b*log(hvref[i2]);
+     resp = exp(a+b*log(hv));
+   } 
+// if between 0 and 50 V, scales linearly
+   else {
+     resp=facteur[0]*(hv/hvref[0]);
+   }
+   //std::cout << " hv,i1,i2,resp " << hv << " " << i1 << " " << i2 << " " << resp << std::endl;
+   return resp;
+}
+
+
+// *** Build list of correction to hardcode by jobOptions
+void LArHVScaleCorrTool::buildFixHVList(const std::vector<std::string>& fixHVStrings) {
+
+  m_HVfix.clear();
+  std::vector<std::string>::const_iterator itrStringID=fixHVStrings.begin();
+  for (;itrStringID!=fixHVStrings.end();++itrStringID) {
+    std::string theString=*itrStringID;
+    std::stringstream is;
+    is << theString << std::endl;
+  
+    unsigned int iDetector,ilayer_min,ilayer_max;
+    float eta_min,eta_max,phi_min,phi_max,corr;
+    is >> iDetector >> ilayer_min >> ilayer_max >> eta_min >> eta_max >> phi_min >> phi_max >> corr;
+
+    HVfix_t myfix;
+    myfix.subdet = iDetector;
+    myfix.layer_min = ilayer_min;
+    myfix.layer_max = ilayer_max;
+    myfix.eta_min = eta_min;
+    myfix.eta_max = eta_max;
+    myfix.phi_min = phi_min;
+    myfix.phi_max = phi_max;
+    myfix.corr = corr;
+    m_HVfix.push_back(myfix);
+  }
+
+  m_msg << MSG::INFO << "  Number of regions with overwritten HV corrections from jobOptions " << m_HVfix.size() << endmsg;
+
+  return;
+}
+
+
+
diff --git a/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.h b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..80b5cf718ca2f7bdf8abb44a91bc76fbbffa1861
--- /dev/null
+++ b/LArCalorimeter/LArRecUtils/src/LArHVScaleCorrTool.h
@@ -0,0 +1,98 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+//Dear emacs, this is -*-c++-*-
+
+#ifndef LARRECUTILS_LARHVSCALECORRTOOL_H
+#define LARRECUTILS_LARHVSCALECORRTOOL_H
+
+#include <string>
+#include <vector>
+#include "GaudiKernel/MsgStream.h"
+
+class CaloCell_ID;
+class LArEM_ID;
+class LArHEC_ID;
+class LArFCAL_ID;
+class CaloDetDescrElement; 
+
+class LArHVScaleCorrTool {
+public:
+
+  //Internal representation of voltage & current per cell: 
+  struct HV_t {
+    HV_t(float ihv, float iweight) : hv(ihv), weight(iweight) {};
+    float hv=0.0; //voltage, potentially current*R corrected
+    float weight=0.0;
+  };
+
+  typedef std::vector<HV_t> voltageCell_t;
+
+
+  LArHVScaleCorrTool(const CaloCell_ID* caloCellID, MsgStream& msg, const std::vector<std::string>& fixHVStrings);
+  
+  LArHVScaleCorrTool() = delete;
+
+   // destructor 
+  virtual ~LArHVScaleCorrTool() = default;
+  
+  float getHVScale(const CaloDetDescrElement* calodde,  const voltageCell_t& hvlist) const;
+
+ private:
+
+  const LArEM_ID*       m_larem_id;	
+  const LArHEC_ID*      m_larhec_id;	
+  const LArFCAL_ID*     m_larfcal_id;	
+  const float           m_T0;
+  MsgStream&            m_msg;
+
+
+  float Scale_barrel(const float hv) const;
+  float Scale_FCAL1(const float hv) const;
+  float champ_e(float hv, float d) const;
+  float vdrift(float e,float tempe) const;  
+  float InvCharge(float e) const;  
+  float Respo(float e,float e_nominal,float tempe) const;  
+  float t_drift (float e, float e_nominal,float d, float tempe) const;  
+  float EMEC_nominal(const float eta_r) const;    
+  float EMEC_gap(const float eta_r, float Zeta) const;
+  void buildFixHVList(const std::vector<std::string>& fixHVStrings);
+
+
+
+  /*##########################################################################
+    definitions of new functions and variables                       units
+    ---------------------------------------------------------------------
+    d              gap distancia between cells in calorimeters       cm
+    nominal        subdetector nominal voltage                       volt
+    E              electric field in the cell                        kvolt/cm
+    E_nominal      nominal electric field in the cell                kvolt/cm
+    T              temperature of cryostat                           Kelvin
+    Zsamp          Z coordinate for samplings in EMEC                mm
+    champ_e        computes electric field                           kvolt/cm
+    vdrift         computes drift velocity                           mm/micro_s
+    Charge         computes recombination charge                     Coulomb
+    Respo          computes the correction factors to HV!=nominal    -
+    t_drift        computes drift times                              ns
+    EMEC_nominal   finds nominal voltages in EMEC                    volt
+    EMEC_gap       finds gap distances in EMEC                       mm
+    ########################################################################## 
+  */
+
+  struct HVfix_t {
+    unsigned int subdet;   // 0-1-2-3 for EMB-EMEC-HEC-FCAL
+    unsigned int layer_min;
+    unsigned int layer_max;
+    float eta_min;
+    float eta_max;
+    float phi_min;
+    float phi_max;
+    float corr;
+  };
+
+  std::vector<HVfix_t> m_HVfix;    
+
+};
+
+#endif
diff --git a/LArCalorimeter/LArRecUtils/src/components/LArRecUtils_entries.cxx b/LArCalorimeter/LArRecUtils/src/components/LArRecUtils_entries.cxx
index 7a4b5c10ff546234a5e14fa4a039617da9a998ae..4b267f944a45d4066f8fb42e7e55df46c4e680fc 100644
--- a/LArCalorimeter/LArRecUtils/src/components/LArRecUtils_entries.cxx
+++ b/LArCalorimeter/LArRecUtils/src/components/LArRecUtils_entries.cxx
@@ -23,7 +23,6 @@
 #include "../LArHVPathologyDbCondAlg.h"
 #include "../LArHVIdMappingAlg.h"
 #include "../LArHVCondAlg.h"
-#include "../LArHVScaleCorrCondAlg.h"
 #include "../LArAutoCorrNoiseCondAlg.h"
 #include "../LArFEBConfigCondAlg.h"
 
@@ -82,6 +81,5 @@ DECLARE_COMPONENT( LArHVPathologyDbCondAlg )
 DECLARE_COMPONENT( LArHVIdMappingAlg )
 DECLARE_COMPONENT( LArOFCCondAlg )
 DECLARE_COMPONENT( LArHVCondAlg )
-DECLARE_COMPONENT( LArHVScaleCorrCondAlg )
 DECLARE_COMPONENT( LArAutoCorrNoiseCondAlg )
 DECLARE_COMPONENT( LArFEBConfigCondAlg )