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

Hid2RESrcID depends on the old, thread-unsafe LArCablingLegacyService.

We can't get rid of it completely, because it's required by interfaces
still used by TrigT2CaloCommon.

Refactor so that it won't affect the thread-safety of the rest of this package.

Split out the part of Hid2RESrcID required by FullEventAssembler into
a separate base class RodRobIdMap.

Split the remaining interfaces of Hid2RESrcID into thread-safe and
thread-unsafe versions.  Only the thread-safe functionality will be needed
from this package; the thread-unsafe versions are needed only
by TrigT2CaloCommon.
---
 .../LArByteStream/LArByteStream/Hid2RESrcID.h |  33 ++++--
 .../LArRawDataContByteStreamTool.h            |   3 +-
 .../LArByteStream/LArByteStream/RodRobIdMap.h |  33 ++++++
 .../LArCnv/LArByteStream/src/Hid2RESrcID.cxx  | 107 +++++++-----------
 .../src/LArCalibDigitContByteStreamCnv.cxx    |   2 +-
 .../src/LArDigitContByteStreamCnv.cxx         |   2 +-
 .../src/LArRawChannelContByteStreamCnv.cxx    |   2 +-
 .../LArCnv/LArByteStream/src/RodRobIdMap.cxx  |  25 ++++
 8 files changed, 131 insertions(+), 76 deletions(-)
 create mode 100644 LArCalorimeter/LArCnv/LArByteStream/LArByteStream/RodRobIdMap.h
 create mode 100644 LArCalorimeter/LArCnv/LArByteStream/src/RodRobIdMap.cxx

diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/Hid2RESrcID.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/Hid2RESrcID.h
index 61387bc893a..5d95dc4660c 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/Hid2RESrcID.h
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/Hid2RESrcID.h
@@ -1,11 +1,11 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef LARBYTESTREAM_HID2RESRCID_H
 #define LARBYTESTREAM_HID2RESRCID_H
 
-// #include "ByteStreamData/RESrcID.h" 
+#include "LArByteStream/RodRobIdMap.h" 
 #include "LArIdentifier/LArOnlineID.h" 
 #include "LArCabling/LArCablingLegacyService.h" 
 
@@ -14,6 +14,9 @@
 #include <map>
 
 #include "LArIdentifier/LArReadoutModuleService.h"
+#include "CxxUtils/checker_macros.h"
+
+class LArFebRodMapping;
 
 
 
@@ -39,17 +42,28 @@ public:
 
   typedef HWIdentifier COLLECTION_ID; 
 
-  /** constrcutor 
+  /** constructor 
   */ 
   Hid2RESrcID(); 
 
-  StatusCode initialize(); 
+  // Legacy unsafe version, relying on old cabling service.
+  // Currently still used by TrigT2CaloCommon.
+  StatusCode initialize ATLAS_NOT_THREAD_SAFE (); 
+
+  StatusCode initialize (const LArFebRodMapping& rodMapping);
 
   bool isInitialized() const { return m_initialized;}
 
   /** make a ROD SrcID for a HWIdentifier 
-  */ 
-  uint32_t getRodID  (const HWIdentifier& hid) const ;
+  */
+  // Legacy unsafe version, relying on old cabling service.
+  // Currently still used by TrigT2CaloCommon.
+  uint32_t getRodID ATLAS_NOT_THREAD_SAFE  (const HWIdentifier& hid) const ;
+
+  /** make a ROD SrcID for a HWIdentifier 
+  */
+  uint32_t getRodID (const LArFebRodMapping& rodMapping,
+                     const HWIdentifier& hid) const;
 
   /** make a ROD SrcID for a COLLECTION_ID
   */ 
@@ -67,15 +81,16 @@ public:
   */
   uint32_t getDetID  ( uint32_t ros_id) const;
 
