From 3474d89774700a9fb638aa48d4070e43a749ec1e Mon Sep 17 00:00:00 2001
From: scott snyder <snyder@bnl.gov>
Date: Thu, 29 Oct 2020 23:40:38 -0400
Subject: [PATCH] LArByteStream: thread-safety fixes

Working towards getting this package to pass the thread-safety checker.

Remove static members from LArRodEncoder; instead, pass in the helper objects
to its ctor.  Change it to use conditions data rather than then old
legacy cabling service.
---
 .../LArRawDataContByteStreamTool.h            |  18 +-
 .../LArByteStream/LArRodEncoder.h             |  18 +-
 .../python/LArByteStreamConfig.py             |   7 +
 .../src/LArRawDataContByteStreamTool.cxx      | 171 +++++++++++++++---
 .../LArByteStream/src/LArRodEncoder.cxx       |  90 +++------
 5 files changed, 198 insertions(+), 106 deletions(-)

diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
index e8a6bc1643c..4a417c9e83e 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
@@ -19,6 +19,8 @@
 //#include "GaudiKernel/ToolHandle.h"
 #include "LArByteStream/Hid2RESrcID.h"
 #include "LArByteStream/RodRobIdMap.h"
+#include "LArCabling/LArOnOffIdMapping.h"
+#include "LArRecConditions/LArFebRodMapping.h"
 #include "ByteStreamCnvSvcBase/FullEventAssembler.h" 
 #include "ByteStreamData/RawEvent.h" 
 #include "LArByteStream/LArRodDecoder.h"
@@ -26,6 +28,7 @@
 #include "CaloIdentifier/CaloGain.h"
 #include "CaloConditions/CaloNoise.h"
 #include "StoreGate/ReadCondHandleKey.h"
+#include "CxxUtils/CachedUniquePtr.h"
 
 #include "LArRawEvent/LArFebHeaderContainer.h"
 // Map of ROBs need this
@@ -115,6 +118,10 @@ private:
   /** Prepare ROB index before conversion */
   StatusCode prepareRobIndex (const RawEvent* event, RobIndex_t& robIndex) const;
  
