From faf1c205b75fb4eeeb31a6513595dba01c4d261a Mon Sep 17 00:00:00 2001
From: Walter Lampl <Walter.Lampl@cern.ch>
Date: Tue, 6 Aug 2019 15:34:35 +0200
Subject: [PATCH] Re-entrant Algorimth reading LArRawChannels from Bytestream
 to replace the old-style converter

---
 .../python/LArRawChannelBSReadConfig.py       |  39 +++++
 .../src/LArRawChannelBSReadAlg.cxx            | 146 ++++++++++++++++++
 .../src/LArRawChannelBSReadAlg.h              |  47 ++++++
 .../src/components/LArByteStream_entries.cxx  |   2 +
 4 files changed, 234 insertions(+)
 create mode 100644 LArCalorimeter/LArCnv/LArByteStream/python/LArRawChannelBSReadConfig.py
 create mode 100644 LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.cxx
 create mode 100644 LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.h

diff --git a/LArCalorimeter/LArCnv/LArByteStream/python/LArRawChannelBSReadConfig.py b/LArCalorimeter/LArCnv/LArByteStream/python/LArRawChannelBSReadConfig.py
new file mode 100644
index 00000000000..29ada223dad
--- /dev/null
+++ b/LArCalorimeter/LArCnv/LArByteStream/python/LArRawChannelBSReadConfig.py
@@ -0,0 +1,39 @@
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
+from LArByteStream.LArByteStreamConf import LArRawChannelBSReadAlg
+from LArGeoAlgsNV.LArGMConfig import LArGMCfg
+
+def LArRawChannelBRReadCfg(configFlags):
+    acc=ComponentAccumulator()
+    acc.merge(LArGMCfg(configFlags)) #Needed for identifier helpers
+    acc.merge(ByteStreamReadCfg(configFlags))    
+    acc.addEventAlgo(LArRawChannelBSReadAlg())
+    return acc
+
+
+if __name__=="__main__":
+
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import DEBUG
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior=1
+    log.setLevel(DEBUG)
+
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+    ConfigFlags.LAr.doAlign=False
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.lock()
+
+    acc=LArRawChannelBRReadCfg(ConfigFlags)
+    
+    from LArEventTest.LArEventTestConf import DumpLArRawChannels
+    from LArCabling.LArCablingConfig import LArOnOffIdMappingCfg 
+    acc.merge(LArOnOffIdMappingCfg(ConfigFlags))
+    acc.addEventAlgo(DumpLArRawChannels(LArRawChannelContainerName="LArRawChannels",))
+
+    #acc.getService("IOVDbSvc").OutputLevel=VERBOSE
+
+    f=open("LArRawChannelBSRead.pkl","w")
+    acc.store(f)
+    f.close()
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.cxx
new file mode 100644
index 00000000000..4a0426a76c5
--- /dev/null
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.cxx
@@ -0,0 +1,146 @@
+#include "LArRawChannelBSReadAlg.h"
+#include "LArIdentifier/LArOnlineID.h"
+#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h" 
+#include "LArRawEvent/LArRawChannelContainer.h"
+#include "eformat/Version.h"
+#include "eformat/index.h"
+//#include "eformat/Issue.h"
+
+
+#include "LArByteStream/LArRodBlockStructure.h"
+//#include "LArByteStream/LArRodBlockPhysicsV0.h"
+//#include "LArByteStream/LArRodBlockPhysicsV1.h"
+//#include "LArByteStream/LArRodBlockPhysicsV2.h"
+//#include "LArByteStream/LArRodBlockPhysicsV3.h"
+//#include "LArByteStream/LArRodBlockPhysicsV4.h"
+#include "LArByteStream/LArRodBlockPhysicsV5.h"
+#include "LArByteStream/LArRodBlockPhysicsV6.h"
+
+
+LArRawChannelBSReadAlg::LArRawChannelBSReadAlg(const std::string& name, ISvcLocator* pSvcLocator) :  
+  AthReentrantAlgorithm(name, pSvcLocator) {
+  //Fill vector of LAr ROB ids:
+  for (uint32_t i=0x41;i<=0x48;++i) {
+    //Fixme these are only subdetector ids.
+    m_larROBIds.push_back(i);
+  }
+
+}
+  
+
+StatusCode LArRawChannelBSReadAlg::initialize() {
+  ATH_CHECK(m_rawChannelKey.initialize());
+  ATH_CHECK(m_robDataProviderSvc.retrieve());
+  ATH_CHECK(detStore()->retrieve(m_onlineId,"LArOnlineID"));  
+  return StatusCode::SUCCESS;
+}     
+  
+StatusCode LArRawChannelBSReadAlg::finalize() {
+  return StatusCode::SUCCESS;
+} 
+
+StatusCode LArRawChannelBSReadAlg::execute(const EventContext& ctx) const {
+
+  //Write output via write handle
+  SG::WriteHandle<LArRawChannelContainer>outputContainer(m_rawChannelKey,ctx);
+  ATH_CHECK(outputContainer.record(std::make_unique<LArRawChannelContainer>()));
+
+ 
+  //std::vector<const IROBDataProviderSvc::ROBF*> robFrags;
+  //m_robDataProviderSvc->getROBData(ctx,m_larROBIds,robFrags);
+  //if (robFrags.size()==0) {
+  //  ATH_MSG_DEBUG("No LAr data found in this event. Recording empty LArRawChannelContainer");
+  //  return StatusCode::SUCCESS;
+  //} 
+  //for (const IROBDataProviderSvc::ROBF* rob : robFrags) {
+
+
+  const RawEvent* fullEvent=m_robDataProviderSvc->getEvent(ctx);
+  std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> > rawEventTOC;
+  eformat::helper::build_toc(*fullEvent, rawEventTOC);
+  auto larRobs=rawEventTOC.find(eformat::LAR);
+  if (larRobs==rawEventTOC.end()) {
+     ATH_MSG_DEBUG("No LAr data found in this event. Recording empty LArRawChannelContainer");
+     return StatusCode::SUCCESS;
+  } 
+  
+  for (const uint32_t* robPtr : larRobs->second) {
+    OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment rob(robPtr);
+    ATH_MSG_VERBOSE("Decoding ROB fragment 0x" << std::hex << rob.rob_source_id () << " with " << std::dec << rob.rod_fragment_size_word() << "ROB words");
+
+    if (rob.rod_fragment_size_word() <3) {
+      ATH_MSG_ERROR("Encountered corrupt ROB fragment, less than 3 words!");
+      return StatusCode::FAILURE;
+    }
+    
+    const uint32_t* pData=rob.rod_data();
+    const uint32_t  nData=rob.rod_ndata();
+ 
+    eformat::helper::Version ver(rob.rod_version());
+    const uint16_t rodMinorVersion=ver.minor_version();
+    const uint32_t rodBlockType=rob.rod_detev_type()&0xff;
+    ATH_MSG_VERBOSE("Found version " << rodMinorVersion <<  " of Rod Block Type  " <<  rodBlockType);
+
+    std::unique_ptr<LArRodBlockStructure> rodBlock;
+
+
+    if (rodBlockType==4) { //Physics mode
+      switch(rodMinorVersion) {
+      case 12: //Physics mode v6 09.03.2011 for LHC
+	rodBlock.reset(new LArRodBlockPhysicsV6);
+	break;
+      case 11: //Physics mode v5 16.06.2008 for LHC 
+      case 10: //Physics mode v5 16.06.2008 for LHC 
+	rodBlock.reset(new LArRodBlockPhysicsV5);
+	break;
+      default:
+	ATH_MSG_ERROR("Found unsupported ROD Block version " << rodMinorVersion 
+		      << " of ROD block type " << rodBlockType);
+	return StatusCode::FAILURE;
+      }// end switch(rodMinorVersion)
+    }//end of rodBlockType==4
+    else {
+      ATH_MSG_ERROR("Found unsupported Rod block type " << rodBlockType);
+      return StatusCode::FAILURE;
+    }
+
+    if (!rodBlock->setFragment(pData,nData)) {
+      ATH_MSG_ERROR("Failed to assign fragment pointer to LArRodBlockStructure");
+      return StatusCode::FAILURE;
+    }
+
+    //Loop over FEBs in ROD:
+    do {
+      HWIdentifier fId( Identifier32(rodBlock->getFEBID()) );
+      if (!m_onlineId->isValidId(fId)) {
+	ATH_MSG_WARNING("Invalid FEB identifer 0x" << std::hex << fId.get_identifier32().get_compact() 
+			<< ". Skipping");
+	continue;
+      }
+      
+      //FIXME: Add status-word and checksum verification to catch corrupt events
+
+
+      int32_t energy;
+      int32_t time;
+      int32_t quality;
+      uint32_t gain;
+      int fcNb;
+      const int NthisFebChannel=m_onlineId->channelInSlotMax(fId);
+      while (rodBlock->getNextEnergy(fcNb,energy,time,quality,gain)) {
+	if (fcNb>=NthisFebChannel)
+	  continue;
+
+	HWIdentifier cId = m_onlineId->channel_Id(fId,fcNb);
+        uint16_t iquality = 0;
+        uint16_t iprovenance = 0x1000;
+        if (quality>0) {
+            iprovenance |= 0x2000;
+            iquality = (quality & 0xFFFF);
+        } 
+	outputContainer->emplace_back(cId, energy, time, iquality, iprovenance, (CaloGain::CaloGain)gain);
+      }//end getNextEnergyLoop
+    }while (rodBlock->nextFEB()); //Get NextFeb
+  } //end loop over ROBs
+  return StatusCode::SUCCESS;
+}
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.h b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.h
new file mode 100644
index 00000000000..185004e7a31
--- /dev/null
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/LArRawChannelBSReadAlg.h
@@ -0,0 +1,47 @@
+//Dear emacs, this is -*-c++-*- 
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef LARBYSTREAM_LARRAWCHANNELBSREADALG_H
+#define LARBYSTREAM_LARRAWCHANNELBSREADALG_H
+
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+//#include "StoreGate/ReadHandle.h"
+#include "StoreGate/WriteHandle.h"
+#include "StoreGate/ReadCondHandle.h"
+#include "LArCabling/LArOnOffIdMapping.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+
+//Event classes
+class LArRawChannelContainer;
+class LArOnlineID;
+class IROBDataProviderSvc;
+
+class LArRawChannelBSReadAlg : public  AthReentrantAlgorithm {
+ public:
+  LArRawChannelBSReadAlg(const std::string& name, ISvcLocator* pSvcLocator);
+
+  StatusCode initialize() override;
+  StatusCode execute(const EventContext& ctx) const override;
+  StatusCode finalize() override;
+
+
+ private:
+  //Event output:
+  SG::WriteHandleKey<LArRawChannelContainer> m_rawChannelKey{this,"LArRawChannelKey","LArRawChannels",
+      "SG key of the LArRawChannelContainer"};
+  
+  
+  ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc{this,"ROBDataProviderSvc","ROBDataProviderSvc"};
+  
+  //Identifier helper
+  const LArOnlineID* m_onlineId;
+
+  std::vector<uint32_t> m_larROBIds;
+
+};
+
+#endif
diff --git a/LArCalorimeter/LArCnv/LArByteStream/src/components/LArByteStream_entries.cxx b/LArCalorimeter/LArCnv/LArByteStream/src/components/LArByteStream_entries.cxx
index b9c6f83e3b0..c6ab45ef843 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/src/components/LArByteStream_entries.cxx
+++ b/LArCalorimeter/LArCnv/LArByteStream/src/components/LArByteStream_entries.cxx
@@ -8,12 +8,14 @@
 #include "LArByteStream/LArRodDecoder.h"
 #include "LArByteStream/LArABBADecoder.h"
 #include "ByteStreamCnvSvcBase/CollectionByteStreamCnv.h"
+#include "../LArRawChannelBSReadAlg.h"
 //#include "LArByteStream/LArRawChannelCollByteStreamTool.h"
 
 // Containers 
 DECLARE_COMPONENT( LArRawDataContByteStreamTool )
 DECLARE_COMPONENT( LArRodDecoder )
 DECLARE_COMPONENT( LArABBADecoder )
+DECLARE_COMPONENT( LArRawChannelBSReadAlg )
 
 DECLARE_CONVERTER( LArRawChannelContByteStreamCnv )
 DECLARE_CONVERTER( LArDigitContByteStreamCnv )
-- 
GitLab