-private: 
+private:
+  StatusCode initialize (const std::vector<HWIdentifier>& roms);
+
   bool m_initialized;
   LArCablingLegacyService* m_cablingSvc; 
   const LArOnlineID* m_onlineHelper; 
   typedef std::map<HWIdentifier, uint32_t> COLL_MAP ; 
   COLL_MAP m_coll2ROD ; 
-
   LArReadoutModuleService m_readoutModuleSvc;
-
+  RodRobIdMap m_rodRobIdMap;
 };
 
 #endif 
diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
index 879ad19c035..e8a6bc1643c 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRawDataContByteStreamTool.h
@@ -18,6 +18,7 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 //#include "GaudiKernel/ToolHandle.h"
 #include "LArByteStream/Hid2RESrcID.h"
+#include "LArByteStream/RodRobIdMap.h"
 #include "ByteStreamCnvSvcBase/FullEventAssembler.h" 
 #include "ByteStreamData/RawEvent.h" 
 #include "LArByteStream/LArRodDecoder.h"
@@ -44,7 +45,7 @@ class IByteStreamEventAccess;
       
 class LArRawDataContByteStreamTool: public AthAlgTool {
 public:
-  using FEA_t = FullEventAssembler<Hid2RESrcID>;
+  using FEA_t = FullEventAssembler<RodRobIdMap>;
 
   /** Constructor
       Standard AlgTool constructor
diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/RodRobIdMap.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/RodRobIdMap.h
new file mode 100644
index 00000000000..ba0840eead1
--- /dev/null
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/RodRobIdMap.h
@@ -0,0 +1,33 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+/*
+ * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration.
+ */
+/**
+ * @file LArByteStream/RodRobIdMap.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Oct, 2020
+ * @brief ROD->ROB mapping part of Hid2RESrcID.
+ */
+
+
+#ifndef LARBYTESTREAM_RODROBIDMAP_H
+#define LARBYTESTREAM_RODROBIDMAP_H
+
+
+#include <cstdint>
+
+
+/**
+ * @brief This implements just the ROD->ROB conversion part
+ *        of Hid2RESrcID.  This is all that's needed
+ *        by FullEventAssembler.
+ */
+class RodRobIdMap
+{
+public:
+  /** Make a ROB Source ID from a ROD source ID
+  */ 
+  uint32_t getRobID  ( uint32_t rod_id) const;
+};
+
+#endif // not LARBYTESTREAM_RODROBIDMAP_H
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/Hid2RESrcID.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/Hid2RESrcID.cxx
index ecbcc88b7da..14c96b1fc24 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/Hid2RESrcID.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/Hid2RESrcID.cxx
@@ -1,13 +1,13 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "LArByteStream/Hid2RESrcID.h" 
+#include "LArByteStream/Hid2RESrcID.h"
+#include "LArRecConditions/LArFebRodMapping.h"
 #include "CaloIdentifier/LArID_Exception.h"
 #include "AtlasDetDescr/AtlasDetectorID.h"
-#include "GaudiKernel/Bootstrap.h"
-#include "GaudiKernel/ISvcLocator.h"
 #include "GaudiKernel/IToolSvc.h"
+#include "GaudiKernel/ToolHandle.h"
 #include "StoreGate/StoreGateSvc.h"
 #include "GaudiKernel/MsgStream.h"
 
@@ -35,64 +35,38 @@ Hid2RESrcID::Hid2RESrcID():
 
 } 
 