+
+  /** Construct a RodBlockStructure instance of the proper concrete type. */
+  std::unique_ptr<LArRodBlockStructure> makeRodBlockStructure() const;
+
   //StatusCode prepareWriting();
   /** 
    * @brief Check that all elements in a container have the same gain
@@ -124,8 +131,9 @@ private:
   template <class COLLECTION >
     bool checkGainConsistency(const COLLECTION* coll) const;
  
-  Hid2RESrcID m_hid2re;       //!< Contains the mapping from channel to ROD
+  CxxUtils::CachedUniquePtr<Hid2RESrcID> m_hid2re;       //!< Contains the mapping from channel to ROD (writing only)
   LArRodDecoder *m_decoder;   //!< Pointer to RodDecoder class
+  const Hid2RESrcID& getHid2RESrcID (const LArFebRodMapping& rodMapping) const;
 
   /** Pointer to @c LArRodBlockStructure base class. 
       Which concrete implementation is used depends on the value of 
@@ -155,8 +163,16 @@ private:
   // Name of Digit container to retrieve
   std::string m_DigitContName;
 
+  const LArOnlineID*    m_onlineHelper = nullptr;
+
   SG::ReadCondHandleKey<CaloNoise> m_caloNoiseKey
   { this, "CaloNoiseKey", "totalNoise", "" };
+
+  SG::ReadCondHandleKey<LArOnOffIdMapping> m_onOffIdMappingKey
+  { this, "OnOffIdMappingKey", "LArOnOffIdMap", "LArOnOffIdMap" };
+
+  SG::ReadCondHandleKey<LArFebRodMapping> m_febRodMappingKey
+  { this, "FebRodMappingKey", "LArFebRodMap", "LArFebRodMap" };
 };
 
 
diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodEncoder.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodEncoder.h
index b22035d14fe..a7602151477 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodEncoder.h
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodEncoder.h
@@ -41,7 +41,7 @@
 #include "LArRawEvent/LArCalibDigit.h"
 #include "LArRawEvent/LArCalibDigitContainer.h"
 
-#include "LArCabling/LArCablingLegacyService.h"
+#include "LArCabling/LArOnOffIdMapping.h"
 #include "LArByteStream/LArRodBlockStructure.h"
 //#include "LArByteStream/LArRodBlockStructure_0.h"
 //#include "LArByteStream/LArRodBlockStructure_1.h"
@@ -56,7 +56,10 @@ class LArRodEncoder
 public: 
 
   // constructor 
-  LArRodEncoder(); 
+  LArRodEncoder (const LArOnlineID& onlineHelper,
+                 const CaloDetDescrManager& calodd,
+                 const LArOnOffIdMapping& onOffIdMapping,
+                 LArRodBlockStructure* BlStruct); 
   // destructor 
   ~LArRodEncoder(); 
 
@@ -79,7 +82,6 @@ public:
 //  void fillROD(std::vector<uint32_t>& v, MsgStream& logstr) ; 
   void fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const CaloNoise& noise, double nsigma) ;
 
-  static void setRodBlockStructure(LArRodBlockStructure* BlStructPtr);
 
 private:
   /*
@@ -110,11 +112,11 @@ private:
   //std::vector<FebData> m_vFEB;
   std::map<uint32_t,FebData_t> m_mFEB;
 
-  //Static members;
-  static LArRodBlockStructure* m_BlStruct;
-  static LArCablingLegacyService*    m_cablingSvc; 
-  static const CaloDetDescrManager* m_CaloDetDescrManager;
-  static const LArOnlineID*    m_onlineHelper; 
+  const LArOnlineID&    m_onlineHelper; 
+  const CaloDetDescrManager& m_CaloDetDescrManager;
+  const LArOnOffIdMapping&   m_onOffIdMapping;
+  LArRodBlockStructure* m_BlStruct;
+
   /*
  public:
   static int m_digitcounter; //for debug purpose only
diff --git a/LArCalorimeter/LArCnv/LArByteStream/python/LArByteStreamConfig.py b/LArCalorimeter/LArCnv/LArByteStream/python/LArByteStreamConfig.py
index 6ea16366764..cad5f10f176 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/python/LArByteStreamConfig.py
+++ b/LArCalorimeter/LArCnv/LArByteStream/python/LArByteStreamConfig.py
@@ -12,11 +12,18 @@ def LArRawDataContByteStreamToolConfig (name="LArRawDataContByteStreamTool",
       tool = LArRawDataContByteStreamTool (name, **kwargs)
       if InitializeForWriting:
          from CaloTools.CaloNoiseCondAlg import CaloNoiseCondAlg
+         from LArCabling.LArCablingAccess import LArOnOffIdMapping, LArFebRodMapping
          noisealg = CaloNoiseCondAlg ('totalNoise')
+         LArOnOffIdMapping()
+         LArFebRodMapping()
          if stream:
             key = str(noisealg.OutputKey)
             if key.find ('+') < 0:
                key = 'ConditionStore+' + key
             stream.ExtraInputs += [('CaloNoise', key)]
+
+            stream.ExtraInputs += [('LArOnOffIdMapping', 'ConditionStore+LArOnOffIdMap')]
+
+            stream.ExtraInputs += [('LArFebRodMapping', 'ConditionStore+LArFebRodMap')]
       tool.InitializeForWriting = InitializeForWriting
       return tool
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawDataContByteStreamTool.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawDataContByteStreamTool.cxx
index 17cbb683866..024fbb38ec2 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawDataContByteStreamTool.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawDataContByteStreamTool.cxx
@@ -11,6 +11,8 @@
 #include "LArRawEvent/LArRawChannelContainer.h"
 #include "LArRawEvent/LArDigitContainer.h"
 #include "LArRawEvent/LArCalibDigitContainer.h"
+#include "LArRecConditions/LArCalibLineMapping.h"
+#include "LArCabling/LArOnOffIdMapping.h"
 
 #include "LArByteStream/LArRodBlockStructure.h"
 //#include "LArByteStream/LArRodBlockStructure_0.h"
@@ -64,8 +66,6 @@ LArRawDataContByteStreamTool::initialize()
   ATH_CHECK( toolSvc()->retrieveTool("LArRodDecoder",m_decoder) );
 
   if (m_initializeForWriting) {
-   ATH_CHECK( m_hid2re.initialize() );
-
    //Set LArRodBlockStructure according to jobOpts.
    switch(m_DSPRunMode)
      {case 0:  //Obsolete mode 
@@ -103,16 +103,17 @@ LArRawDataContByteStreamTool::initialize()
        break;
      }
 
-   // Set chosen RodBlockType
-   LArRodEncoder::setRodBlockStructure(m_RodBlockStructure);
-   ATH_MSG_INFO ( "Initialization done for reading and writing" );
+   ATH_CHECK( detStore()->retrieve (m_onlineHelper, "LArOnlineID") );
 
+   ATH_MSG_INFO ( "Initialization done for reading and writing" );
  }
   else {
     ATH_MSG_INFO ( "Initialization done for reading only" );
   }
 
   ATH_CHECK( m_caloNoiseKey.initialize (m_initializeForWriting) );
+  ATH_CHECK( m_onOffIdMappingKey.initialize (m_initializeForWriting) );
+  ATH_CHECK( m_febRodMappingKey.initialize (m_initializeForWriting) );
 
   return StatusCode::SUCCESS;  
 }
@@ -141,7 +142,10 @@ LArRawDataContByteStreamTool::WriteLArDigits(const LArDigitContainer* digitCont,
    ATH_MSG_ERROR ( "Null pointer passed to WriteLArDigit routine!" );
    return StatusCode::FAILURE;
  }
- if (!m_RodBlockStructure->canSetRawData() && !m_RodBlockStructure->canSetRawDataFixed()) {
+
+ std::unique_ptr<LArRodBlockStructure> blstruct = makeRodBlockStructure();
+
+ if (!blstruct->canSetRawData() && !blstruct->canSetRawDataFixed()) {
    ATH_MSG_DEBUG ( "This instance of LArRodBlockStructure can't hold LArDigits!" );
    return StatusCode::FAILURE;
  }
@@ -154,13 +158,28 @@ LArRawDataContByteStreamTool::WriteLArDigits(const LArDigitContainer* digitCont,
  LArDigitContainer::const_iterator it_b=digitCont->begin();
  LArDigitContainer::const_iterator it_e=digitCont->end();
  if (it_b==it_e) {
-   ATH_MSG_WARNING ( "Attempt to persitify a empty LArDigitContainer to ByteStream" );
+   ATH_MSG_WARNING ( "Attempt to persistify a empty LArDigitContainer to ByteStream" );
    return StatusCode::SUCCESS;
  }
 
+ const CaloDetDescrManager* calodd = nullptr;
+ ATH_CHECK( detStore()->retrieve (calodd, "CaloMgr") );
+ const EventContext& ctx = Gaudi::Hive::currentContext();
+ SG::ReadCondHandle<LArOnOffIdMapping> onOffMapping (m_onOffIdMappingKey, ctx);
+ SG::ReadCondHandle<LArFebRodMapping> febRodMapping (m_febRodMappingKey, ctx);
+ const Hid2RESrcID& hid2re = getHid2RESrcID (**febRodMapping);
+
  std::map<uint32_t, LArRodEncoder> mapEncoder; 
+
+ auto getEncoder = [&] (uint32_t reid) -> LArRodEncoder&
+                   { return mapEncoder.try_emplace (reid,
+                                                    *m_onlineHelper,
+                                                    *calodd,
+                                                    **onOffMapping,
+                                                    blstruct.get()).first->second; };
+
  unsigned n=0;
- if (m_RodBlockStructure->canSetRawDataFixed() && checkGainConsistency(digitCont))
+ if (blstruct->canSetRawDataFixed() && checkGainConsistency(digitCont))
    {//Set fixed gain raw data
      int fixgain=(*it_b)->gain();
      ATH_MSG_DEBUG(" number of Digits in LArDigitContainer for gain " << fixgain << ": " 
@@ -169,29 +188,29 @@ LArRawDataContByteStreamTool::WriteLArDigits(const LArDigitContainer* digitCont,
      for(; it_b!=it_e; ++it_b){
        const LArDigit* digit = *it_b; 
        HWIdentifier  chid = digit->hardwareID() ; 
-       uint32_t reid      = m_hid2re.getRodID( chid ); 
-       mapEncoder[reid].add(digit, fixgain);
+       uint32_t reid      = hid2re.getRodID( **febRodMapping, chid );
+       getEncoder(reid).add (digit, fixgain);
        n++;
      }  
      ATH_MSG_VERBOSE(" number of channels in the LArDigitContainer for gain " 
                      << fixgain << ": "<<n );
    } // end if
  else 
-   if (m_RodBlockStructure->canSetRawData()) { //Set free gain raw data
+   if (blstruct->canSetRawData()) { //Set free gain raw data
      ATH_MSG_DEBUG(" number of channels in LArDigit container: "<< digitCont->size() );
 
       // Sorting Channels by ROD
       for(; it_b!=it_e; ++it_b){
 	const LArDigit* digit = *it_b; 
 	HWIdentifier  chid = digit->hardwareID() ; 
-	uint32_t reid      = m_hid2re.getRodID( chid ); 
-	mapEncoder[reid].add(digit);
+	uint32_t reid      = hid2re.getRodID( **febRodMapping, chid ); 
+	getEncoder(reid).add (digit);
 	n++;
       }  
       ATH_MSG_VERBOSE(" number of channels added to framgent: "<<n );
      }//  end else-if(can set Raw data)
 
- SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey);
+ SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey, ctx);
 
  // Now loop over map and fill all ROD Data Blocks
  std::map<uint32_t,LArRodEncoder>::iterator it  =mapEncoder.begin(); 
@@ -224,7 +243,10 @@ LArRawDataContByteStreamTool::WriteLArCalibDigits(const LArCalibDigitContainer*
    ATH_MSG_DEBUG ( "Null pointer passed to WriteLArCalibDigit routine!" );
    return StatusCode::FAILURE;
  }
- if (!m_RodBlockStructure->canSetCalibration()|| !m_RodBlockStructure->canSetRawDataFixed()) {
+
+ std::unique_ptr<LArRodBlockStructure> blstruct = makeRodBlockStructure();
+
+ if (!blstruct->canSetCalibration()|| !blstruct->canSetRawDataFixed()) {
    ATH_MSG_DEBUG ( "This instance of LArRodBlockStructure can't hold LArCalibDigits!" );
    return StatusCode::FAILURE;
  }
@@ -245,7 +267,22 @@ LArRawDataContByteStreamTool::WriteLArCalibDigits(const LArCalibDigitContainer*
    return StatusCode::FAILURE;
  }
 
+ const CaloDetDescrManager* calodd = nullptr;
+ ATH_CHECK( detStore()->retrieve (calodd, "CaloMgr") );
+ const EventContext& ctx = Gaudi::Hive::currentContext();
+ SG::ReadCondHandle<LArOnOffIdMapping> onOffMapping (m_onOffIdMappingKey, ctx);
+ SG::ReadCondHandle<LArFebRodMapping> febRodMapping (m_febRodMappingKey, ctx);
+ const Hid2RESrcID& hid2re = getHid2RESrcID (**febRodMapping);
+
  std::map<uint32_t, LArRodEncoder> mapEncoder; 
+
+ auto getEncoder = [&] (uint32_t reid) -> LArRodEncoder&
+                   { return mapEncoder.try_emplace (reid,
+                                                    *m_onlineHelper,
+                                                    *calodd,
+                                                    **onOffMapping,
+                                                    blstruct.get()).first->second; };
+
  unsigned n=0;
  int fixgain=(*it_b)->gain();
  
@@ -253,15 +290,15 @@ LArRawDataContByteStreamTool::WriteLArCalibDigits(const LArCalibDigitContainer*
  for(; it_b!=it_e; ++it_b){
    const LArCalibDigit* digit = *it_b; 
    HWIdentifier  chid = digit->hardwareID() ; 
-   uint32_t reid      = m_hid2re.getRodID( chid ); 
-   mapEncoder[reid].add(digit, fixgain);
+   uint32_t reid      = hid2re.getRodID( **febRodMapping, chid );
+   getEncoder(reid).add (digit, fixgain);
    n++;
  } 
  
  ATH_MSG_VERBOSE(" number of channels in the LArCalibDigitContainer for gain " 
                  << fixgain << ": "<<n );
 
- SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey);
+ SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey, ctx);
 
  // Now loop over map and fill all ROD Data Blocks
  std::map<uint32_t,LArRodEncoder>::iterator it  =mapEncoder.begin(); 
@@ -290,7 +327,10 @@ LArRawDataContByteStreamTool::WriteLArRawChannels(const LArRawChannelContainer*
    ATH_MSG_DEBUG ( "Null pointer passed to WriteLArCalibDigit routine!" );
   return StatusCode::FAILURE;
  }
- if (!m_RodBlockStructure->canSetEnergy()) {
+
+ std::unique_ptr<LArRodBlockStructure> blstruct = makeRodBlockStructure();
+
+ if (!blstruct->canSetEnergy()) {
    ATH_MSG_DEBUG ( "This instance of LArRodBlockStructure can't hold LArRawChannels!" );
     return StatusCode::FAILURE;
  }
@@ -305,7 +345,23 @@ LArRawDataContByteStreamTool::WriteLArRawChannels(const LArRawChannelContainer*
    ATH_MSG_WARNING ( "Attempt to persistify a empty LArDigitContainer to ByteStream" );
    return StatusCode::SUCCESS;
  }
+
+ const CaloDetDescrManager* calodd = nullptr;
+ ATH_CHECK( detStore()->retrieve (calodd, "CaloMgr") );
+ const EventContext& ctx = Gaudi::Hive::currentContext();
+ SG::ReadCondHandle<LArOnOffIdMapping> onOffMapping (m_onOffIdMappingKey, ctx);
+ SG::ReadCondHandle<LArFebRodMapping> febRodMapping (m_febRodMappingKey, ctx);
+ const Hid2RESrcID& hid2re = getHid2RESrcID (**febRodMapping);
+
  std::map<uint32_t, LArRodEncoder> mapEncoder; 
+
+ auto getEncoder = [&] (uint32_t reid) -> LArRodEncoder&
+                   { return mapEncoder.try_emplace (reid,
+                                                    *m_onlineHelper,
+                                                    *calodd,
+                                                    **onOffMapping,
+                                                    blstruct.get()).first->second; };
+
  //LArRodEncoder* Encoder = NULL;
  //uint32_t last_reid(0x0);
  //unsigned n=0; //For debug only
@@ -313,44 +369,44 @@ LArRawDataContByteStreamTool::WriteLArRawChannels(const LArRawChannelContainer*
  for(; it!=it_e; ++it){
      const LArRawChannel& rawChan = *it; 
      HWIdentifier  chid = rawChan.channelID() ; 
-     uint32_t reid      = m_hid2re.getRodID( chid ); 
+     uint32_t reid      = hid2re.getRodID( **febRodMapping, chid ); 
 
 /*
      if ( reid != last_reid ) {
 	last_reid = reid;
 	// The guy does not exist
 	// This will create it
-	mapEncoder[reid].add(&rawChan);
+	getEncoder(reid).add(&rawChan);
 	// This will get its address
 	Encoder = &(mapEncoder[reid]);
      } else Encoder->add(&rawChan) ; // Encoder already there
 */
