From 6bd4df0c48a431bbe2ae176db9910c4b24fdd398 Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Thu, 28 Oct 2021 13:21:23 +0100
Subject: [PATCH 1/6] RichDAQ - Decoding fixes when inactive links are present

---
 .../RichFutureDAQ/RichTel40CableMapping.h     |  8 ++-
 .../src/component/RichRawBankDecoder.cpp      | 57 +++++++++++++------
 .../src/lib/RichTel40CableMapping.cpp         |  7 ++-
 3 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/Rich/RichFutureDAQ/include/RichFutureDAQ/RichTel40CableMapping.h b/Rich/RichFutureDAQ/include/RichFutureDAQ/RichTel40CableMapping.h
index 9d234052c37..609449483db 100644
--- a/Rich/RichFutureDAQ/include/RichFutureDAQ/RichTel40CableMapping.h
+++ b/Rich/RichFutureDAQ/include/RichFutureDAQ/RichTel40CableMapping.h
@@ -153,7 +153,13 @@ namespace Rich::Future::DAQ {
     using LinksPerSourceID = std::map<Rich::DAQ::SourceID, std::set<Rich::DAQ::Tel40Connector>>;
 
     /// Array of Tel40 data structs for each connection
-    using Tel40Connections = boost::container::static_vector<Tel40LinkData, MaxConnectionsPerTel40>;
+    class Tel40Connections final : public boost::container::static_vector<Tel40LinkData, MaxConnectionsPerTel40> {
+    public:
+      /// Flag to indicate if at least one link is inactive
+      bool hasInactiveLinks{false};
+      /// Total number of active links;
+      std::size_t nActiveLinks{0};
+    };
 
     /// connection data for each SourceID
     using Tel40SourceIDs = DetectorArray<PanelArray<std::vector<Tel40Connections>>>;
diff --git a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
index 721e2eb74d3..983fdf5da3f 100644
--- a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
+++ b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
@@ -10,11 +10,13 @@
 \*****************************************************************************/
 
 // STD
+#include <algorithm>
 #include <array>
 #include <bitset>
 #include <cstdint>
 #include <limits>
 #include <memory>
+#include <numeric>
 #include <set>
 #include <sstream>
 #include <string>
@@ -357,11 +359,13 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
   // Get the Tel40 DB info for this Source ID
   const auto& connData = tel40Maps.tel40Data( tel40ID );
 
-  // Expected number of data links
-  const auto nTel40Links = connData.size();
+  // Expected number of data size words
+  const auto nSizeWords = connData.size();
+
   // ... number of packed words
-  const auto nPackedSizeW = ( nTel40Links / 2 ) + ( nTel40Links % 2 );
-  daq_debug( " -> Expecting ", nTel40Links, " Tel40 Links, ", nPackedSizeW, " packed header words", endmsg );
+  const auto nPackedSizeW = ( nSizeWords / 2 ) + ( nSizeWords % 2 );
+  daq_debug( " -> Expecting ", connData.nActiveLinks, " active Tel40 Links, ", nPackedSizeW, " packed header words",
+             endmsg );
   if ( bankSize < (std::size_t)nPackedSizeW ) {
     ++m_bankSizeTooSmall;
     std::ostringstream mess;
@@ -373,11 +377,12 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
   std::array<PackedFrameSizes::IntType, Tel40CableMapping::MaxConnectionsPerTel40> connSizes{};
 
   // Decode in 8-bit chunks
-  using DT             = std::uint8_t;
-  const auto NDataBits = std::numeric_limits<DT>::digits;
+  using DT                = std::uint8_t;
+  const auto NDataBits    = std::numeric_limits<DT>::digits;
+  const auto LastBitIndex = NDataBits - 1;
 
   // Loop over the first header words to extract the sizes in bytes
-  std::size_t     iWord{0}, nPayloadWords{0}, iPayloadWord{0};
+  std::size_t     iWord{0}, iPayloadWord{0};
   const DT* const bankStart = bank.begin<DT>();
   const DT*       dataW     = bankStart;      // outside for loop as reused below to decode payload
   const DT* const bankEnd   = bank.end<DT>(); // cache locally
@@ -385,15 +390,31 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
     // Extract the sizes from the packed word
     const PackedFrameSizes sizes( *dataW );
     // extract sizes for each packed value
-    const auto s0 = sizes.size0();
-    const auto s1 = sizes.size1();
-    nPayloadWords += ( s0 + s1 );
-    assert( ( std::size_t )( iWord + 1 ) < connSizes.size() );
-    connSizes[iPayloadWord]     = s1;
-    connSizes[iPayloadWord + 1] = s0;
+    assert( iPayloadWord < connSizes.size() );
+    connSizes[iPayloadWord] = sizes.size1();
+    assert( ( iPayloadWord + 1 ) < connSizes.size() );
+    connSizes[iPayloadWord + 1] = sizes.size0();
     daq_verbo( "  -> Word ", boost::format( "%02i" ) % iWord, " PackedSizeHeader ", sizes, endmsg );
   }
 
+  // If we have any inactive links need to shift expected data sizes around
+  // as padding is at the end, not where the inactive link appears..
+  if ( connData.hasInactiveLinks ) {
+    daq_debug( " -> has at least one link inactive -> Correcting for header padding.", endmsg );
+    for ( std::size_t iL = 0; iL < nSizeWords; ++iL ) {
+      if ( !connData[iL].isActive ) {
+        daq_debug( "  -> Link ", iL, " is inactive", endmsg );
+        for ( auto i = nSizeWords - 1; i > iL; --i ) { connSizes[i] = connSizes[i - 1]; }
+        connSizes[iL] = 0;
+      }
+    }
+  }
+
+  // Count the total number of payload words.
+  // Do this after rearranging for inactive links just to double check we don't
+  // loose hits doing this...
+  const auto nPayloadWords = std::accumulate( connSizes.begin(), connSizes.end(), 0u );
+
   // Validate the data sizes for each tel40 link extracted from the data
   // is in agreement with the overall bank size
   if ( ( nPackedSizeW + nPayloadWords ) != bankSize ) {
@@ -429,7 +450,7 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
       while ( iW < connSizes[iLink] && dataW != bankEnd ) {
 
         // check MSB for this word
-        const auto isNZS = isBitOn<NDataBits - 1>( *dataW );
+        const auto isNZS = isBitOn<LastBitIndex>( *dataW );
         daq_verbo( "  -> NZS=", isNZS, " iW=", iW, " gW=", ( dataW - bankStart ), //
                    " ", boost::format( "%02X" ) % (int)( *dataW ),                //
                    "(", std::bitset<NDataBits>( *dataW ), ")", endmsg );
@@ -478,7 +499,7 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
             // read the NZS word
             auto nzsW = *( dataW + iNZS );
             // if word zero clear MSB as this is the NZS flag
-            if ( 0 == iNZS ) { setBitOff<NDataBits - 1>( nzsW ); }
+            if ( 0 == iNZS ) { setBitOff<LastBitIndex>( nzsW ); }
 
             daq_verbo( "    -> iNZS=", iNZS, " gW=", iNZS + ( dataW - bankStart ), //
                        " ", boost::format( "%02X" ) % (int)( nzsW ),               //
@@ -532,11 +553,13 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
 
     } // no data for this link, so just move on
 
-    // move to next link
+    // move to next Tel40 link
     ++iLink;
 
-    // info() << cData << endmsg;
   } // data word loop
+
+  // Finally assert we reached the end of the bank
+  assert( dataW == bankEnd );
 }
 
 //=============================================================================
diff --git a/Rich/RichFutureDAQ/src/lib/RichTel40CableMapping.cpp b/Rich/RichFutureDAQ/src/lib/RichTel40CableMapping.cpp
index fe888de41e5..36efec8ef54 100644
--- a/Rich/RichFutureDAQ/src/lib/RichTel40CableMapping.cpp
+++ b/Rich/RichFutureDAQ/src/lib/RichTel40CableMapping.cpp
@@ -56,7 +56,7 @@ bool Tel40CableMapping::fillCableMaps( const DeRichSystem& richSys ) {
       // Number of links for this RICH panel
       const std::size_t nLinks = cond->param<int>( "NumberOfLinks" );
       if ( nLinks > 0 ) {
-        debug( " -> Found ", nLinks, " active links", endmsg );
+        debug( " -> Found ", nLinks, " links", endmsg );
 
         // Load links data
         const auto pmtTypes   = cond->paramVect<std::string>( "PMTTypes" );
@@ -155,6 +155,11 @@ bool Tel40CableMapping::fillCableMaps( const DeRichSystem& richSys ) {
           assert( (std::size_t)link.data() < Tel40CableMapping::MaxConnectionsPerTel40 );
           if ( conData.size() <= (std::size_t)link.data() ) { conData.resize( link.data() + 1 ); }
           conData[link.data()] = linkD;
+          if ( status ) {
+            ++conData.nActiveLinks;
+          } else {
+            conData.hasInactiveLinks = true;
+          }
           verbo( "  -> ", linkD, endmsg );
 
           // fill Tel40 module data structure
-- 
GitLab


From 74d7421ff56bc4b0d2ef82f8ea2f6c13da4a1845 Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Thu, 4 Nov 2021 14:33:12 +0000
Subject: [PATCH 2/6] RichDAQ - Minor tweaks to local storage allocations

---
 .../RichFutureDAQ/src/component/RichRawBankDecoder.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
index 983fdf5da3f..8878899c04f 100644
--- a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
+++ b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
@@ -53,9 +53,7 @@
 #include "RichDet/DeRichSystem.h"
 
 // Boost
-#include "boost/container/small_vector.hpp"
 #include "boost/format.hpp"
-#include "boost/lexical_cast.hpp"
 
 // Old 32 bit SmartID
 #include "Kernel/RichSmartID32.h"
@@ -98,7 +96,7 @@ namespace Rich::Future {
     }
 
     /// Type for local decoded SmartID cache
-    using DecodedIDs = boost::container::small_vector<LHCb::RichSmartID, 1000>;
+    using DecodedIDs = LHCb::RichSmartID::Vector;
 
   } // namespace
 
@@ -255,6 +253,8 @@ OutData RawBankDecoder::operator()( const LHCb::RawEvent&     rawEvent,  //
   // working container for decoded Smart IDs
   // Define here to share allocation across all Source IDs
   DecodedIDs decodedIDs;
+  // Pre-allocate minimum 'default' size
+  decodedIDs.reserve( 1536 );
 
   // Make the data map to return
   OutData decodedData;
@@ -423,6 +423,10 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,
                            " != DecodedSize:" + std::to_string( nPackedSizeW + nPayloadWords ) );
   }
 
+  // Guess at number of hits to be created based on # payload words.
+  // Scale factor comes from 'empirical observations'
+  decodedIDs.reserve( 8 * nPayloadWords );
+
   // finally loop over payload words and decode hits
   // note iterator starts from where the above header loop ended...
   std::size_t iLink{0};
-- 
GitLab


From 841c22490749bbd4c872ad10821cd33704b2b27c Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Thu, 4 Nov 2021 15:38:33 +0000
Subject: [PATCH 3/6] remove DeRichSystem from RICH MaPMT1 decoding arguments

---
 Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
index 8878899c04f..f19c8fdfe8c 100644
--- a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
+++ b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
@@ -147,7 +147,6 @@ namespace Rich::Future {
   private:
     /// Decoding for MaPMT1 version
     void decodeToSmartIDs_MaPMT1( const LHCb::RawBank&      bank,      //
-                                  const DeRichSystem&       deRichSys, //
                                   const Tel40CableMapping&  tel40Maps, //
                                   const PDMDBDecodeMapping& pdmdbMaps, //
                                   DecodedIDs&               decodedIDs ) const;
@@ -300,7 +299,7 @@ OutData RawBankDecoder::operator()( const LHCb::RawEvent&     rawEvent,  //
           // Check version to dispatch to the correct decoding
           if ( MaPMT1 == version ) {
             // real PMT bank
-            decodeToSmartIDs_MaPMT1( *bank, deRichSys, tel40Maps, pdmdbMaps, decodedIDs );
+            decodeToSmartIDs_MaPMT1( *bank, tel40Maps, pdmdbMaps, decodedIDs );
           } else if ( StreamSmartIDs == version ) {
             // simple 'streamed RichSmartID' version (MC only)
             decodeToSmartIDs_StreamIDs( *bank, deRichSys, decodedIDs );
@@ -333,8 +332,7 @@ OutData RawBankDecoder::operator()( const LHCb::RawEvent&     rawEvent,  //
 
 //=============================================================================
 
-void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank& bank,           //
-                                              const DeRichSystem& /* deRichSys */, //
+void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank&      bank,      //
                                               const Tel40CableMapping&  tel40Maps, //
                                               const PDMDBDecodeMapping& pdmdbMaps, //
                                               DecodedIDs&               decodedIDs ) const {
-- 
GitLab


From de49667adaebc083d931bc666bc93df49cbdae9c Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Wed, 10 Nov 2021 17:13:29 +0000
Subject: [PATCH 4/6] Properly skip inactive links in Rich encoding

---
 .../include/RichFutureDAQ/EncodeTel40Data.h   |  9 ++++
 .../src/component/RichRawBankDecoder.cpp      | 51 +++++++++----------
 .../RichFutureDAQ/src/lib/EncodeTel40Data.cpp | 39 ++++++++++----
 3 files changed, 63 insertions(+), 36 deletions(-)

diff --git a/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h b/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
index 3d598672159..32815b94d13 100644
--- a/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
+++ b/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
@@ -86,6 +86,12 @@ namespace Rich::Future::DAQ {
       /// Access the number of words (bytes) in this data frame
       auto nBytes() const noexcept { return m_data[0].size() + m_data[1].size(); }
 
+      /// Is this link active
+      auto isActive() const noexcept { return m_isActive; }
+
+      /// Set link active flag
+      void setActive( const bool active ) noexcept { m_isActive = active; }
+
     public:
       /// ostream operator
       friend std::ostream& operator<<( std::ostream& os, const DataHalves& d ) {
@@ -126,6 +132,9 @@ namespace Rich::Future::DAQ {
 
       /// Is ZS or not
       HalfArray<bool> m_zs{true, true};
+
+      /// Is link active or inactive in the DB
+      bool m_isActive{true};
     };
 
     /// Data frame for each connection in a Tel40
diff --git a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
index f19c8fdfe8c..1c128d3dea0 100644
--- a/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
+++ b/Rich/RichFutureDAQ/src/component/RichRawBankDecoder.cpp
@@ -136,7 +136,24 @@ namespace Rich::Future {
                        {KeyValue{"DecodedDataLocation", DecodedDataLocation::Default}} ) {}
 
     /// Initialize
-    StatusCode initialize() override;
+    StatusCode initialize() override {
+      // Initialise base class
+      auto sc = Transformer::initialize();
+      if ( !sc ) return sc;
+
+      // force debug messages
+      // sc = setProperty( "OutputLevel", MSG::VERBOSE );
+
+      // derived conditions
+      Tel40CableMapping::addConditionDerivation( this );
+      PDMDBDecodeMapping::addConditionDerivation( this );
+
+      // report inactive RICHes
+      if ( !m_richIsActive[Rich::Rich1] ) { info() << "Decoding for RICH1 disabled" << endmsg; }
+      if ( !m_richIsActive[Rich::Rich2] ) { info() << "Decoding for RICH2 disabled" << endmsg; }
+
+      return sc;
+    }
 
     /// Algorithm execution via transform
     OutData operator()( const LHCb::RawEvent&     rawEvent,  //
@@ -219,28 +236,6 @@ using namespace Rich::Future;
 
 //=============================================================================
 
-StatusCode RawBankDecoder::initialize() {
-
-  // Initialise base class
-  auto sc = Transformer::initialize();
-  if ( !sc ) return sc;
-
-  // force debug messages
-  // sc = setProperty( "OutputLevel", MSG::VERBOSE );
-
-  // derived conditions
-  Tel40CableMapping::addConditionDerivation( this );
-  PDMDBDecodeMapping::addConditionDerivation( this );
-
-  // report inactive RICHes
-  if ( !m_richIsActive[Rich::Rich1] ) { info() << "Decoding for RICH1 disabled" << endmsg; }
-  if ( !m_richIsActive[Rich::Rich2] ) { info() << "Decoding for RICH2 disabled" << endmsg; }
-
-  return sc;
-}
-
-//=============================================================================
-
 OutData RawBankDecoder::operator()( const LHCb::RawEvent&     rawEvent,  //
                                     const DeRichSystem&       deRichSys, //
                                     const Tel40CableMapping&  tel40Maps, //
@@ -356,9 +351,10 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank&      bank,
 
   // Get the Tel40 DB info for this Source ID
   const auto& connData = tel40Maps.tel40Data( tel40ID );
+  daq_verbo( " -> Connection data array size ", connData.size(), endmsg );
 
   // Expected number of data size words
-  const auto nSizeWords = connData.size();
+  const auto nSizeWords = connData.nActiveLinks;
 
   // ... number of packed words
   const auto nPackedSizeW = ( nSizeWords / 2 ) + ( nSizeWords % 2 );
@@ -398,11 +394,11 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank&      bank,
   // If we have any inactive links need to shift expected data sizes around
   // as padding is at the end, not where the inactive link appears..
   if ( connData.hasInactiveLinks ) {
-    daq_debug( " -> has at least one link inactive -> Correcting for header padding.", endmsg );
-    for ( std::size_t iL = 0; iL < nSizeWords; ++iL ) {
+    daq_debug( " -> Has at least one link inactive -> Correcting for header padding.", endmsg );
+    for ( std::size_t iL = 0; iL < connData.size(); ++iL ) {
       if ( !connData[iL].isActive ) {
         daq_debug( "  -> Link ", iL, " is inactive", endmsg );
-        for ( auto i = nSizeWords - 1; i > iL; --i ) { connSizes[i] = connSizes[i - 1]; }
+        for ( auto i = connData.size() - 1; i > iL; --i ) { connSizes[i] = connSizes[i - 1]; }
         connSizes[iL] = 0;
       }
     }
@@ -412,6 +408,7 @@ void RawBankDecoder::decodeToSmartIDs_MaPMT1( const LHCb::RawBank&      bank,
   // Do this after rearranging for inactive links just to double check we don't
   // loose hits doing this...
   const auto nPayloadWords = std::accumulate( connSizes.begin(), connSizes.end(), 0u );
+  daq_debug( " -> Expecting ", nPayloadWords, " payload words", endmsg );
 
   // Validate the data sizes for each tel40 link extracted from the data
   // is in agreement with the overall bank size
diff --git a/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp b/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
index bf39eda0b63..39c8f282c09 100644
--- a/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
+++ b/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
@@ -42,10 +42,21 @@ EncodeTel40::EncodeTel40( const Tel40CableMapping&   tel40Maps, //
   const auto& links = tel40Maps.linksPerSourceID();
   // loop over tel40's
   for ( const auto& tel40 : links ) {
+    if ( m_parent ) {
+      m_parent->verbose() << "Initialising " << tel40.second.size() << " (active+inactive) links for SourceID "
+                          << tel40.first << endmsg;
+    }
+    // tel40 connection for this link
+    auto& connData = tel40Maps.tel40Data( tel40.first );
     // make entry for this Tel40
     auto& t = m_tel40Data[tel40.first];
     // loop over links and make default entry for each
-    for ( const auto& c : tel40.second ) { t[c]; }
+    for ( const auto& c : tel40.second ) {
+      assert( (std::size_t)c.data() < connData.size() );
+      auto& l = t[c];
+      l.setActive( connData[c.data()].isActive );
+      if ( m_parent ) { m_parent->verbose() << " -> Link " << c << connData[c.data()] << endmsg; }
+    }
   }
 }
 
@@ -123,16 +134,23 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
 
     // loop over connections for this Tel40 and collect frame sizes
     std::uint8_t word = 1;
+    if ( m_parent ) { m_parent->debug() << " -> Found " << tel40.second.size() << " connections" << endmsg; }
     for ( const auto& con : tel40.second ) {
       // Number of bytes in the frame payload
       const auto bSize = con.second.nBytes();
-      totDataSize += bSize;
-      if ( 1 == word ) {
-        packedFrameSizes.emplace_back( 0, bSize );
-        word = 0; // Next time through fill first half of this word
+      // Skip inactive links
+      if ( con.second.isActive() ) {
+        totDataSize += bSize;
+        if ( 1 == word ) {
+          packedFrameSizes.emplace_back( 0, bSize );
+          word = 0; // Next time through fill first half of this word
+        } else {
+          packedFrameSizes.back().setSize0( bSize );
+          word = 1; // Next time through start a new word.
+        }
       } else {
-        packedFrameSizes.back().setSize0( bSize );
-        word = 1; // Next time through start a new word.
+        if ( m_parent ) { m_parent->verbose() << "  -> Skipping inactive link " << con.first << endmsg; }
+        assert( 0 == bSize );
       }
     }
 
@@ -142,9 +160,11 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
 
     // Pipe the data size header words to the RawBank
     for ( const auto h : packedFrameSizes ) {
-      if ( m_parent ) { m_parent->debug() << "  -> Size Header " << h << endmsg; }
+      if ( m_parent ) { m_parent->verbose() << "  -> Size Header " << h << endmsg; }
       payload.emplace_back( h.data() );
     }
+    const auto nHeaderWords = payload.size();
+    m_parent->verbose() << " -> Added " << nHeaderWords << " packed size header words" << endmsg;
 
     // now save the rest of the payload for each connector
     for ( const auto& con : tel40.second ) {
@@ -152,11 +172,12 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
         // zero pad its to two digits...
         boost::format twoDigits( "%u" );
         twoDigits.modify_item( 1, boost::io::group( std::setw( 2 ), std::setfill( '0' ) ) );
-        m_parent->debug() << "  -> Con:" << twoDigits % (int)con.first.data() << " " << con.second << endmsg;
+        m_parent->verbose() << " -> Con:" << twoDigits % (int)con.first.data() << " " << con.second << endmsg;
       }
       // save to payload
       con.second.appendTo( payload );
     }
+    m_parent->verbose() << " -> Added " << payload.size() - nHeaderWords << " payload words" << endmsg;
 
     // finally save to RawEvent
     rawEv.addBank( tel40.first.data(), LHCb::RawBank::Rich, version, std::move( payload ) );
-- 
GitLab


From 75ac627af2e1c8c8eb568e15d6a3f9b6fb80c611 Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Wed, 10 Nov 2021 17:44:32 +0000
Subject: [PATCH 5/6] RichEncodeTel40Data - Clean up messaging

---
 .../include/RichFutureDAQ/EncodeTel40Data.h   | 29 ++++++-----
 .../RichFutureDAQ/src/lib/EncodeTel40Data.cpp | 51 ++++++++++++-------
 2 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h b/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
index 32815b94d13..122ef7436d0 100644
--- a/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
+++ b/Rich/RichFutureDAQ/include/RichFutureDAQ/EncodeTel40Data.h
@@ -22,6 +22,7 @@
 #include <vector>
 
 // RICH Utils
+#include "RichFutureUtils/RichMessaging.h"
 #include "RichUtils/RichDAQDefinitions.h"
 
 // local
@@ -36,8 +37,9 @@
 #include "boost/format/group.hpp"
 #include "boost/range/adaptor/reversed.hpp"
 
-// Gaudi
-#include "GaudiKernel/CommonMessaging.h"
+namespace Gaudi {
+  class Algorithm;
+}
 
 namespace Rich::Future::DAQ {
 
@@ -49,8 +51,8 @@ namespace Rich::Future::DAQ {
 
   public:
     /// Constructor from RICH detector elements
-    EncodeTel40( const Tel40CableMapping&   tel40Maps, //
-                 CommonMessagingBase const* parent = nullptr );
+    EncodeTel40( const Tel40CableMapping& tel40Maps, //
+                 const Gaudi::Algorithm*  parent = nullptr );
 
   public:
     /// 8-bit data words for the two halves of each Tel40 data frame
@@ -147,24 +149,23 @@ namespace Rich::Future::DAQ {
     /// Add data to the storage
     void add( const Rich::DAQ::SourceID       sID,  //
               const Rich::DAQ::Tel40Connector conn, //
-              const Rich::DAQ::FrameBitIndex  bit ) {
-      assert( m_tel40Data.find( sID ) != m_tel40Data.end() );
-      assert( m_tel40Data[sID].find( conn ) != m_tel40Data[sID].end() );
-      auto& frame = m_tel40Data[sID][conn];
-      m_parent->verbose() << "Setting SourceID=" << sID << " Con=" << conn << " Bit=" << bit << endmsg;
-      m_parent->verbose() << "  Before " << frame << endmsg;
-      frame.add( bit );
-      m_parent->verbose() << "  After  " << frame << endmsg;
-    }
+              const Rich::DAQ::FrameBitIndex  bit );
 
     /// Fill RawBanks into a RawEvent
     void fill( LHCb::RawEvent& rawEv, const std::uint8_t version );
 
+  private:
+    /// Define the messenger entity
+    inline auto messenger() const noexcept {
+      assert( m_parent );
+      return m_parent;
+    }
+
   private:
     // data
 
     /// pointer to parent
-    CommonMessagingBase const* m_parent = nullptr;
+    const Gaudi::Algorithm* m_parent = nullptr;
 
     /// AllTel40 data storage
     AllTel40 m_tel40Data;
diff --git a/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp b/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
index 39c8f282c09..9f18b6b0049 100644
--- a/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
+++ b/Rich/RichFutureDAQ/src/lib/EncodeTel40Data.cpp
@@ -14,10 +14,16 @@
 #include "RichFutureDAQ/RichPackedFrameSizes.h"
 
 // Gaudi
+#include "Gaudi/Algorithm.h"
 #include "GaudiKernel/Kernel.h"
 
 using namespace Rich::Future::DAQ;
 
+#define debug( ... )                                                                                                   \
+  if ( messenger() ) { ri_debug( __VA_ARGS__ ); }
+#define verbo( ... )                                                                                                   \
+  if ( messenger() ) { ri_verbo( __VA_ARGS__ ); }
+
 namespace {
 
   /// Set a given bit on
@@ -34,18 +40,27 @@ namespace {
 
 } // namespace
 
-EncodeTel40::EncodeTel40( const Tel40CableMapping&   tel40Maps, //
-                          CommonMessagingBase const* parent )
+void EncodeTel40::add( const Rich::DAQ::SourceID       sID,  //
+                       const Rich::DAQ::Tel40Connector conn, //
+                       const Rich::DAQ::FrameBitIndex  bit ) {
+  assert( m_tel40Data.find( sID ) != m_tel40Data.end() );
+  assert( m_tel40Data[sID].find( conn ) != m_tel40Data[sID].end() );
+  auto& frame = m_tel40Data[sID][conn];
+  verbo( "Setting SourceID=", sID, " Con=", conn, " Bit=", bit, endmsg );
+  verbo( "  Before ", frame, endmsg );
+  frame.add( bit );
+  verbo( "  After  ", frame, endmsg );
+}
+
+EncodeTel40::EncodeTel40( const Tel40CableMapping& tel40Maps, //
+                          const Gaudi::Algorithm*  parent )
     : m_parent( parent ) {
   // init. the data struture to fill
   // get the list of active Tel40s and the links for each
   const auto& links = tel40Maps.linksPerSourceID();
   // loop over tel40's
   for ( const auto& tel40 : links ) {
-    if ( m_parent ) {
-      m_parent->verbose() << "Initialising " << tel40.second.size() << " (active+inactive) links for SourceID "
-                          << tel40.first << endmsg;
-    }
+    verbo( "Initialising ", tel40.second.size(), " (active+inactive) links for SourceID ", tel40.first, endmsg );
     // tel40 connection for this link
     auto& connData = tel40Maps.tel40Data( tel40.first );
     // make entry for this Tel40
@@ -55,7 +70,7 @@ EncodeTel40::EncodeTel40( const Tel40CableMapping&   tel40Maps, //
       assert( (std::size_t)c.data() < connData.size() );
       auto& l = t[c];
       l.setActive( connData[c.data()].isActive );
-      if ( m_parent ) { m_parent->verbose() << " -> Link " << c << connData[c.data()] << endmsg; }
+      verbo( " -> Link ", c, connData[c.data()], endmsg );
     }
   }
 }
@@ -123,7 +138,7 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
   // Loop over the Tel40s filled
   for ( const auto& tel40 : m_tel40Data ) {
 
-    if ( m_parent ) { m_parent->debug() << "Creating RawBank for Source ID = " << tel40.first << endmsg; }
+    debug( "Creating RawBank for Source ID = ", tel40.first, endmsg );
 
     /// container for packed frame sizes
     std::vector<PackedFrameSizes> packedFrameSizes;
@@ -134,7 +149,7 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
 
     // loop over connections for this Tel40 and collect frame sizes
     std::uint8_t word = 1;
-    if ( m_parent ) { m_parent->debug() << " -> Found " << tel40.second.size() << " connections" << endmsg; }
+    debug( " -> Found ", tel40.second.size(), " connections", endmsg );
     for ( const auto& con : tel40.second ) {
       // Number of bytes in the frame payload
       const auto bSize = con.second.nBytes();
@@ -149,7 +164,7 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
           word = 1; // Next time through start a new word.
         }
       } else {
-        if ( m_parent ) { m_parent->verbose() << "  -> Skipping inactive link " << con.first << endmsg; }
+        verbo( "  -> Skipping inactive link ", con.first, endmsg );
         assert( 0 == bSize );
       }
     }
@@ -160,24 +175,22 @@ void EncodeTel40::fill( LHCb::RawEvent& rawEv, const std::uint8_t version ) {
 
     // Pipe the data size header words to the RawBank
     for ( const auto h : packedFrameSizes ) {
-      if ( m_parent ) { m_parent->verbose() << "  -> Size Header " << h << endmsg; }
+      verbo( "  -> Size Header ", h, endmsg );
       payload.emplace_back( h.data() );
     }
     const auto nHeaderWords = payload.size();
-    m_parent->verbose() << " -> Added " << nHeaderWords << " packed size header words" << endmsg;
+    verbo( " -> Added ", nHeaderWords, " packed size header words", endmsg );
 
     // now save the rest of the payload for each connector
     for ( const auto& con : tel40.second ) {
-      if ( m_parent ) {
-        // zero pad its to two digits...
-        boost::format twoDigits( "%u" );
-        twoDigits.modify_item( 1, boost::io::group( std::setw( 2 ), std::setfill( '0' ) ) );
-        m_parent->verbose() << " -> Con:" << twoDigits % (int)con.first.data() << " " << con.second << endmsg;
-      }
+      // zero pad its too two digits...
+      boost::format twoDigits( "%u" );
+      twoDigits.modify_item( 1, boost::io::group( std::setw( 2 ), std::setfill( '0' ) ) );
+      verbo( "  -> Con:", twoDigits % (int)con.first.data(), " ", con.second, endmsg );
       // save to payload
       con.second.appendTo( payload );
     }
-    m_parent->verbose() << " -> Added " << payload.size() - nHeaderWords << " payload words" << endmsg;
+    verbo( " -> Added ", payload.size() - nHeaderWords, " payload words", endmsg );
 
     // finally save to RawEvent
     rawEv.addBank( tel40.first.data(), LHCb::RawBank::Rich, version, std::move( payload ) );
-- 
GitLab


From 55aad680aa2eae91dda3f6236562567877531455 Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Tue, 16 Nov 2021 13:46:37 +0000
Subject: [PATCH 6/6] RichSmartID: Add ecGlobalPMTFrameX2() helper method

---
 .../LHCbKernel/include/Kernel/RichSmartID.h   | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/Kernel/LHCbKernel/include/Kernel/RichSmartID.h b/Kernel/LHCbKernel/include/Kernel/RichSmartID.h
index e8643096751..203ce79f2ff 100644
--- a/Kernel/LHCbKernel/include/Kernel/RichSmartID.h
+++ b/Kernel/LHCbKernel/include/Kernel/RichSmartID.h
@@ -1160,6 +1160,26 @@ namespace LHCb {
       }
     }
 
+    /// Returns a 'local' EC pixel row number for each PMT corrected for the PMT rotations in the EC
+    [[nodiscard]] constexpr std::int32_t ecGlobalPMTFrameX2() const
+#ifdef NDEBUG
+        noexcept
+#endif
+    {
+      assert( isPMT() );
+      static_assert( MaPMT::PDGlobalViewShift % 2 == 0 );
+      if ( isPMT() ) {
+        const auto iCol    = panelLocalModuleColumn();
+        const auto iLocalX = -ecLocalPMTFrameX();
+        return ( isHTypePMT() ? ( iCol * MaPMT::PDGlobalViewShift ) + ( 2 * iLocalX ) + 1
+                              : ( iCol * MaPMT::PDGlobalViewShift ) -
+                                    ( ( pdNumInEC() % 2 ) * ( MaPMT::PDGlobalViewShift / 2 ) ) + iLocalX );
+      } else {
+        // HPD fallback
+        return 0;
+      }
+    }
+
   public:
     // messaging
 
-- 
GitLab