-StatusCode Hid2RESrcID::initialize()
+StatusCode Hid2RESrcID::initialize ATLAS_NOT_THREAD_SAFE ()
+{  
+  ServiceHandle<IToolSvc> toolSvc ("ToolSvc", "Hid2RESrcID");
+  ATH_CHECK( toolSvc.retrieve() );
+  ATH_CHECK( toolSvc->retrieveTool("LArCablingLegacyService",m_cablingSvc) );
+
+  const std::vector<HWIdentifier>& roms = m_cablingSvc->getLArRoModIDvec();
+  ATH_CHECK( initialize (roms) );
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode Hid2RESrcID::initialize (const LArFebRodMapping& rodMapping)
+{  
+  ATH_CHECK( initialize (rodMapping.getLArRoModIDvec()) );
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode Hid2RESrcID::initialize (const std::vector<HWIdentifier>& roms)
 {  
-  // Message service
-  IMessageSvc*  msgSvc;
-  StatusCode sc = Gaudi::svcLocator()->service( "MessageSvc", msgSvc  );
-  MsgStream log(msgSvc, "Hid2RESrcID");
-
-  // Cabling Service
-  IToolSvc* toolSvc;
-  sc   = Gaudi::svcLocator()->service("ToolSvc",toolSvc  );
-  if(sc.isSuccess())
-    {
-      sc = toolSvc->retrieveTool("LArCablingLegacyService",m_cablingSvc);
-      if (sc.isFailure()) {
-	log << MSG::FATAL << "Could not get LArCablingLegacyService !" << endmsg;
-	exit(1);
-      }
-    } else {  // check if it fails
-        // what do you want to do if it fails...
-      log << MSG::FATAL << "Could not get ToolSvc !" << 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 {
-    log << MSG::VERBOSE << "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;
-    log << MSG::VERBOSE << " Found the LArOnlineID helper. " << endmsg;
-  }
+  ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "Hid2RESrcID");
+  ATH_CHECK( detStore.retrieve() );
+  ATH_CHECK( detStore->retrieve(m_onlineHelper, "LArOnlineID") );
 
   // make internal maps 
   
   eformat::SubDetector detid ;
-  
-  
-
-  const std::vector<HWIdentifier>& roms = m_cablingSvc->getLArRoModIDvec();
-  std::vector<HWIdentifier>::const_iterator it =  roms.begin(); 
-  std::vector<HWIdentifier>::const_iterator it_end =  roms.end(); 
-
-  for(; it!=it_end; ++it)
+  for (const HWIdentifier& mId : roms)
     { 
-      HWIdentifier mId(*it); 
       detid = (eformat::SubDetector) m_readoutModuleSvc.subDet(mId); 
       uint8_t m = m_readoutModuleSvc.rodFragId(mId); 
 
@@ -117,14 +91,16 @@ uint32_t  Hid2RESrcID::getRodIDFromROM(const COLLECTION_ID& id) const
   COLL_MAP::const_iterator it = m_coll2ROD.find( id ); 
   if(it == m_coll2ROD.end()){
     std::cout <<" H2d2RESrcID invalid COLL ID in hex "<<std::hex<<id.get_compact()<<std::dec<<std::endl;
-    assert(0); 
+    std::abort();
   }	
 
   return  (*it).second ;
 }
 
 
-uint32_t  Hid2RESrcID::getRodID(const HWIdentifier& hid) const
+// Legacy unsafe version, relying on old cabling service.
+// Currently still used by TrigT2CaloCommon.
+uint32_t  Hid2RESrcID::getRodID ATLAS_NOT_THREAD_SAFE (const HWIdentifier& hid) const
 { // this method returns a RESrcID for the ROD, for a given LArOnlineID
   // channel number is ignored.
   HWIdentifier febId =  m_onlineHelper->feb_Id(hid) ;
@@ -134,16 +110,21 @@ uint32_t  Hid2RESrcID::getRodID(const HWIdentifier& hid) const
   return getRodIDFromROM(romId); 
 }
 
+uint32_t  Hid2RESrcID::getRodID(const LArFebRodMapping& rodMapping,
+                                const HWIdentifier& hid) const
+{ // this method returns a RESrcID for the ROD, for a given LArOnlineID
+  // channel number is ignored.
+  HWIdentifier febId =  m_onlineHelper->feb_Id(hid) ;
+  HWIdentifier romId = rodMapping.getReadoutModuleID(febId);
+  
+  return getRodIDFromROM(romId); 
+}
+
 /** mapping SrcID from ROD to ROB
  */ 
 uint32_t Hid2RESrcID::getRobID( uint32_t rod_id) const
 {
-//  Change Module Type to ROB 
-
- SourceIdentifier  id  = SourceIdentifier(rod_id);
- SourceIdentifier  id2 = SourceIdentifier(id.subdetector_id(), id.module_id());
- return    id2.code();
-
+  return m_rodRobIdMap.getRobID (rod_id);
 }
 
 
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArCalibDigitContByteStreamCnv.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArCalibDigitContByteStreamCnv.cxx
index 750f18aedca..5c3850234e6 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/LArCalibDigitContByteStreamCnv.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArCalibDigitContByteStreamCnv.cxx
@@ -102,7 +102,7 @@ LArCalibDigitContByteStreamCnv::createRepConst(DataObject* pObj, IOpaqueAddress*
 {// convert LArDigits from StoreGate into ByteStream
   ATH_MSG_VERBOSE( "Execute CreateRep method of LArCalibDigitContainer " );
   // Get Full Event Assembler
-  FullEventAssembler<Hid2RESrcID> *fea = 0;
+  FullEventAssembler<RodRobIdMap> *fea = 0;
   ATH_CHECK( m_byteStreamCnvSvc->getFullEventAssembler(fea,"LAr") );
 
   LArCalibDigitContainer* CalibDigitContainer=0;
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArDigitContByteStreamCnv.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArDigitContByteStreamCnv.cxx
index 3bfcf354cdb..3d2c8396c50 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/LArDigitContByteStreamCnv.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArDigitContByteStreamCnv.cxx
@@ -119,7 +119,7 @@ LArDigitContByteStreamCnv::createRepConst(DataObject* pObj, IOpaqueAddress*& pAd
   ATH_MSG_VERBOSE( "Execute CreateRep method of LArDigitContainer " );
 
   // Get Full Event Assembler
-  FullEventAssembler<Hid2RESrcID> *fea = 0;
+  FullEventAssembler<RodRobIdMap> *fea = 0;
   ATH_CHECK( m_byteStreamCnvSvc->getFullEventAssembler(fea,"LAr") );
 
   LArDigitContainer* DigitContainer=0;
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelContByteStreamCnv.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelContByteStreamCnv.cxx
index d702953edb1..a71c66a2ea3 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelContByteStreamCnv.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelContByteStreamCnv.cxx
@@ -102,7 +102,7 @@ LArRawChannelContByteStreamCnv::createRepConst(DataObject* pObj, IOpaqueAddress*
 { // convert LArRawChannels in the container into ByteStream
    
    // Get Full Event Assembler
-  FullEventAssembler<Hid2RESrcID> *fea = 0;
+  FullEventAssembler<RodRobIdMap> *fea = 0;
   ATH_CHECK( m_byteStreamCnvSvc->getFullEventAssembler(fea,"LAr") );
 
   LArRawChannelContainer* ChannelContainer = nullptr;
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/RodRobIdMap.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/RodRobIdMap.cxx
new file mode 100644
index 00000000000..df18932b92f
--- /dev/null
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/RodRobIdMap.cxx
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration.
+ */
+/**
+ * @file LArByteStream/src/RodRobIdMap.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Oct, 2020
+ * @brief ROD->ROB mapping part of Hid2RESrcID.
+ */
+
+
+#include "LArByteStream/RodRobIdMap.h"
+#include "eformat/SourceIdentifier.h" 
+
+
+/** mapping SrcID from ROD to ROB
+ */ 
+uint32_t RodRobIdMap::getRobID( uint32_t rod_id) const
+{
+  //  Change Module Type to ROB 
+  using eformat::helper::SourceIdentifier; 
+  SourceIdentifier  id  = SourceIdentifier(rod_id);
+  SourceIdentifier  id2 = SourceIdentifier(id.subdetector_id(), id.module_id());
+  return    id2.code();
+}
-- 
GitLab