-     mapEncoder[reid].add(&rawChan);
+     getEncoder(reid).add (&rawChan);
    } 
    // I may want to also include the digits
    if ( m_includeDigits ) {
-	const DataHandle<LArDigitContainer> digitCont;
+        const LArDigitContainer* digitCont = nullptr;
 	if ( evtStore()->retrieve(digitCont,m_DigitContName).isFailure() ){
           ATH_MSG_ERROR ( "Digits required but not really found" );
 	} else {
-	  if ( m_RodBlockStructure->canIncludeRawData() ){
+	  if ( blstruct->canIncludeRawData() ){
 	   LArDigitContainer::const_iterator it_b=digitCont->begin();
 	   LArDigitContainer::const_iterator it_e=digitCont->end();
 	   if (it_b==it_e) {
-             ATH_MSG_WARNING ( "Attempt to persitify a empty LArDigitContainer to ByteStream" );
+             ATH_MSG_WARNING ( "Attempt to persistify a empty LArDigitContainer to ByteStream" );
 	   }
 	   for(; it_b!=it_e; ++it_b){
 		const LArDigit* digit = *it_b;
 		HWIdentifier  chid = digit->hardwareID() ;
-		uint32_t reid      = m_hid2re.getRodID( chid );
+		uint32_t reid      = hid2re.getRodID( **febRodMapping, chid );
 		// Lets use anygain for the moment
-		mapEncoder[reid].add(digit);
+		getEncoder(reid).add (digit);
      	   }
 	  } // End of check whether format allows to include RawData
 	} // Finish checking for Digit container in SG
    } // End of check for digits inclusion
 
- SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey);
+ SG::ReadCondHandle<CaloNoise> noise (m_caloNoiseKey, ctx);
       
  // Now loop over map and fill all ROD Data Blocks
  std::map<uint32_t,LArRodEncoder>::iterator it_m  =mapEncoder.begin(); 
@@ -397,3 +453,62 @@ LArRawDataContByteStreamTool::prepareRobIndex(const RawEvent* re,
   }
   return StatusCode::SUCCESS;
 }
+
+
+/** Construct a RodBlockStructure instance of the proper concrete type. */
+std::unique_ptr<LArRodBlockStructure>
+LArRawDataContByteStreamTool::makeRodBlockStructure() const
+{
+  switch(m_DSPRunMode) {
+  case 0:  // Obsolete; shouldn't get here.
+    std::abort();
+
+  case 2:  //Transparent mode, DSP just copies FEB-data                                            
+    ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockTransparent (#2)" );
+    return std::make_unique<LArRodBlockTransparentV0<LArRodBlockHeaderTransparentV0> >();
+    break;
+
+  case 7: //Calibration mode
+    ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockCalibration (#7)" );
+    return std::make_unique<LArRodBlockCalibrationV0<LArRodBlockHeaderCalibrationV0> >();
+    break;
+
+  case 4: //Physics assembly mode
+    if ( m_RodBlockVersion == 10 ){
+      ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockPhysics (#5)" );
+      return std::make_unique<LArRodBlockPhysicsV5>();
+    }
+    else if ( m_RodBlockVersion == 12 ){
+      ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockPhysics (#6)" );
+      return std::make_unique<LArRodBlockPhysicsV6>();
+    }
+    else {
+      ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockPhysics (#4)" );
+      return std::make_unique<LArRodBlockPhysicsV0>();
+    }
+    break;
+
+  case 5: //Physics assembly mode
+    ATH_MSG_DEBUG ( "Set Rod Block Type to LArRodBlockPhysics (#5)" );
+    return std::make_unique<LArRodBlockPhysicsV3>();
+
+  default:
+    ATH_MSG_WARNING ( "DSP runmode " << m_DSPRunMode << " is unknown. Using physics assembly mode (#4) by default" );
+    return std::make_unique<LArRodBlockPhysicsV0>();
+  }
+}
+
+
+const Hid2RESrcID&
+LArRawDataContByteStreamTool::getHid2RESrcID (const LArFebRodMapping& rodMapping) const
+{
+  if (!m_hid2re) {
+    auto hid2re = std::make_unique<Hid2RESrcID>();
+    if (hid2re->initialize (rodMapping).isFailure()) {
+      std::abort();
+    }
+    m_hid2re.set (std::move (hid2re));
+  }
+  return *m_hid2re.get();
+}
+
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArRodEncoder.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArRodEncoder.cxx
index 20eeeea42a5..7182e95be34 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/LArRodEncoder.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArRodEncoder.cxx
@@ -15,65 +15,17 @@
 #include <Identifier/HWIdentifier.h>
 #include "CaloInterface/ICaloNoiseTool.h"
 
-// static variables
-LArCablingLegacyService*    LArRodEncoder::m_cablingSvc=NULL;
-const LArOnlineID*    LArRodEncoder::m_onlineHelper=NULL; 
-LArRodBlockStructure* LArRodEncoder::m_BlStruct=NULL;
-const CaloDetDescrManager* LArRodEncoder::m_CaloDetDescrManager=NULL;
-
-void LArRodEncoder::setRodBlockStructure(LArRodBlockStructure* BlStructPtr)
-{
-  m_BlStruct=BlStructPtr; 
-}
-
 
 // constructor 
-LArRodEncoder::LArRodEncoder()
+LArRodEncoder::LArRodEncoder (const LArOnlineID& onlineHelper,
+                              const CaloDetDescrManager& calodd,
+                              const LArOnOffIdMapping& onOffIdMapping,
+                              LArRodBlockStructure* BlStruct)
+  : m_onlineHelper (onlineHelper),
+    m_CaloDetDescrManager (calodd),
+    m_onOffIdMapping (onOffIdMapping),
+    m_BlStruct (BlStruct)
 {
-  if(m_cablingSvc==NULL || m_onlineHelper==NULL) {
-    // Message service
-    IMessageSvc*  msgSvc;
-    StatusCode sc = Gaudi::svcLocator()->service( "MessageSvc", msgSvc  );
-    MsgStream log(msgSvc, "LArRodEncoder");
-    if ( log.level() <= MSG::DEBUG )
-      log << MSG::DEBUG << "initialize" << endmsg;
-    // Cabling Service
-    IToolSvc* toolSvc;
-    sc   = Gaudi::svcLocator()->service( "ToolSvc",toolSvc  );
-    if(sc.isSuccess())
-      {
-	sc = 
-	  toolSvc->retrieveTool("LArCablingLegacyService",m_cablingSvc);
-      } else {  // check if it fails
-        // what do you want to do if it fails...
-	log << MSG::FATAL << "Could not get LArCablingService !" << endmsg;
-	exit(1);
-      }
-    //m_cablingSvc = LArCablingService::getInstance(); 
-    // retrieve onlineHelper
-    const LArOnlineID* online_id = 0;
-    StoreGateSvc* detStore = 0;
-    sc =Gaudi::svcLocator()->service( "DetectorStore", detStore );
-    if (sc.isFailure()) {
-      log << MSG::ERROR << "Unable to locate DetectorStore" << endmsg;
-      exit(1);
-    } else {
-      if ( log.level() <= MSG::INFO ) 
-        log << MSG::INFO << "Successfully located DetectorStore" << endmsg;
-    }     
-    sc = detStore->retrieve(online_id, "LArOnlineID");
-    if (sc.isFailure()) {
-      log << MSG::FATAL << "Could not get LArOnlineID helper !" << endmsg;
-      exit(1);
-    } 
-    else {
-      m_onlineHelper=online_id;
-      if ( log.level() <= MSG::DEBUG ) 
-        log << MSG::DEBUG << " Found the LArOnlineID helper. " << endmsg;
-    }
-  }
-
-  m_CaloDetDescrManager = CaloDetDescrManager::instance();
 }
 
 // destructor 
@@ -85,28 +37,28 @@ LArRodEncoder::~LArRodEncoder()
 // Add LArRawChannel
 void LArRodEncoder::add(const LArRawChannel* rc)
 {
- uint32_t FEB_ID = (m_onlineHelper->feb_Id(rc->channelID()).get_identifier32().get_compact());
+ uint32_t FEB_ID = (m_onlineHelper.feb_Id(rc->channelID()).get_identifier32().get_compact());
  if ( m_mFEB[FEB_ID].vLArRC.empty() ){
 	m_mFEB[FEB_ID].vLArRC.resize(128,0);
 	//for(int i=0;i<128;i++) m_mFEB[FEB_ID].vLArRC.push_back(0);
  }
- uint32_t chan = m_BlStruct->FebToRodChannel(m_onlineHelper->channel( rc->channelID() ) );
+ uint32_t chan = m_BlStruct->FebToRodChannel(m_onlineHelper.channel( rc->channelID() ) );
  m_mFEB[FEB_ID].vLArRC[chan]=rc;
 }
 
 // Add free gain digits
 void LArRodEncoder::add(const LArDigit* dg)
-{uint32_t FEB_ID = (m_onlineHelper->feb_Id(dg->hardwareID()).get_identifier32().get_compact());
+{uint32_t FEB_ID = (m_onlineHelper.feb_Id(dg->hardwareID()).get_identifier32().get_compact());
  m_mFEB[FEB_ID].vLArDigit.push_back(dg);
 }
 //Add fixed gain digits
 void LArRodEncoder::add(const LArDigit* dg, const int gain)
-{uint32_t FEB_ID = (m_onlineHelper->feb_Id(dg->hardwareID()).get_identifier32().get_compact());
+{uint32_t FEB_ID = (m_onlineHelper.feb_Id(dg->hardwareID()).get_identifier32().get_compact());
  m_mFEB[FEB_ID].vLArDigitFixed[gain].push_back(dg);
 }
 //Add calibration digits
 void LArRodEncoder::add(const LArCalibDigit* dg, const int gain)
-{uint32_t FEB_ID = (m_onlineHelper->feb_Id(dg->hardwareID()).get_identifier32().get_compact());
+{uint32_t FEB_ID = (m_onlineHelper.feb_Id(dg->hardwareID()).get_identifier32().get_compact());
  m_mFEB[FEB_ID].vLArCalibDigit[gain].push_back(dg);
 }
 
@@ -154,7 +106,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
 
         for (const LArRawChannel *theChannel : it->second.vLArRC) {
 	  if ( theChannel != nullptr ){
-	  int cId =  m_onlineHelper->channel(theChannel->hardwareID());
+	  int cId =  m_onlineHelper.channel(theChannel->hardwareID());
 
 	  int e=theChannel->energy();
           uint32_t quality = theChannel->quality();
@@ -162,9 +114,9 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
 				    quality,theChannel->gain());
 	  
 	  // you convert from hardwareID to offline channle ID hash (???)
-	  myofflineID = m_cablingSvc->cnvToIdentifier(theChannel->hardwareID()) ;
+	  myofflineID = m_onOffIdMapping.cnvToIdentifier(theChannel->hardwareID()) ;
 	  //std::cout << "Got Offile id 0x" << std::hex << myofflineID.get_compact() << std::dec << std::endl;
-          const CaloDetDescrElement* caloDDE = m_CaloDetDescrManager->get_element(myofflineID);
+          const CaloDetDescrElement* caloDDE = m_CaloDetDescrManager.get_element(myofflineID);
 	  // This is probably NOT what one wants. You want the cell gain!
           double cellnoise = noise.getNoise(myofflineID,theChannel->gain());
           if( e > (nsigma*cellnoise) && (quality != 65535 ) ){
@@ -189,7 +141,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
       // Order channels according to ROD numbering
       m_BlStruct->sortDataVector(it->second.vLArDigit);
       for (const LArDigit* digit : it->second.vLArDigit) {
-        int cId =  m_onlineHelper->channel(digit->hardwareID());
+        int cId =  m_onlineHelper.channel(digit->hardwareID());
         m_BlStruct->setRawData(cId, digit->samples(), digit->gain());
       } // end of for digits
     } // End of can Include Raw Data check
@@ -203,7 +155,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
       if(digit_it!=digit_it_end) { //Container not empty
 	m_BlStruct->setNumberOfSamples((*digit_it)->samples().size());
 	for (;digit_it!=digit_it_end;++digit_it)  {
-	  int cId =  m_onlineHelper->channel((*digit_it)->hardwareID());
+	  int cId =  m_onlineHelper.channel((*digit_it)->hardwareID());
 	  //cId = m_BlStruct->FebToRodChannel(cId);
 	  m_BlStruct->setRawData(cId, (*digit_it)->samples(), (*digit_it)->gain());
 	} 
@@ -221,7 +173,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
 	if(digit_it!=digit_it_end) {//Container not empty
 	  m_BlStruct->setNumberOfSamples((*digit_it)->samples().size());
 	  for (;digit_it!=digit_it_end;++digit_it)  {
-	    int cId =  m_onlineHelper->channel((*digit_it)->hardwareID()); 
+	    int cId =  m_onlineHelper.channel((*digit_it)->hardwareID()); 
 	    //cId = m_BlStruct->FebToRodChannel(cId);
 	    m_BlStruct->setRawDataFixed(cId, (*digit_it)->samples(), (*digit_it)->gain());
 	  }
@@ -241,7 +193,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
 	    m_BlStruct->setDelay((*digit_it)->delay());
 	    m_BlStruct->setDAC((*digit_it)->DAC());
 	    for (;digit_it!=digit_it_end;++digit_it) { 
-	      int cId =  m_onlineHelper->channel((*digit_it)->hardwareID()); 
+	      int cId =  m_onlineHelper.channel((*digit_it)->hardwareID()); 
 	      //cId = m_BlStruct->FebToRodChannel(cId);
 	      m_BlStruct->setRawDataFixed(cId, (*digit_it)->samples(), (*digit_it)->gain());
 	      if ((*digit_it)->isPulsed())
@@ -263,7 +215,7 @@ void LArRodEncoder::fillROD(std::vector<uint32_t>& v, MsgStream& logstr, const C
 	  m_BlStruct->setDAC((*digit_it)->DAC());
 	  m_BlStruct->setDelay((*digit_it)->delay());
 	  for (;digit_it!=digit_it_end;digit_it++) { 
-	    int cId =  m_cablingSvc->channel((*digit_it)->channelID()); 
+	    int cId =  m_cablingSvc.channel((*digit_it)->channelID()); 
 	    cId = m_BlStruct->FebToRodChannel(cId);
 	    m_BlStruct->setRawData(cId, (*digit_it)->samples(), (*digit_it)->gain());
 	    m_BlStruct->setIsPulsed(cId);
-- 
GitLab