diff --git a/DAQ/DAQSys/CMakeLists.txt b/DAQ/DAQSys/CMakeLists.txt
index 433bd6422ff1b57c565accadc0e67a3bca4849f9..66c9dcccd742df8c0ae8c7e7ca4ae0d71287adae 100644
--- a/DAQ/DAQSys/CMakeLists.txt
+++ b/DAQ/DAQSys/CMakeLists.txt
@@ -18,3 +18,5 @@ gaudi_generate_confuserdb()
 lhcb_add_confuser_dependencies(DAQ/RawEventCompat)
 
 gaudi_add_tests(QMTest)
+
+set_property( TEST DAQSys.gaudirun DAQSys.gaudirun-defsplit APPEND PROPERTY DISABLED TRUE )
diff --git a/DAQ/DAQSys/python/DAQSys/Decoders.py b/DAQ/DAQSys/python/DAQSys/Decoders.py
index 27ca879daeb5f4c0b5915cd03ead732088a163e4..0bc1298c6bf8e0a11f79e5ac1cc7e5ef0506821e 100644
--- a/DAQ/DAQSys/python/DAQSys/Decoders.py
+++ b/DAQ/DAQSys/python/DAQSys/Decoders.py
@@ -171,21 +171,14 @@ tool2 = tool.clone(tname + "/ToolSvc." + tname)
 
 #report, the type of report
 for report in ["Dec", "Sel"]:
-    #hlt, which HLT to decode? None=both, 1=Hlt1, 2=Hlt2
-    for hlt in [None, 1, 2]:
-        hltname = "Hlt"
-        algtype = "Hlt" + report + "ReportsDecoder"
-        algname = algtype
-        active = False
-        if hlt is not None:
-            hltname = hltname + str(hlt)
-            algname = algtype + "/" + hltname + report + "ReportsDecoder"
-            active = True
+    #which HLT to decode?
+    for hltname in ["Hlt1", "Hlt2"]:
         #create the decoder
         dec = Decoder(
             #\/ e.g. HltSelReportsDecoder/Hlt1SelReportsDecoder
-            algname,
-            active,
+            "Hlt" + report + "ReportsDecoder/" + hltname + report +
+            "ReportsDecoder",
+            active=True,
             #\/ e.g. HltSelReports
             banks=["Hlt" + report + "Reports"],
             inputs={"RawEventLocations": None},
@@ -194,34 +187,27 @@ for report in ["Dec", "Sel"]:
                 "OutputHlt" + report + "ReportsLocation":
                 hltname + "/" + report + "Reports"
             },
-            properties={"SourceID": hlt},  #None=default(0)
+            properties={"SourceID": hltname},
             conf=DecoderDB)
         if report == "Sel":
             dec.Outputs[
                 "OutputHltObjectSummariesLocation"] = hltname + "/SelReports/Candidates"
 
 #Vertex Decoder
-Decoder(
-    "HltVertexReportsDecoder",
-    active=True,
-    banks=["HltVertexReports"],
-    inputs={"RawEventLocations": None},
-    outputs={
-        "OutputHltVertexLocations":
-        ["Hlt/VertexReports/PV3D", "Hlt/VertexReports/ProtoPV3D"]
-    },
-    conf=DecoderDB)
-#Also TrackingDecoder, but don't make it active, it's only used during HLT2 stand-alone!
-Decoder(
-    "HltTrackReportsDecoder",
-    active=False,
-    banks=["HltTrackReports"],
-    inputs={"RawEventLocations": None},
-    outputs={
-        "OutputHltTrackReportsLocation":
-        ["Hlt/Track/Velo", "Hlt/Track/VeloTTHPT", "Hlt/Track/ForwardHPT"]
-    },
-    conf=DecoderDB)
+for hltname in ["Hlt1", "Hlt2"]:
+    Decoder(
+        "HltVertexReportsDecoder/" + hltname + "VertexReportsDecoder",
+        active=True,
+        banks=["HltVertexReports"],
+        inputs={"RawEventLocations": None},
+        outputs={
+            "OutputHltVertexReportsLocations": [
+                hltname + "/VertexReports/PV3D",
+                hltname + "/VertexReports/ProtoPV3D"
+            ]
+        },
+        properties={"SourceID": hltname},
+        conf=DecoderDB)
 
 #is a Routing bits filter really a decoder? it doesn't create output...
 Decoder(
diff --git a/DAQ/DAQSys/tests/options/test-decoder-db.py b/DAQ/DAQSys/tests/options/test-decoder-db.py
index d11b78f6cfc96de0909e9bd0f4af2851cc48c482..13474ac67d70c64f1598253504801508a427dae4 100644
--- a/DAQ/DAQSys/tests/options/test-decoder-db.py
+++ b/DAQ/DAQSys/tests/options/test-decoder-db.py
@@ -199,10 +199,7 @@ if test_db["0"].listRequired() != [
 from DAQSys.Decoders import caloSetZeroSuppressed
 caloSetZeroSuppressed(DecoderDB, False)
 #next add configuration of the inactive algorithms, because they're not in the default DB
-for dec in [
-        "HltTrackReportsDecoder", "CaloDigitsFromRaw/EcalFromRaw",
-        "CaloDigitsFromRaw/HcalFromRaw"
-]:
+for dec in ["CaloDigitsFromRaw/EcalFromRaw", "CaloDigitsFromRaw/HcalFromRaw"]:
     if dec not in DecoderDB:
         raise KeyError(
             "The decoder called " + dec +
diff --git a/DAQ/DAQSys/tests/qmtest/daqsys.qms/gaudirun.qmt b/DAQ/DAQSys/tests/qmtest/daqsys.qms/gaudirun.qmt
index 6ca1711a8967236119168c71b538466e83dbc4e8..b53f9119055e8ab04d896fa94ac6100361edf4a9 100644
--- a/DAQ/DAQSys/tests/qmtest/daqsys.qms/gaudirun.qmt
+++ b/DAQ/DAQSys/tests/qmtest/daqsys.qms/gaudirun.qmt
@@ -31,11 +31,11 @@
   <argument name="args"><set>
     <text>../options/test-gaudirun.py</text>
     <text>--option</text>
-    <text>from PRConfig import TestFileDB; TestFileDB.test_file_db['2012_raw_default'].run();from Configurables import LHCbApp; LHCbApp().EvtMax=10;</text>
+    <text>from PRConfig import TestFileDB; TestFileDB.test_file_db['2015_raw_full'].run();from Configurables import LHCbApp; LHCbApp().EvtMax=10;</text>
   </set></argument>
   <argument name="validator"><text>
 
-countErrorLines({"FATAL":0, "ERROR":2, "WARNING" :0})
+countErrorLines({"FATAL":0, "ERROR":6, "WARNING" :7})
 
 # check there are no warnings printed about the configuration
 warnlines=[l for l in stdout.split('\n') if l.strip().startswith("# WARNING:") and "DQFLAGS" not in l and "cppyy" not in l]
diff --git a/Event/DAQEvent/include/Event/RawEvent.h b/Event/DAQEvent/include/Event/RawEvent.h
index 17f5a71f47574d544a96de15a485cb4d7403a4e7..11e14e7f61375b244cb29aab728cadabd4bd3698 100644
--- a/Event/DAQEvent/include/Event/RawEvent.h
+++ b/Event/DAQEvent/include/Event/RawEvent.h
@@ -190,6 +190,11 @@ namespace LHCb {
       addBank( sourceID, bankType, version, make_span( data ) );
     }
 
+    template <typename ValueType, auto N>
+    void addBank( int sourceID, RawBank::BankType bankType, int version, const std::array<ValueType, N>& data ) {
+      addBank( sourceID, bankType, version, make_span( data ) );
+    }
+
     /// For offline use only: copy data into a bank, adding bank header internally.
     void addBank( const RawBank* data ); // Pointer to data block (payload) of bank
 
diff --git a/Event/HltEvent/include/Event/HltObjectSummary.h b/Event/HltEvent/include/Event/HltObjectSummary.h
index db38d643a560180fd8d4d3cced97dc519cbdd542..856f71e80b59e06f4683ab24e2cfbc413e72ecb0 100644
--- a/Event/HltEvent/include/Event/HltObjectSummary.h
+++ b/Event/HltEvent/include/Event/HltObjectSummary.h
@@ -56,7 +56,7 @@ namespace LHCb {
     typedef GaudiUtils::VectorMap<std::string, float> Info;
 
     /// Default Constructor
-    HltObjectSummary() : m_lhcbIDs(), m_numericalInfo(), m_summarizedObjectCLID( 0 ), m_summarizedObject( 0 ) {}
+    HltObjectSummary() = default;
 
     // Retrieve pointer to class definition structure
     const CLID&        clID() const override;
@@ -158,13 +158,24 @@ namespace LHCb {
 
     friend std::ostream& operator<<( std::ostream& str, const HltObjectSummary& obj ) { return obj.fillStream( str ); }
 
-  protected:
+    friend bool operator==( const HltObjectSummary& lhs, const HltObjectSummary& rhs ) {
+      return lhs.m_lhcbIDs == rhs.m_lhcbIDs && lhs.m_numericalInfo == rhs.m_numericalInfo &&
+             lhs.m_summarizedObjectCLID == rhs.m_summarizedObjectCLID &&
+             lhs.m_summarizedObject == rhs.m_summarizedObject &&
+             std::equal( lhs.m_substructure.begin(), lhs.m_substructure.end(), rhs.m_substructure.begin(),
+                         rhs.m_substructure.end() ) &&
+             std::equal( lhs.m_substructureExtended.begin(), lhs.m_substructureExtended.end(),
+                         rhs.m_substructureExtended.begin(), rhs.m_substructureExtended.end() );
+    }
+    friend bool operator!=( const HltObjectSummary& lhs, const HltObjectSummary& rhs ) { return !( lhs == rhs ); }
+
+  private:
     std::vector<LHCb::LHCbID> m_lhcbIDs; ///< List of of LHCbIDs stored directly here. Not expected for obj summary with
                                          ///< a substructure. See also Flattened access method.
     Info m_numericalInfo; ///< List of numerical information from the object stored directly here. See  also Flattened
                           ///< access method.
-    unsigned int           m_summarizedObjectCLID;         ///< Class ID of the object being summarized.
-    const ContainedObject* m_summarizedObject;             ///< Pointer to the object being summarized. Non persistent.
+    unsigned int           m_summarizedObjectCLID = 0;     ///< Class ID of the object being summarized.
+    const ContainedObject* m_summarizedObject = nullptr;   ///< Pointer to the object being summarized. Non persistent.
     SmartRefVector<LHCb::HltObjectSummary> m_substructure; ///< Either pointer to subobject of the same type or pointers
                                                            ///< to objects on which this one was built ( e.g. particle
                                                            ///< daughters, tracks making the vertex etc.). See also
@@ -172,7 +183,6 @@ namespace LHCb {
     SmartRefVector<LHCb::HltObjectSummary> m_substructureExtended; ///< substructure (used in TisTos) plus any extended
                                                                    ///< substructure added for Turbo stream.
 
-  private:
   }; // class HltObjectSummary
 
   /// Definition of vector container type for HltObjectSummary
diff --git a/Event/HltEvent/include/Event/HltSelReports.h b/Event/HltEvent/include/Event/HltSelReports.h
index 029835c4b3b7ec5272a5a8f03ec4c6f6350ef8dd..190a24721dae6c31251d3ea1a453d5b5fecb1969 100644
--- a/Event/HltEvent/include/Event/HltSelReports.h
+++ b/Event/HltEvent/include/Event/HltSelReports.h
@@ -47,7 +47,7 @@ namespace LHCb {
     typedef GaudiUtils::VectorMap<std::string, LHCb::HltObjectSummary> Container;
 
     /// Default Constructor
-    HltSelReports() : m_selReports() {}
+    HltSelReports() = default;
 
     // Retrieve pointer to class definition structure
     const CLID&        clID() const override;
@@ -104,10 +104,9 @@ namespace LHCb {
 
     friend std::ostream& operator<<( std::ostream& str, const HltSelReports& obj ) { return obj.fillStream( str ); }
 
-  protected:
+  private:
     LHCb::HltSelReports::Container m_selReports; ///< container of HltObjectSummary-s keyed by trigger selection name
 
-  private:
   }; // class HltSelReports
 
 } // namespace LHCb
diff --git a/Hlt/HltDAQ/CMakeLists.txt b/Hlt/HltDAQ/CMakeLists.txt
index eba4db9b25dbddba3b406b284ca0334e7814dc00..4e4d2d1e9fde9df57a23171e0d1dc58f153711c4 100644
--- a/Hlt/HltDAQ/CMakeLists.txt
+++ b/Hlt/HltDAQ/CMakeLists.txt
@@ -51,8 +51,7 @@ gaudi_add_module(HltDAQ
         src/component/HltSelReportsDecoder.cpp
         src/component/HltSelReportsStripper.cpp
         src/component/HltSelReportsWriter.cpp
-        src/component/HltTrackReportsDecoder.cpp
-        src/component/HltTrackReportsWriter.cpp
+        src/component/HltSourceID.cpp
         src/component/HltVertexReportsDecoder.cpp
         src/component/HltVertexReportsWriter.cpp
         src/component/PackedDataBuffer.cpp
@@ -94,3 +93,5 @@ gaudi_add_executable(utestTrackingCoder
 )
 
 gaudi_add_tests(QMTest)
+
+set_property( TEST HltDAQ.b_dumpafterreformat APPEND PROPERTY DISABLED TRUE )
diff --git a/Hlt/HltDAQ/include/HltDAQ/HltSelRepRBObjTyp.h b/Hlt/HltDAQ/include/HltDAQ/HltSelRepRBObjTyp.h
index 275522049d2655c35c3c51e703e5ac6073f2b4cb..a81ab5b3aefadae29935de82d70ba81ef48c7d9f 100644
--- a/Hlt/HltDAQ/include/HltDAQ/HltSelRepRBObjTyp.h
+++ b/Hlt/HltDAQ/include/HltDAQ/HltSelRepRBObjTyp.h
@@ -39,7 +39,7 @@ namespace LHCb {
    *
    */
 
-  class HltSelRepRBObjTyp {
+  class HltSelRepRBObjTyp final {
   public:
     /// default allocation size in 32-bit words for new bank or increment in its extension
     enum DefaultAllocation { kDefaultAllocation = 50 };
@@ -47,15 +47,7 @@ namespace LHCb {
     enum InitialPositionOfIterator { kInitialPosition = 1 };
 
     /// takes pointer to the memory location of the subbank body as input
-    HltSelRepRBObjTyp( unsigned int* pBankBody )
-        : m_location( pBankBody ), m_iterator( InitialPositionOfIterator::kInitialPosition ), m_objiterator( 0 ) {}
-
-    /// Default Constructor
-    HltSelRepRBObjTyp()
-        : m_location( 0 ), m_iterator( InitialPositionOfIterator::kInitialPosition ), m_objiterator( 0 ) {}
-
-    /// Default Destructor
-    virtual ~HltSelRepRBObjTyp() {}
+    explicit HltSelRepRBObjTyp( unsigned int* pBankBody = nullptr ) : m_location( pBankBody ) {}
 
     /// Number of Object Types in the sub-banks
     unsigned int numberOfObjTyp() const;
@@ -110,15 +102,15 @@ namespace LHCb {
 
     friend std::ostream& operator<<( std::ostream& str, const HltSelRepRBObjTyp& obj ) { return obj.fillStream( str ); }
 
-  protected:
   private:
     /// throw exception on access to non-allocated bank
     void noBank() const;
 
-    unsigned int* m_location;    ///< Location of the subbank body in the program memory
-    unsigned int  m_iterator;    ///< internal iterator - gives current position in number of long word
-    unsigned int  m_objiterator; ///< internal object iterator - gives current object count (used in association with
-                                 ///< iterator)
+    unsigned int* m_location = nullptr; ///< Location of the subbank body in the program memory
+    unsigned int  m_iterator = InitialPositionOfIterator::kInitialPosition; ///< internal iterator - gives current
+                                                                            ///< position in number of long word
+    unsigned int m_objiterator = 0; ///< internal object iterator - gives current object count (used in association with
+                                    ///< iterator)
 
   }; // class HltSelRepRBObjTyp
 
@@ -157,7 +149,6 @@ inline unsigned int LHCb::HltSelRepRBObjTyp::iterator() const { return m_iterato
 inline unsigned int LHCb::HltSelRepRBObjTyp::objiterator() const { return m_objiterator; }
 
 inline unsigned int LHCb::HltSelRepRBObjTyp::numberOfObjTyp() const {
-
   noBank();
   return (unsigned int)( m_location[0] & 0xFFFFL );
 }
@@ -211,7 +202,6 @@ inline unsigned int LHCb::HltSelRepRBObjTyp::next() {
 }
 
 inline void LHCb::HltSelRepRBObjTyp::rewind() {
-
   m_iterator    = InitialPositionOfIterator::kInitialPosition;
   m_objiterator = 0;
 }
@@ -221,10 +211,7 @@ inline unsigned int LHCb::HltSelRepRBObjTyp::size() const { return ( numberOfObj
 inline void LHCb::HltSelRepRBObjTyp::push_back( unsigned int clid ) {
 
   // allocate new bank if neccessary
-  if ( !m_location ) {
-    unsigned int len = DefaultAllocation::kDefaultAllocation;
-    initialize( len );
-  }
+  if ( !m_location ) initialize( DefaultAllocation::kDefaultAllocation );
 
   // re-locate the bank body if necessary
   unsigned int aSize = allocatedSize();
@@ -305,7 +292,6 @@ inline std::ostream& LHCb::HltSelRepRBObjTyp::fillStream( std::ostream& s ) cons
 }
 
 inline void LHCb::HltSelRepRBObjTyp::noBank() const {
-
   if ( !m_location )
     throw GaudiException( "Accessing non-allocated bank in HltSelRepRBObjTyp", "HltSelRepRBObjTyp",
                           StatusCode::FAILURE );
diff --git a/Hlt/HltDAQ/include/HltDAQ/HltSelRepRawBank.h b/Hlt/HltDAQ/include/HltDAQ/HltSelRepRawBank.h
index 451324567c9e98874238086efe74b9d2ed160fff..3139ec30c8f0d44fed393609fcac881a9830fb02 100644
--- a/Hlt/HltDAQ/include/HltDAQ/HltSelRepRawBank.h
+++ b/Hlt/HltDAQ/include/HltDAQ/HltSelRepRawBank.h
@@ -40,7 +40,7 @@ namespace LHCb {
    *
    */
 
-  class HltSelRepRawBank {
+  class HltSelRepRawBank final {
   public:
     /// positions of words in the header
     enum Header { kAllocatedSize = 0, kSubBankIDs = 1, kSubBankLocations = 2, kHeaderSize = 10 };
@@ -48,13 +48,7 @@ namespace LHCb {
     enum DefaultAllocation { kDefaultAllocation = 3000 };
 
     /// takes pointer to the memory location of the bank body as input
-    HltSelRepRawBank( unsigned int* pBankBody ) : m_location( pBankBody ) {}
-
-    /// Default Constructor
-    HltSelRepRawBank() : m_location( 0 ) {}
-
-    /// Default Destructor
-    virtual ~HltSelRepRawBank() {}
+    HltSelRepRawBank( unsigned int* pBankBody = nullptr ) : m_location( pBankBody ) {}
 
     /// throw exception if no Bank or index invalid
     void validateIndex( unsigned int iBank ) const;
@@ -133,7 +127,7 @@ namespace LHCb {
     /// word)
     unsigned int subBankEnd( unsigned int iBank ) const;
 
-    unsigned int* m_location; ///< Location of the bank body in the program memory
+    unsigned int* m_location = nullptr; ///< Location of the bank body in the program memory
 
   }; // class HltSelRepRawBank
 
@@ -328,7 +322,6 @@ inline void LHCb::HltSelRepRawBank::push_back( unsigned int idSubBank, const uns
 }
 
 inline void LHCb::HltSelRepRawBank::deleteBank() {
-
   delete[] m_location;
   m_location = nullptr;
 }
diff --git a/Hlt/HltDAQ/src/component/HltDecReportsDecoder.cpp b/Hlt/HltDAQ/src/component/HltDecReportsDecoder.cpp
index 577217956277f19a388cc09eb1ccc26d2513e2bb..0a8029efba3a05632a8e7fbadda0e24d018a2f79 100644
--- a/Hlt/HltDAQ/src/component/HltDecReportsDecoder.cpp
+++ b/Hlt/HltDAQ/src/component/HltDecReportsDecoder.cpp
@@ -10,7 +10,6 @@
 \*****************************************************************************/
 #include "Event/HltDecReport.h"
 #include "Event/HltDecReports.h"
-#include "HltDecReportsWriter.h"
 #include "HltRawBankDecoderBase.h"
 
 //-----------------------------------------------------------------------------
@@ -39,8 +38,20 @@ public:
 private:
   enum HeaderIDs { kVersionNumber = 2 };
 
-  template <typename HDRConverter, typename I, typename Table>
-  int decodeHDR( I i, I end, LHCb::HltDecReports& output, const Table& table ) const;
+  template <typename HDRConverter, typename Range, typename Table>
+  int decodeHDR( HDRConverter converter, Range& input, LHCb::HltDecReports& output, const Table& table ) const;
+
+  mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_bad_version{
+      this,
+      " HltDecReports RawBank version # is larger then the known ones.... cannot decode, use newer software version. "};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_no_key{
+      this, " No string key found for trigger decision in storage", 50};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_duplicate_key{
+      this, " Duplicate string key found for trigger decision in storage", 50};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_multiple_banks{
+      this,
+      " More then one HltDecReports RawBanks for requested SourceID in RawEvent. Will only process the first one. ",
+      20};
 };
 
 // Declaration of the Algorithm Factory
@@ -63,7 +74,7 @@ namespace {
   // stage:     0x        e                   xxx0
   // id:        0xffff 0000
   struct v0_v1 {
-    HltDecReport convert( unsigned int x ) const {
+    HltDecReport operator()( unsigned int x ) const {
       // ID & decision stay the same
       unsigned int temp = ( x & 0xffff0001 );
       // stage needs to be moved left
@@ -78,9 +89,16 @@ namespace {
   };
 
   struct vx_vx {
-    HltDecReport convert( unsigned int x ) const { return HltDecReport( x ); }
+    HltDecReport operator()( unsigned int x ) const { return HltDecReport( x ); }
   };
 
+  template <typename T>
+  auto pop( LHCb::span<T>& s ) {
+    auto d = s.front();
+    s      = s.subspan( 1 );
+    return d;
+  }
+
 } // namespace
 
 //=============================================================================
@@ -98,22 +116,12 @@ HltDecReportsDecoder::HltDecReportsDecoder( const std::string& name, ISvcLocator
 //=============================================================================
 LHCb::HltDecReports HltDecReportsDecoder::operator()( const LHCb::RawEvent& rawEvent ) const {
 
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg;
-
-  // create output container
-  HltDecReports outputSummary;
-
   auto hltdecreportsRawBanks = selectRawBanks( rawEvent.banks( RawBank::HltDecReports ) );
   if ( hltdecreportsRawBanks.empty() ) {
     throw GaudiException( " No HltDecReports RawBank -- continuing, but not producing HltDecReports", name(),
                           StatusCode::SUCCESS );
   }
-  if ( hltdecreportsRawBanks.size() != 1 ) {
-    Warning(
-        " More then one HltDecReports RawBanks for requested SourceID in RawEvent. Will only process the first one. ",
-        StatusCode::SUCCESS, 20 )
-        .ignore();
-  }
+  if ( hltdecreportsRawBanks.size() != 1 ) ++m_multiple_banks;
   const RawBank* hltdecreportsRawBank = hltdecreportsRawBanks.front();
   if ( hltdecreportsRawBank->magic() != RawBank::MagicPattern ) {
     throw GaudiException( " HltDecReports RawBank has wrong magic number. Return without decoding.", name(),
@@ -126,12 +134,14 @@ LHCb::HltDecReports HltDecReportsDecoder::operator()( const LHCb::RawEvent& rawE
   }
 
   // ----------------------------------------------------------
-  const unsigned int* content = hltdecreportsRawBank->begin<unsigned int>();
+  auto data = hltdecreportsRawBank->range<unsigned int>();
 
+  // create output container
+  HltDecReports outputSummary;
   // version 0 has only decreps, version 1 has TCK, taskID, then decreps...
   if ( hltdecreportsRawBank->version() > 0 ) {
-    outputSummary.setConfiguredTCK( *content++ );
-    outputSummary.setTaskID( *content++ );
+    outputSummary.setConfiguredTCK( pop( data ) );
+    outputSummary.setTaskID( pop( data ) );
   }
   // --------------------------------- get configuration --------------------
   unsigned int tck = outputSummary.configuredTCK();
@@ -141,16 +151,14 @@ LHCb::HltDecReports HltDecReportsDecoder::operator()( const LHCb::RawEvent& rawE
   int err = 0;
   switch ( hltdecreportsRawBank->version() ) {
   case 0:
-    err += this->decodeHDR<v0_v1>( content, hltdecreportsRawBank->end<unsigned int>(), outputSummary, tbl );
+    err += this->decodeHDR( v0_v1{}, data, outputSummary, tbl );
     break;
   case 1:
   case 2:
-    err += this->decodeHDR<vx_vx>( content, hltdecreportsRawBank->end<unsigned int>(), outputSummary, tbl );
+    err += this->decodeHDR( vx_vx{}, data, outputSummary, tbl );
     break;
   default:
-    Error( " HltDecReports RawBank version # is larger then the known ones.... cannot decode, use newer version. ",
-           StatusCode::FAILURE )
-        .ignore();
+    ++m_bad_version;
     err += 1;
   }
 
@@ -165,23 +173,19 @@ LHCb::HltDecReports HltDecReportsDecoder::operator()( const LHCb::RawEvent& rawE
   return outputSummary;
 }
 
-template <typename HDRConverter, typename I, typename Table>
-int HltDecReportsDecoder::decodeHDR( I i, I end, HltDecReports& output, const Table& table ) const {
-  int                ret = 0;
-  const HDRConverter converter{};
-  while ( i != end ) {
-    auto dec  = converter.convert( *i++ );
+template <typename HDRConverter, typename R, typename Table>
+int HltDecReportsDecoder::decodeHDR( HDRConverter converter, R& input, HltDecReports& output,
+                                     const Table& table ) const {
+  int ret = 0;
+  while ( !input.empty() ) {
+    auto dec  = converter( pop( input ) );
     auto isel = table.find( dec.intDecisionID() );
     if ( isel == std::end( table ) ) { // oops missing.
-      Error( " No string key found for trigger decision in storage id = " + std::to_string( dec.intDecisionID() ),
-             StatusCode::FAILURE, 50 )
-          .ignore();
+      ++m_no_key;
       ++ret;
     } else if ( !!isel->second ) { // has a non-zero string -- insert!!
-      // debug() << " adding " << id << " as " << isel->second << endmsg;
       if ( !output.insert( isel->second, dec ).isSuccess() ) {
-        Error( " Duplicate decision report in storage " + std::string( isel->second ), StatusCode::FAILURE, 20 )
-            .ignore();
+        ++m_duplicate_key;
         ++ret;
       }
     } // otherwise, present, but should be skipped
diff --git a/Hlt/HltDAQ/src/component/HltDecReportsWriter.cpp b/Hlt/HltDAQ/src/component/HltDecReportsWriter.cpp
index e78da8fcfcb9fd400d964bf189756ffa4442cd91..cfcb61e8470da832211e4278b5bc65e009cd6f65 100644
--- a/Hlt/HltDAQ/src/component/HltDecReportsWriter.cpp
+++ b/Hlt/HltDAQ/src/component/HltDecReportsWriter.cpp
@@ -8,13 +8,10 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-
 #include "Event/HltDecReports.h"
 #include "Event/RawEvent.h"
-
-// local
-#include "HltDecReportsWriter.h"
+#include "HltSourceID.h"
+#include "LHCbAlgs/Consumer.h"
 
 //-----------------------------------------------------------------------------
 // Implementation file for class : HltDecReportsWriter
@@ -22,89 +19,97 @@
 // 2008-07-26 : Tomasz Skwarnicki
 //-----------------------------------------------------------------------------
 
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT( HltDecReportsWriter )
-
-using namespace LHCb;
-
-//=============================================================================
-// Initialization
-//=============================================================================
-StatusCode HltDecReportsWriter::initialize() {
-  auto sc = GaudiAlgorithm::initialize(); // must be executed first
-  if ( sc.isFailure() ) return sc;        // error printed already by GaudiAlgorithm
-
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg;
-
-  if ( m_sourceID > kSourceID_Max || m_sourceID < 0 ) {
-    return Error( "Illegal SourceID specified; maximal allowed value is 7", StatusCode::FAILURE );
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-// Main execution
-//=============================================================================
-StatusCode HltDecReportsWriter::execute() {
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg;
-
-  // get input
-  const auto inputSummary = getIfExists<HltDecReports>( m_inputHltDecReportsLocation );
-  if ( !inputSummary ) {
-    return Warning( " No HltDecReports at " + m_inputHltDecReportsLocation.value(), StatusCode::SUCCESS, 20 );
-  }
-  if ( msgLevel( MSG::VERBOSE ) ) {
-    verbose() << " Input: ";
-    for ( const auto& rep : *inputSummary ) {
-      auto decRep = HltDecReport{rep.second.decReport()};
-      verbose() << decRep.intDecisionID() << "-" << decRep.decision() << " ";
-    }
-    verbose() << endmsg;
-  }
-
-  // get output
-  auto rawEvent = m_outputRawEvent.getOrCreate();
-
-  // delete any previously inserted dec reports
-  // note that we need to _copy_ the list of banks, as the original will be modified while
-  // we're looping over the list...
-  const auto& bnks = rawEvent->banks( RawBank::HltDecReports );
-  for ( const LHCb::RawBank* b : std::vector( bnks.begin(), bnks.end() ) ) {
-    auto sourceID = b->version() > 1 ? ( b->sourceID() >> kSourceID_BitShift ) : kSourceID_Hlt;
-    if ( m_sourceID != sourceID ) continue;
-    rawEvent->removeBank( b );
-    Warning( " Deleted previously inserted HltDecReports bank ", StatusCode::SUCCESS, 20 ).ignore();
-  }
-
-  // compose the bank body
-  std::vector<unsigned int> bankBody;
-  bankBody.reserve( inputSummary->size() + 2 );
-  bankBody.push_back( inputSummary->configuredTCK() );
-  bankBody.push_back( inputSummary->taskID() );
-  std::transform( std::begin( *inputSummary ), std::end( *inputSummary ), std::back_inserter( bankBody ),
-                  []( HltDecReports::Container::const_reference r ) { return r.second.decReport(); } );
-
-  // order according to the values, essentially orders by intDecisionID
-  // this is important since it will put "*Global" reports at the beginning of the bank
-  // NOTE: we must skip the first two words (configuredTCK, taskID)
-  std::sort( std::next( std::begin( bankBody ), 2 ), std::end( bankBody ) );
-
-  // shift bits in sourceID for the same convention as in HltSelReports
-  rawEvent->addBank( int( m_sourceID << kSourceID_BitShift ), RawBank::HltDecReports, kVersionNumber, bankBody );
-
-  if ( msgLevel( MSG::VERBOSE ) ) {
-    verbose() << " Output:  ";
-    verbose() << " VersionNumber= " << kVersionNumber;
-    verbose() << " SourceID= " << m_sourceID;
-    auto i = std::begin( bankBody );
-    verbose() << " configuredTCK = " << *i++ << " ";
-    verbose() << " taskID = " << *i++ << " ";
-    for ( ; i != std::end( bankBody ); ++i ) {
-      auto rep = HltDecReport{*i};
-      verbose() << rep.intDecisionID() << "-" << rep.decision() << " ";
+/** @class DecReportsWriter HltDecReportsWriter.h
+ *
+ *
+ *  @author Tomasz Skwarnicki
+ *  @date   2008-07-26
+ *
+ *  Algorithm to convert HltDecReports container on TES to HLT Raw Bank
+ *
+ */
+
+namespace LHCb::Hlt::DAQ {
+
+  class DecReportsWriter : public Algorithm::Consumer<void( HltDecReports const& )> {
+    /// location of output -- as it (potentially) updated 'in-situ' we use an explicit datahandle...
+    DataObjectWriteHandle<RawEvent> m_outputRawEvent{this, "OutputRawEventLocation", RawEventLocation::Default};
+
+    /// SourceID to insert in the bank header
+    Gaudi::Property<SourceID> m_sourceID{this, "SourceID", SourceID::Dummy};
+
+    mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_removed_old_banks{
+        this, " Deleted previously inserted HltDecReports bank ", 50};
+
+  public:
+    enum HeaderIDs { kVersionNumber = 2 };
+
+    DecReportsWriter( const std::string& name, ISvcLocator* pSvcLocator )
+        : Consumer{name, pSvcLocator, KeyValue{"InputHltDecReportsLocation", HltDecReportsLocation::Default}} {}
+
+    void operator()( HltDecReports const& inputSummary ) const override {
+
+      assert( m_sourceID == SourceIDs::Hlt1 || m_sourceID == SourceIDs::Hlt2 || m_sourceID == SourceIDs::Spruce );
+      if ( msgLevel( MSG::VERBOSE ) ) {
+        verbose() << " Input: ";
+        for ( const auto& rep : inputSummary ) {
+          auto decRep = HltDecReport{rep.second.decReport()};
+          verbose() << decRep.intDecisionID() << "-" << decRep.decision() << " ";
+        }
+        verbose() << endmsg;
+      }
+
+      // get output
+      auto rawEvent = m_outputRawEvent.getOrCreate();
+
+      // delete any previously inserted dec reports
+      // note that we need to _copy_ the list of banks, as the original will be modified while
+      // we're looping over the list...
+      const auto& bnks = rawEvent->banks( RawBank::HltDecReports );
+      for ( const RawBank* b : std::vector( bnks.begin(), bnks.end() ) ) {
+        auto sourceID = b->version() > 1 ? static_cast<SourceID>( b->sourceID() >> SourceID::BitShift ) : SourceID::Hlt;
+        if ( m_sourceID != sourceID ) continue;
+        rawEvent->removeBank( b );
+        ++m_removed_old_banks;
+      }
+
+      // compose the bank body
+      std::vector<unsigned int> bankBody;
+      bankBody.reserve( inputSummary.size() + 2 );
+      bankBody.push_back( inputSummary.configuredTCK() );
+      bankBody.push_back( inputSummary.taskID() );
+      std::transform( std::begin( inputSummary ), std::end( inputSummary ), std::back_inserter( bankBody ),
+                      []( const auto& r ) { return r.second.decReport(); } );
+
+      // order according to the values, essentially orders by intDecisionID
+      // this is important since it will put "*Global" reports at the beginning of the bank
+      // NOTE: we must skip the first two words (configuredTCK, taskID)
+      std::sort( std::next( std::begin( bankBody ), 2 ), std::end( bankBody ) );
+
+      // shift bits in sourceID for the same convention as in HltSelReports
+      rawEvent->addBank( int( m_sourceID << SourceID::BitShift ), RawBank::HltDecReports, kVersionNumber, bankBody );
+
+      if ( msgLevel( MSG::VERBOSE ) ) {
+        verbose() << " Output:  ";
+        verbose() << " VersionNumber= " << kVersionNumber;
+        verbose() << " SourceID= " << m_sourceID.value();
+        auto i = std::begin( bankBody );
+        verbose() << " configuredTCK = " << *i++ << " ";
+        verbose() << " taskID = " << *i++ << " ";
+        while ( i != std::end( bankBody ) ) {
+          auto rep = HltDecReport{*i++};
+          verbose() << rep.intDecisionID() << "-" << rep.decision() << " ";
+        }
+        verbose() << endmsg;
+      }
+      // return rawEvent->banks( RawBank::HltDecReports ); // FIXME this is _not_ save when a _subsequent_ algorithm
+      // calls
+      //                                                  // addBank,adoptBank or removeBank on the underlying
+      //                                                  RawEvent...
     }
-    verbose() << endmsg;
-  }
-  return StatusCode::SUCCESS;
-}
+  };
+
+  // Declaration of the Algorithm Factory
+  DECLARE_COMPONENT_WITH_ID( DecReportsWriter, "HltDecReportsWriter" )
+
+} // namespace LHCb::Hlt::DAQ
diff --git a/Hlt/HltDAQ/src/component/HltDecReportsWriter.h b/Hlt/HltDAQ/src/component/HltDecReportsWriter.h
deleted file mode 100644
index ef1e27f0b078766bf03c8ba20877d8ed371a6de2..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltDecReportsWriter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTDECREPORTSWRITER_H
-#define HLTDECREPORTSWRITER_H 1
-
-#include "Event/HltDecReports.h"
-#include "Event/RawEvent.h"
-
-#include "GaudiAlg/GaudiAlgorithm.h"
-
-/** @class HltDecReportsWriter HltDecReportsWriter.h
- *
- *
- *  @author Tomasz Skwarnicki
- *  @date   2008-07-26
- *
- *  Algorithm to convert HltDecReports container on TES to HLT Raw Bank
- *
- */
-class HltDecReportsWriter : public GaudiAlgorithm {
-public:
-  enum HeaderIDs { kVersionNumber = 2 };
-
-  enum SourceIDs {
-    kSourceID_Dummy     = 0,
-    kSourceID_Hlt       = kSourceID_Dummy,
-    kSourceID_Hlt1      = 1,
-    kSourceID_Hlt2      = 2,
-    kSourceID_Max       = 7,
-    kSourceID_BitShift  = 13,
-    kSourceID_MinorMask = 0x1FFF,
-    kSourceID_MajorMask = 0xE000
-  };
-
-  /// Standard constructor
-  using GaudiAlgorithm::GaudiAlgorithm;
-
-  StatusCode initialize() override; ///< Algorithm initialization
-  StatusCode execute() override;    ///< Algorithm execution
-
-private:
-  /// location of input
-  Gaudi::Property<std::string> m_inputHltDecReportsLocation{this, "InputHltDecReportsLocation",
-                                                            LHCb::HltDecReportsLocation::Default};
-
-  /// location of output
-  DataObjectWriteHandle<LHCb::RawEvent> m_outputRawEvent{this, "OutputRawEventLocation",
-                                                         LHCb::RawEventLocation::Default};
-
-  /// SourceID to insert in the bank header
-  Gaudi::Property<int> m_sourceID{this, "SourceID", kSourceID_Dummy};
-};
-#endif // HLTDECREPORTSWRITER_H
diff --git a/Hlt/HltDAQ/src/component/HltDiffHltDecReports.cpp b/Hlt/HltDAQ/src/component/HltDiffHltDecReports.cpp
index e241686a95c87a298cb88d77fc14a62a6b3d0623..3c4ffe911217d27edd6f6d7755025983820d8dbb 100644
--- a/Hlt/HltDAQ/src/component/HltDiffHltDecReports.cpp
+++ b/Hlt/HltDAQ/src/component/HltDiffHltDecReports.cpp
@@ -8,74 +8,47 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-// from Gaudi
 #include "Event/HltDecReports.h"
-#include "GaudiAlg/GaudiAlgorithm.h"
-#include <iterator>
-
-class HltDiffHltDecReports : public GaudiAlgorithm {
-public:
-  /// Standard constructor
-  HltDiffHltDecReports( const std::string& name, ISvcLocator* pSvcLocator );
-  ~HltDiffHltDecReports() override = default; ///< Destructor
-  StatusCode execute() override;              ///< Algorithm execution
-private:
-  std::string m_lhs;
-  std::string m_rhs;
-};
-
+#include "LHCbAlgs/Consumer.h"
 //-----------------------------------------------------------------------------
 // Implementation file for class : HltDiffHltDecReports
 //
 // 2009-05-26 : Gerhard Raven
 //-----------------------------------------------------------------------------
 
-DECLARE_COMPONENT( HltDiffHltDecReports )
+struct HltDiffHltDecReports
+    : LHCb::Algorithm::Consumer<void( LHCb::HltDecReports const&, LHCb::HltDecReports const& )> {
 
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-HltDiffHltDecReports::HltDiffHltDecReports( const std::string& name, ISvcLocator* pSvcLocator )
-    : GaudiAlgorithm( name, pSvcLocator ) {
-  declareProperty( "HltDecReportsLHS", m_lhs );
-  declareProperty( "HltDecReportsRHS", m_rhs );
-}
+  HltDiffHltDecReports( const std::string& name, ISvcLocator* pSvcLocator )
+      : Consumer{name, pSvcLocator, {KeyValue{"HltDecReportsLHS", ""}, KeyValue{"HltDecReportsRHS", ""}}} {}
 
-//=============================================================================
-// Main execution
-//=============================================================================
-
-StatusCode HltDiffHltDecReports::execute() {
-  // grab the two reports...
-  auto lhs = get<LHCb::HltDecReports>( m_lhs );
-  auto rhs = get<LHCb::HltDecReports>( m_rhs );
-
-  if ( lhs->configuredTCK() != rhs->configuredTCK() ) {
-    always() << " configuredTCK: " << m_lhs << " : " << lhs->configuredTCK() << m_rhs << " : " << rhs->configuredTCK()
-             << endmsg;
-  }
-
-  auto l = lhs->begin(), r = rhs->begin();
-  while ( l != lhs->end() || r != rhs->end() ) {
-    auto rend = ( r == rhs->end() );
-    auto lend = ( l == lhs->end() );
-
-    if ( !lend && ( rend || l->first < r->first ) ) {
-      always() << " only in " << m_lhs << " : " << l->first << " : " << l->second << endmsg;
-      ++l;
-    } else if ( !rend && ( lend || r->first < l->first ) ) {
-      always() << " only in " << m_rhs << " : " << r->first << " : " << r->second << endmsg;
-      ++r;
-    } else {
-      if ( l->second.decReport() != r->second.decReport() ) {
-        always() << " dif: " << l->first << " : " << l->second << "  <-> " << r->second << endmsg;
+  void operator()( LHCb::HltDecReports const& lhs, LHCb::HltDecReports const& rhs ) const override {
+    if ( lhs.configuredTCK() != rhs.configuredTCK() ) {
+      always() << " configuredTCK: " << inputLocation<0>() << " : " << lhs.configuredTCK() << inputLocation<1>()
+               << " : " << rhs.configuredTCK() << endmsg;
+    }
+    auto l = lhs.begin(), r = rhs.begin();
+    while ( l != lhs.end() || r != rhs.end() ) {
+      auto rend = ( r == rhs.end() );
+      auto lend = ( l == lhs.end() );
+
+      if ( !lend && ( rend || l->first < r->first ) ) {
+        always() << " only in " << inputLocation<0>() << " : " << l->first << " : " << l->second << endmsg;
+        ++l;
+      } else if ( !rend && ( lend || r->first < l->first ) ) {
+        always() << " only in " << inputLocation<1>() << " : " << r->first << " : " << r->second << endmsg;
+        ++r;
       } else {
-        // always() << " match: " << l->first << " : " << l->second << endmsg;
+        if ( l->second.decReport() != r->second.decReport() ) {
+          always() << " diff: " << l->first << " : " << l->second << "  <-> " << r->second << endmsg;
+        } else {
+          // always() << " match: " << l->first << " : " << l->second << endmsg;
+        }
+        ++l;
+        ++r;
       }
-      ++l;
-      ++r;
     }
   }
-  return StatusCode::SUCCESS;
-}
+};
+
+DECLARE_COMPONENT( HltDiffHltDecReports )
diff --git a/Hlt/HltDAQ/src/component/HltLumiWriter.cpp b/Hlt/HltDAQ/src/component/HltLumiWriter.cpp
index 5a003b276e67ddffba0b3d99024f2a48e47fb2b1..94575e875dd99fb8c5d5822a80155bf0b7a8f316 100644
--- a/Hlt/HltDAQ/src/component/HltLumiWriter.cpp
+++ b/Hlt/HltDAQ/src/component/HltLumiWriter.cpp
@@ -8,109 +8,71 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-// local
-#include "HltLumiWriter.h"
 #include "Event/HltLumiSummary.h"
 #include "Event/LumiCounters.h"
+#include "Event/RawEvent.h"
+#include "Kernel/STLExtensions.h"
+#include "LHCbAlgs/Transformer.h"
 
 //-----------------------------------------------------------------------------
 // Implementation file for class : HltLumiWriter
 //
-// 2008-07-22 : Jaap Panman (using the calo as template)
 //-----------------------------------------------------------------------------
 
-DECLARE_COMPONENT( HltLumiWriter )
-
-//=============================================================================
-// Initialization
-//=============================================================================
-StatusCode HltLumiWriter::initialize() {
-  StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first
-  if ( sc.isFailure() ) return sc;              // error printed already by GaudiAlgorithm
-
-  debug() << "==> Initialize" << endmsg;
-
-  m_nbEvents    = 0;
-  m_totDataSize = 0;
-  m_bank.reserve( 20 );
-  m_bankType = LHCb::RawBank::HltLumiSummary;
-
-  return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-// Main execution
-//=============================================================================
-StatusCode HltLumiWriter::execute() {
-
-  debug() << "==> Execute" << endmsg;
-
-  m_bank.clear();
-
-  //== Build the data banks
-  fillDataBankShort();
-
-  int totDataSize = 0;
-
-  auto rawEvent = m_outputRawEvent.getOrCreate();
-
-  // set source, type, version
-  rawEvent->addBank( 0, m_bankType, 0, m_bank );
-  totDataSize += m_bank.size();
-
-  m_totDataSize += totDataSize;
-  m_nbEvents++;
-
-  if ( msgLevel( MSG::DEBUG ) ) {
-    debug() << "Bank size: " << format( "%4d ", m_bank.size() ) << "Total Data bank size " << totDataSize << endmsg;
-  }
+/** @class HltLumiWriter HltLumiWriter.h
+ *  Fills the Raw Buffer banks for the LumiSummary
+ */
+class HltLumiWriter : public LHCb::Algorithm::Transformer<LHCb::RawBank::View( const LHCb::HltLumiSummary& )> {
+
+  DataObjectWriteHandle<LHCb::RawEvent> m_outputRawEvent{this, "RawEventLocation", LHCb::RawEventLocation::Default};
+  mutable Gaudi::Accumulators::AveragingCounter<> m_totDataSize{this, "Average event size / 32-bit words"};
+
+public:
+  HltLumiWriter( const std::string& name, ISvcLocator* pSvcLocator )
+      : Transformer{name, pSvcLocator, KeyValue{"InputBank", LHCb::HltLumiSummaryLocation::Default},
+                    KeyValue{"OutputBank", "DAQ/RawBanks/HltLumiSummary"}} {}
+
+  //=============================================================================
+  // Main execution
+  //  Fill the data bank, structure: Key (upper 16 bits) + value
+  //=============================================================================
+  LHCb::RawBank::View operator()( const LHCb::HltLumiSummary& summary ) const override {
+
+    std::vector<unsigned int> bank;
+    bank.reserve( 20 );
+    for ( const auto& info : summary.extraInfo() ) {
+      bank.push_back( ( std::min( info.first, 0xFFFF ) << 16 ) | ( std::min( info.second, 0xFFFF ) & 0xFFFF ) );
+      if ( msgLevel( MSG::VERBOSE ) ) {
+        auto word = bank.back();
+        verbose() << format( " %8x %11d %11d %11d ", word, word, word >> 16, word & 0xFFFF ) << endmsg;
+      }
+    }
 
-  if ( MSG::VERBOSE >= msgLevel() ) {
-    verbose() << "DATA bank : " << endmsg;
-    int kl = 0;
-    for ( const auto& w : m_bank ) {
-      verbose() << format( " %8x %11d   ", w, w );
-      if ( ++kl % 4 == 0 ) verbose() << endmsg;
+    auto rawEvent = m_outputRawEvent.getOrCreate();
+    if ( !rawEvent->banks( LHCb::RawBank::HltLumiSummary ).empty() ) {
+      throw std::runtime_error( "RawEvent already contains HltLumiSummary raw bank" );
     }
-    verbose() << endmsg;
-  }
 
-  return StatusCode::SUCCESS;
-}
+    // set source, type, version
+    rawEvent->addBank( 0, LHCb::RawBank::HltLumiSummary, 0, bank );
 
-//=============================================================================
-//  Finalize
-//=============================================================================
-StatusCode HltLumiWriter::finalize() {
+    m_totDataSize += bank.size();
 
-  if ( m_nbEvents > 0 ) {
-    m_totDataSize /= m_nbEvents;
-    info() << format( "Average event size : %7.1f words", m_totDataSize ) << endmsg;
-  }
-  return GaudiAlgorithm::finalize(); // must be called after all other actions
-}
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "Bank size: " << format( "%4d ", bank.size() ) << "Total Data bank size " << bank.size() << endmsg;
+    }
 
-//=========================================================================
-//  Fill the data bank, structure: Key (upper 16 bits) + value
-//=========================================================================
-void HltLumiWriter::fillDataBankShort() {
+    if ( msgLevel( MSG::VERBOSE ) ) {
+      verbose() << "DATA bank : " << endmsg;
+      for ( const auto& [k, w] : LHCb::range::enumerate( bank, 1 ) ) {
+        verbose() << format( " %8x %11d   ", w, w );
+        if ( k % 4 == 0 ) verbose() << endmsg;
+      }
+      verbose() << endmsg;
+    }
 
-  LHCb::HltLumiSummary* HltLumiSummary = getIfExists<LHCb::HltLumiSummary>( m_inputBank );
-  if ( !HltLumiSummary ) {
-    debug() << m_inputBank << " not found" << endmsg;
-    return;
+    return rawEvent->banks( LHCb::RawBank::HltLumiSummary );
   }
-  debug() << m_inputBank << " found" << endmsg;
+};
 
-  // handle overflow
-  auto i_value = []( int s ) { return ( s < 0xFFFF ) ? (int)s : (int)0xFFFF; };
-  for ( const auto& summaryIter : HltLumiSummary->extraInfo() ) {
-    m_bank.push_back( ( summaryIter.first << 16 ) | ( i_value( summaryIter.second ) & 0xFFFF ) );
-    if ( MSG::VERBOSE >= msgLevel() ) {
-      auto word = m_bank.back();
-      verbose() << format( " %8x %11d %11d %11d ", word, word, word >> 16, word & 0xFFFF ) << endmsg;
-    }
-  }
-}
-//=============================================================================
+DECLARE_COMPONENT( HltLumiWriter )
diff --git a/Hlt/HltDAQ/src/component/HltLumiWriter.h b/Hlt/HltDAQ/src/component/HltLumiWriter.h
deleted file mode 100644
index 67af4ec3738d817d6df09ce30a4c51b295ac93fa..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltLumiWriter.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTLUMIWRITER_H
-#define HLTLUMIWRITER_H 1
-
-#include "Event/HltLumiSummary.h"
-#include "Event/RawEvent.h"
-
-#include "GaudiAlg/GaudiAlgorithm.h"
-
-/** @class HltLumiWriter HltLumiWriter.h
- *  Fills the Raw Buffer banks for the LumiSummary
- *
- *  @author Jaap Panman
- *  @date   2004-07-22
- */
-class HltLumiWriter : public GaudiAlgorithm {
-public:
-  /// Standard constructor
-  using GaudiAlgorithm::GaudiAlgorithm;
-
-  StatusCode initialize() override; ///< Algorithm initialization
-  StatusCode execute() override;    ///< Algorithm execution
-  StatusCode finalize() override;   ///< Algorithm finalization
-
-private:
-  void fillDataBankShort();
-
-  Gaudi::Property<std::string>          m_inputBank = {this, "InputBank", LHCb::HltLumiSummaryLocation::Default};
-  DataObjectWriteHandle<LHCb::RawEvent> m_outputRawEvent{this, "RawEventLocation", LHCb::RawEventLocation::Default};
-
-  // Statistics
-  double                    m_totDataSize = 0;
-  int                       m_nbEvents    = 0;
-  std::vector<unsigned int> m_bank;
-  LHCb::RawBank::BankType   m_bankType = LHCb::RawBank::HltLumiSummary;
-};
-#endif // HLTLUMIWRITER_H
diff --git a/Hlt/HltDAQ/src/component/HltPackedDataDecoder.cpp b/Hlt/HltDAQ/src/component/HltPackedDataDecoder.cpp
index fffea46d633f4362fed5a6a8e0b209db59f5a36c..3735edee113bb8714d7703940586c92abe7c91d8 100644
--- a/Hlt/HltDAQ/src/component/HltPackedDataDecoder.cpp
+++ b/Hlt/HltDAQ/src/component/HltPackedDataDecoder.cpp
@@ -112,7 +112,7 @@ namespace LHCb::Hlt::PackedData {
     initRawEventSearch();
     // The default m_sourceID=0 triggers a warning in HltRawBankDecoderBase::initialize
     // Since we only care about HLT2 persistence, set it explicitly:
-    setProperty( "SourceID", kSourceID_Hlt2 ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
+    setProperty( "SourceID", SourceIDs::Hlt2 ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
     m_rawEventLocations.push_back( RawEventLocation::PersistReco );
   }
 
diff --git a/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.cpp b/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.cpp
index 04a85d364e7dfb8f646411b0ecc93dfcb0a1370c..1877ee7405ba64db222d412c6b9048fe01159a0a 100644
--- a/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.cpp
+++ b/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.cpp
@@ -14,6 +14,7 @@
 namespace {
   const Gaudi::StringKey Hlt1SelectionID{"Hlt1SelectionID"};
   const Gaudi::StringKey Hlt2SelectionID{"Hlt2SelectionID"};
+  const Gaudi::StringKey SpruceSelectionID{"SpruceSelectionID"};
   const Gaudi::StringKey InfoID{"InfoID"};
 
   unsigned int getTCK( const LHCb::RawBank* rb ) {
@@ -26,9 +27,7 @@ namespace {
 
   std::vector<const LHCb::RawBank*> selectRawBanks_( unsigned int sourceID, LHCb::RawBank::View rawbanks ) {
     auto has_sourceID = []( int id ) {
-      return [id]( const LHCb::RawBank* bank ) {
-        return id == ( bank->sourceID() >> HltRawBankDecoderBase::kSourceID_BitShift );
-      };
+      return [id]( const LHCb::RawBank* bank ) { return id == ( bank->sourceID() >> SourceIDs::BitShift ); };
     };
 
     // TODO: do we need a reqType dependent version check ???
@@ -40,10 +39,9 @@ namespace {
     // first pass didn't find the requested bank -- try to find 'unsplit' bank
     // if we find something here, we will 'partially' decode it downstream
     // (steered by the entries in the id lookup table)
-    if ( mybanks.empty() &&
-         ( sourceID == HltRawBankDecoderBase::kSourceID_Hlt1 || sourceID == HltRawBankDecoderBase::kSourceID_Hlt2 ) ) {
+    if ( mybanks.empty() && ( sourceID == SourceIDs::Hlt1 || sourceID == SourceIDs::Hlt2 ) ) {
       std::copy_if( std::begin( rawbanks ), std::end( rawbanks ), std::back_inserter( mybanks ),
-                    has_sourceID( HltRawBankDecoderBase::kSourceID_Hlt ) );
+                    has_sourceID( SourceIDs::Hlt ) );
     }
     return mybanks;
   }
@@ -54,20 +52,18 @@ StatusCode HltRawBankDecoderBase::initialize() {
   StatusCode sc = Decoder::AlgBase::initialize(); // must be executed first
 
   m_TCKANNSvc = service<IIndexedANNSvc>( "TCKANNSvc" );
-  if ( m_sourceID > kSourceID_Max ) {
-    return Error( "Illegal SourceID specified; maximal allowed value is 7", StatusCode::FAILURE, 50 );
-  }
-  if ( m_sourceID == kSourceID_Hlt ) {
-    Warning( "Hlt raw bank decoder " + name() +
-                 " is configured to decode both Hlt1 and Hlt2 into a single TES location;\n"
-                 "This configuration is deprecated as it can NOT work for data taken with a 'split' Hlt configuration, "
-                 "i.e. 2015 data and beyond\n"
-                 "Please reconfigure, and request seperate decoding of Hlt1 and Hlt2 instead.\n"
-                 "And yes, this 'split' decoding will also work for data taken with an 'unsplit' Hlt configuration, "
-                 "eg. old data taken before 2015\n"
-                 "NB: you may have to adapt your Hlt decision filtering accordingly!",
-             StatusCode::SUCCESS )
-        .ignore();
+  if ( m_sourceID == SourceIDs::Hlt ) {
+    error()
+        << "Hlt raw bank decoder " + name() +
+               " is configured to decode both Hlt1 and Hlt2 into a single TES location;\n"
+               "This configuration is deprecated as it can NOT work for data taken with a 'split' Hlt configuration, "
+               "i.e. 2015 data and beyond\n"
+               "Please reconfigure, and request seperate decoding of Hlt1 and Hlt2 instead.\n"
+               "And yes, this 'split' decoding will also work for data taken with an 'unsplit' Hlt configuration, "
+               "eg. old data taken before 2015\n"
+               "NB: you may have to adapt your Hlt decision filtering accordingly!"
+        << endmsg;
+    return StatusCode::FAILURE;
   }
   return sc;
 }
@@ -114,10 +110,21 @@ HltRawBankDecoderBase::IdTable_t::const_iterator HltRawBankDecoderBase::fetch_id
       }
     }
   };
-  bool decode_hlt1 = ( m_sourceID == kSourceID_Hlt1 || m_sourceID == kSourceID_Hlt );
-  append( Hlt1SelectionID, decode_hlt1 );
-  bool decode_hlt2 = ( m_sourceID == kSourceID_Hlt2 || m_sourceID == kSourceID_Hlt );
-  append( Hlt2SelectionID, decode_hlt2 );
+  switch ( m_sourceID.value() ) {
+  case SourceIDs::Hlt1:
+    append( Hlt1SelectionID, true );
+    break;
+  case SourceIDs::Hlt2:
+    append( Hlt2SelectionID, true );
+    break;
+  case SourceIDs::Spruce:
+    append( SpruceSelectionID, true );
+    break;
+  default:
+    fatal() << "you are reading data with Hlt source id " << m_sourceID.value() << " which was only used in run1."
+            << "this is no longer supported in this version of the code. Refusing to continue" << endmsg;
+    throw GaudiException( "Unsupport HLT sourceID", "HltRawBankDecoderBas", StatusCode::FAILURE );
+  }
   auto res = m_idTable.insert( tck, std::move( tbl ) );
   assert( res.second );
   return res.first;
diff --git a/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.h b/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.h
index f8420219ae2d37d4f6e2c3aecfc82edd590731cd..138b57dd8666e87e016e3bff9d958c2ac0285a75 100644
--- a/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.h
+++ b/Hlt/HltDAQ/src/component/HltRawBankDecoderBase.h
@@ -21,22 +21,12 @@
 #include "Event/RawEvent.h"
 #include "GaudiKernel/SmartIF.h"
 #include "GaudiKernel/VectorMap.h"
+#include "HltSourceID.h"
 #include "Kernel/IANNSvc.h"
 #include "Kernel/IIndexedANNSvc.h"
 
 class HltRawBankDecoderBase : public Decoder::AlgBase {
 public:
-  enum SourceIDs {
-    kSourceID_Dummy     = 0,
-    kSourceID_Hlt       = kSourceID_Dummy,
-    kSourceID_Hlt1      = 1,
-    kSourceID_Hlt2      = 2,
-    kSourceID_Max       = 7,
-    kSourceID_BitShift  = 13,
-    kSourceID_MinorMask = 0x1FFF,
-    kSourceID_MajorMask = 0xE000
-  };
-
   using Decoder::AlgBase::AlgBase;
 
   StatusCode initialize() override;
@@ -91,8 +81,7 @@ private:
   Table_t::const_iterator   fetch_info2string( unsigned int tck, const IANNSvc::major_key_type& major,
                                                Table_t& table ) const;
 
-  /// SourceID to decode: 0=Hlt 1=Hlt1 2=Hlt2 ... (1,2 will decode from 0 if 1,2 not found)
-  Gaudi::Property<unsigned int> m_sourceID{this, "SourceID", kSourceID_Dummy};
+  Gaudi::Property<SourceIDs> m_sourceID{this, "SourceID", SourceIDs::Dummy};
 };
 
 using HltRawBankDecoder_Setup = Gaudi::Functional::Traits::BaseClass_t<HltRawBankDecoderBase>;
diff --git a/Hlt/HltDAQ/src/component/HltRawDataMonitor.cpp b/Hlt/HltDAQ/src/component/HltRawDataMonitor.cpp
index 2eec56f04b34f3392e594e776327cd6a27a482cf..19e2406c0298ce0861b47e82d60d119fbf171ffd 100644
--- a/Hlt/HltDAQ/src/component/HltRawDataMonitor.cpp
+++ b/Hlt/HltDAQ/src/component/HltRawDataMonitor.cpp
@@ -8,36 +8,31 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-
-// from Gaudi
+#include "AIDA/IAxis.h"
+#include "AIDA/IHistogram1D.h"
+#include "Event/CaloCluster.h"
 #include "Event/HltDecReports.h"
 #include "Event/HltObjectSummary.h"
 #include "Event/HltSelReports.h"
+#include "Event/Particle.h"
 #include "Event/RawEvent.h"
+#include "Event/RecVertex.h"
+#include "Event/Track.h"
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "GaudiAlg/GaudiHistoAlg.h"
+#include "GaudiAlg/GaudiTupleAlg.h"
 #include "GaudiKernel/IMessageSvc.h"
 #include "GaudiKernel/MsgStream.h"
-
-// bank structure
 #include "HltDAQ/HltSelRepRBExtraInfo.h"
 #include "HltDAQ/HltSelRepRBHits.h"
 #include "HltDAQ/HltSelRepRBObjTyp.h"
 #include "HltDAQ/HltSelRepRBStdInfo.h"
 #include "HltDAQ/HltSelRepRBSubstr.h"
 #include "HltDAQ/HltSelRepRawBank.h"
-
-// boost
+#include "HltSourceID.h"
+#include "Kernel/IANNSvc.h"
 #include "boost/format.hpp"
 
-// local
-#include "HltRawDataMonitor.h"
-#include "HltSelReportsWriter.h"
-
-#include "Event/CaloCluster.h"
-#include "Event/Particle.h"
-#include "Event/RecVertex.h"
-#include "Event/Track.h"
-
 //-----------------------------------------------------------------------------
 // Implementation file for class : HltRawDataMonitor
 //
@@ -45,6 +40,69 @@
 // Author                        : Chun-Min Jen, jencmhep@gmail.com
 //-----------------------------------------------------------------------------
 
+/** @class HltRawDataMonitor HltRawDataMonitor.h
+ *
+ *
+ *  @author Chun-Min Jen
+ *  @date   2008-10-07
+ **/
+
+class HltRawDataMonitor : public GaudiHistoAlg {
+public:
+  enum HeaderIDs { kVersionNumber = 2 };
+
+  /// Standard constructor
+  HltRawDataMonitor( const std::string& name, ISvcLocator* pSvcLocator );
+
+  StatusCode initialize() override; ///< Algorithm initialization
+  StatusCode execute() override;    ///< Algorithm execution
+  StatusCode finalize() override;   ///< Algorithm finalization
+
+private:
+  /// location of input
+  std::string              m_inputRawEventLocation;
+  std::vector<std::string> m_rawEventLocations;
+
+  /// SourceID to decode 0=Hlt 1=Hlt1 2=Hlt2 ... (1,2 will decode from 0 if 1,2 not found)
+  Gaudi::Property<SourceIDs> m_sourceID{this, "SourceID", SourceIDs::Hlt};
+
+  /// <0 never 0=at finalize >0 event frequency
+  IntegerProperty m_diagnosticsFrequency;
+
+private:
+  typedef std::pair<std::pair<std::string, AIDA::IHistogram1D*>, double> HltSortedSelName;
+  class sort {
+  public:
+    bool operator()( const HltSortedSelName& q1, const HltSortedSelName& q2 ) const;
+  };
+
+  void fillDiag( const char* trigName, double length );
+
+  StatusCode fillRawBank();
+  StatusCode fillHltSelRep();
+  StatusCode selectionDiagnostics();
+
+  int    nLength( const LHCb::HltObjectSummary& p );
+  double nMedian( const AIDA::IHistogram1D& q );
+  double nMedian2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
+  double nMean2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
+  double nRMS2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
+
+  // lots of different sorts of histograms are declared here
+  // call/book histograms here
+  AIDA::IHistogram1D* m_bankSize    = 0;
+  AIDA::IHistogram1D* m_hitSize     = 0;
+  AIDA::IHistogram1D* m_objtypSize  = 0;
+  AIDA::IHistogram1D* m_substrSize  = 0;
+  AIDA::IHistogram1D* m_stdinfoSize = 0;
+  AIDA::IHistogram1D* m_extinfoSize = 0;
+
+  std::vector<std::pair<std::string, AIDA::IHistogram1D*>> m_hltSelNameList;
+  std::vector<HltSortedSelName>                            m_hltRankedSelName;
+
+  unsigned int m_event = 0;
+};
+
 // Declaration of the Algorithm Factory
 DECLARE_COMPONENT( HltRawDataMonitor )
 
@@ -58,8 +116,6 @@ HltRawDataMonitor::HltRawDataMonitor( const std::string& name, ISvcLocator* pSvc
   declareProperty( "InputRawEventLocation", m_inputRawEventLocation = "" );
   // <0 never 0=at finalize >0 event frequency
   declareProperty( "DiagnosticsFrequency", m_diagnosticsFrequency = 0 );
-
-  declareProperty( "SourceID", m_sourceID = HltSelReportsWriter::kSourceID_Hlt );
 }
 
 //=============================================================================
@@ -83,7 +139,7 @@ StatusCode HltRawDataMonitor::initialize() {
   m_stdinfoSize = book( 500, "Size of Standard-Info sub-bank in HltSelReports (kB)", 0., 5., 500 );
   m_extinfoSize = book( 600, "Size of Extra-Info sub-bank in HltSelreports (kB)", 0., 5., 500 );
 
-  return StatusCode::SUCCESS;
+  return sc;
 }
 
 //=============================================================================
@@ -111,15 +167,14 @@ StatusCode HltRawDataMonitor::execute() {
   if ( !rawEvent ) { return Warning( " No RawEvent found at any location." ); }
 
   ++m_event; // event counter
-  StatusCode sc;
-  sc = fillRawBank();
-  sc = fillHltSelRep();
+  StatusCode sc = fillRawBank();
+  sc            = fillHltSelRep();
 
   if ( m_diagnosticsFrequency > 0 && ( m_event % m_diagnosticsFrequency ) == 0 ) {
     selectionDiagnostics().ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
   }
 
-  return StatusCode::SUCCESS;
+  return sc;
 }
 
 //=============================================================================
@@ -164,10 +219,8 @@ StatusCode HltRawDataMonitor::fillRawBank() {
         hltselreportsRawBankP != hltselreportsRawBanks.end(); ++hltselreportsRawBankP ) {
     const RawBank* hltselreportsRawBank = *hltselreportsRawBankP;
 
-    unsigned int sourceID = HltSelReportsWriter::kSourceID_Hlt;
-    if ( hltselreportsRawBank->version() > 1 ) {
-      sourceID = hltselreportsRawBank->sourceID() >> HltSelReportsWriter::kSourceID_BitShift;
-    }
+    unsigned int sourceID = SourceIDs::Hlt;
+    if ( hltselreportsRawBank->version() > 1 ) { sourceID = hltselreportsRawBank->sourceID() >> SourceIDs::BitShift; }
     if ( m_sourceID != sourceID ) continue;
 
     if ( hltselreportsRawBank->magic() != RawBank::MagicPattern ) {
@@ -175,7 +228,7 @@ StatusCode HltRawDataMonitor::fillRawBank() {
       continue;
     }
     unsigned int bankCounter = hltselreportsRawBank->sourceID();
-    if ( hltselreportsRawBank->version() > 1 ) { bankCounter = bankCounter & HltSelReportsWriter::kSourceID_MinorMask; }
+    if ( hltselreportsRawBank->version() > 1 ) { bankCounter = bankCounter & SourceIDs::MinorMask; }
     if ( bankCounter < hltselreportsRawBanks.size() ) {
       orderedBanks[bankCounter] = hltselreportsRawBank;
       if ( bankCounter > bankCounterMax ) bankCounterMax = bankCounter;
@@ -186,27 +239,24 @@ StatusCode HltRawDataMonitor::fillRawBank() {
   }
   //      if new Hlt1,Hlt2 reports not found try for Hlt1+Hlt2 reports
   if ( !bankSize ) {
-    if ( ( m_sourceID == HltSelReportsWriter::kSourceID_Hlt1 ) ||
-         ( m_sourceID == HltSelReportsWriter::kSourceID_Hlt2 ) ) {
+    if ( ( m_sourceID == SourceIDs::Hlt1 ) || ( m_sourceID == SourceIDs::Hlt2 ) ) {
 
       for ( auto hltselreportsRawBankP = hltselreportsRawBanks.begin();
             hltselreportsRawBankP != hltselreportsRawBanks.end(); ++hltselreportsRawBankP ) {
         const RawBank* hltselreportsRawBank = *hltselreportsRawBankP;
 
-        unsigned int sourceID = HltSelReportsWriter::kSourceID_Hlt;
+        unsigned int sourceID = SourceIDs::Hlt;
         if ( hltselreportsRawBank->version() > 1 ) {
-          sourceID = hltselreportsRawBank->sourceID() >> HltSelReportsWriter::kSourceID_BitShift;
+          sourceID = hltselreportsRawBank->sourceID() >> SourceIDs::BitShift;
         }
-        if ( HltSelReportsWriter::kSourceID_Hlt != sourceID ) continue;
+        if ( SourceIDs::Hlt != sourceID ) continue;
 
         if ( hltselreportsRawBank->magic() != RawBank::MagicPattern ) {
           Error( " HltSelReports RawBank has wrong magic number. Skipped ", StatusCode::SUCCESS, 20 ).ignore();
           continue;
         }
         unsigned int bankCounter = hltselreportsRawBank->sourceID();
-        if ( hltselreportsRawBank->version() > 1 ) {
-          bankCounter = bankCounter & HltSelReportsWriter::kSourceID_MinorMask;
-        }
+        if ( hltselreportsRawBank->version() > 1 ) { bankCounter = bankCounter & SourceIDs::MinorMask; }
         if ( bankCounter < hltselreportsRawBanks.size() ) {
           orderedBanks[bankCounter] = hltselreportsRawBank;
           if ( bankCounter > bankCounterMax ) bankCounterMax = bankCounter;
@@ -365,15 +415,13 @@ StatusCode HltRawDataMonitor::fillRawBank() {
 void HltRawDataMonitor::fillDiag( const char* trigName, double length ) {
   const double maxlen = 20000.0;
   double       lenn   = ( length < maxlen ) ? length : ( maxlen - 1. );
-  for ( std::vector<std::pair<std::string, AIDA::IHistogram1D*>>::const_iterator i = m_hltSelNameList.begin();
-        i != m_hltSelNameList.end(); ++i ) {
-    if ( i->first == trigName ) {
-      fill( i->second, lenn, 1 );
+  for ( const auto& i : m_hltSelNameList ) {
+    if ( i.first == trigName ) {
+      fill( i.second, lenn, 1 );
       return;
     }
   }
-  std::pair<std::string, AIDA::IHistogram1D*> hltHis( trigName, book( trigName, 0., maxlen, 2000 ) );
-  m_hltSelNameList.push_back( hltHis );
+  auto& hltHis = m_hltSelNameList.emplace_back( trigName, book( trigName, 0., maxlen, 2000 ) );
   fill( hltHis.second, lenn, 1 );
 }
 
diff --git a/Hlt/HltDAQ/src/component/HltRawDataMonitor.h b/Hlt/HltDAQ/src/component/HltRawDataMonitor.h
deleted file mode 100644
index 1ebf38800f166cdb2cc611845788b96e0aeb4a9e..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltRawDataMonitor.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTRAWDATAMONITOR_H
-#define HLTRAWDATAMONITOR_H 1
-
-// Include files
-// from Gaudi
-#include "AIDA/IAxis.h"
-#include "AIDA/IHistogram1D.h"
-#include "Event/HltObjectSummary.h"
-#include "GaudiAlg/GaudiAlgorithm.h"
-#include "GaudiAlg/GaudiHistoAlg.h"
-#include "GaudiAlg/GaudiTupleAlg.h"
-#include "Kernel/IANNSvc.h"
-
-/** @class HltRawDataMonitor HltRawDataMonitor.h
- *
- *
- *  @author Chun-Min Jen
- *  @date   2008-10-07
- **/
-
-class HltRawDataMonitor : public GaudiHistoAlg {
-public:
-  enum HeaderIDs { kVersionNumber = 2 };
-
-  /// Standard constructor
-  HltRawDataMonitor( const std::string& name, ISvcLocator* pSvcLocator );
-
-  StatusCode initialize() override; ///< Algorithm initialization
-  StatusCode execute() override;    ///< Algorithm execution
-  StatusCode finalize() override;   ///< Algorithm finalization
-
-private:
-  /// location of input
-  std::string              m_inputRawEventLocation;
-  std::vector<std::string> m_rawEventLocations;
-
-  /// SourceID to decode 0=Hlt 1=Hlt1 2=Hlt2 ... (1,2 will decode from 0 if 1,2 not found)
-  UnsignedIntegerProperty m_sourceID;
-
-  /// <0 never 0=at finalize >0 event frequency
-  IntegerProperty m_diagnosticsFrequency;
-
-private:
-  typedef std::pair<std::pair<std::string, AIDA::IHistogram1D*>, double> HltSortedSelName;
-  class sort {
-  public:
-    bool operator()( const HltSortedSelName& q1, const HltSortedSelName& q2 ) const;
-  };
-
-  void fillDiag( const char* trigName, double length );
-
-  StatusCode fillRawBank();
-  StatusCode fillHltSelRep();
-  StatusCode selectionDiagnostics();
-
-  int    nLength( const LHCb::HltObjectSummary& p );
-  double nMedian( const AIDA::IHistogram1D& q );
-  double nMedian2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
-  double nMean2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
-  double nRMS2( unsigned int NumOfEvt, const AIDA::IHistogram1D& q );
-
-  // lots of different sorts of histograms are declared here
-  // call/book histograms here
-  AIDA::IHistogram1D* m_bankSize    = 0;
-  AIDA::IHistogram1D* m_hitSize     = 0;
-  AIDA::IHistogram1D* m_objtypSize  = 0;
-  AIDA::IHistogram1D* m_substrSize  = 0;
-  AIDA::IHistogram1D* m_stdinfoSize = 0;
-  AIDA::IHistogram1D* m_extinfoSize = 0;
-
-  std::vector<std::pair<std::string, AIDA::IHistogram1D*>> m_hltSelNameList;
-  std::vector<HltSortedSelName>                            m_hltRankedSelName;
-
-  unsigned int m_event = 0;
-};
-#endif // HLTRAWDATAMONITOR_H
diff --git a/Hlt/HltDAQ/src/component/HltRoutingBitsWriter.cpp b/Hlt/HltDAQ/src/component/HltRoutingBitsWriter.cpp
index d3f5283edd7d32e7bf2bf5a4d80ebcb00edccfed..3937746c8411f7f0c4d163b749afcfb4dd008495 100644
--- a/Hlt/HltDAQ/src/component/HltRoutingBitsWriter.cpp
+++ b/Hlt/HltDAQ/src/component/HltRoutingBitsWriter.cpp
@@ -14,10 +14,6 @@
 #include "Event/ODIN.h"
 #include "Event/RawBank.h"
 #include "Event/RawEvent.h"
-#include "GaudiAlg/GaudiHistoAlg.h"
-#include "GaudiKernel/GaudiException.h"
-#include "GaudiKernel/IIncidentListener.h"
-#include "GaudiKernel/IIncidentSvc.h"
 #include "GaudiKernel/IUpdateManagerSvc.h"
 #include "HltDAQ/HltEvaluator.h"
 #include "Kernel/IHltMonitorSvc.h"
@@ -56,18 +52,29 @@ private:
   std::unordered_map<unsigned int, EvalVariant> m_evaluators;
   Gaudi::Property<bool>                         m_updateBank{this, "UpdateExistingRawBank", false};
   DataObjectWriteHandle<LHCb::RawEvent> m_outputRawEvent{this, "RawEventLocation", LHCb::RawEventLocation::Default};
-  Gaudi::Property<std::map<unsigned int, std::string>> m_bits{
-      this, "RoutingBits", {}, [=]( auto& ) {
-        /// mark as "to-be-updated"
-        m_evals_updated = true;
-        // no action if not yet initialized
-        if ( Gaudi::StateMachine::INITIALIZED > FSMState() ) return;
-        // postpone the action
-        if ( !m_preambulo_updated ) { return; }
-        // perform the actual immediate decoding
-        StatusCode sc = decode();
-        Assert( sc.isFailure(), "Error from HltRoutingBitsWriter::decode()", sc );
-      }};
+  Gaudi::Property<std::map<unsigned int, std::string>> m_bits{this, "RoutingBits", {}, [=]( auto& ) {
+                                                                /// mark as "to-be-updated"
+                                                                m_evals_updated = true;
+                                                                // no action if not yet initialized
+                                                                if ( Gaudi::StateMachine::INITIALIZED > FSMState() )
+                                                                  return;
+                                                                // postpone the action
+                                                                if ( !m_preambulo_updated ) { return; }
+                                                                // perform the actual immediate decoding
+                                                                decode().orThrow(
+                                                                    "Error from HltRoutingBitsWriter::decode()" );
+                                                              }};
+
+  mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_multiple_banks{
+      this, " Multiple RoutingBits RawBanks -- don't know which to update. Skipping... ", 20};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_unexpected_size{
+      this, " RoutingBits RawBanks has unexpected size.. Skipping", 20};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_unexpected_two{
+      this, " RoutingBits RawBanks: requested to update bank, but first two entries not the same", 20};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_unexpected_three{
+      this, " RoutingBits RawBanks: requested to update bank, but non-zero third entry", 20};
+  mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_unexpected_presence{
+      this, " Pre-existing RoutingBits bank in the event..."};
 };
 
 // Declaration of the Algorithm Factory
@@ -119,22 +126,19 @@ void HltRoutingBitsWriter::zeroEvaluators() {
 // Main execution
 //=============================================================================
 StatusCode HltRoutingBitsWriter::execute() {
-  StatusCode sc;
-  if ( m_evals_updated || m_preambulo_updated ) {
-    sc = decode();
-    if ( !sc.isSuccess() ) return Error( " Unable to Decode ???? ", std::move( sc ) );
-  }
+  // TODO/FIXME: take lock if update needed -- and move to `initialize` to avoid doing it here more often than needed...
+  if ( m_evals_updated || m_preambulo_updated ) decode().orThrow( "HltRoutingBitsWriter: Unable to decode" );
 
   // Get the fill time, weight and event time
-  double t = 0, weight = 0, evt_time = 0;
-  sc = times( t, weight, evt_time );
+  double     t = 0, weight = 0, evt_time = 0;
+  StatusCode sc = times( t, weight, evt_time );
   if ( !sc.isSuccess() ) return sc;
 
   // Create the evaluator
   Evaluator evaluator{this, t, weight, evt_time};
 
   // The routing bits
-  std::vector<unsigned int> bits( 3, 0 );
+  std::array<unsigned int, 3> bits{0, 0, 0};
 
   // Evaluate the routing bits
   for ( auto& entry : m_evaluators ) {
@@ -150,28 +154,20 @@ StatusCode HltRoutingBitsWriter::execute() {
   if ( m_updateBank ) {
     const auto& banks = rawEvent->banks( LHCb::RawBank::HltRoutingBits );
     if ( banks.size() != 1 ) {
-      return Error( " Multiple RoutingBits RawBanks -- don't know which to update. Skipping... ", StatusCode::SUCCESS,
-                    20 );
+      ++m_multiple_banks;
+      return StatusCode::SUCCESS;
     }
     const LHCb::RawBank* bank = banks[0];
     if ( bank->size() != 3 * sizeof( unsigned int ) ) {
-      return Error( " RoutingBits RawBanks has unexpected size.. Skipping", StatusCode::SUCCESS, 20 );
+      ++m_unexpected_size;
+      return StatusCode::SUCCESS;
     }
     const unsigned int* data = bank->data();
-    if ( data[0] != bits[0] || data[1] != bits[1] ) {
-      Warning( " RoutingBits RawBanks: requested to update bank, but first two entries not the same",
-               StatusCode::SUCCESS, 20 )
-          .ignore();
-    }
-    if ( data[2] != 0 ) {
-      Warning( " RoutingBits RawBanks: requested to update bank, but non-zero third entry", StatusCode::SUCCESS, 20 )
-          .ignore();
-    }
+    if ( data[0] != bits[0] || data[1] != bits[1] ) ++m_unexpected_two;
+    if ( data[2] != 0 ) ++m_unexpected_three;
     const_cast<unsigned int*>( data )[2] = bits[2];
   } else {
-    if ( !rawEvent->banks( LHCb::RawBank::HltRoutingBits ).empty() ) {
-      Warning( " Pre-existing RoutingBits bank in the event...", StatusCode::SUCCESS, 0 ).ignore();
-    }
+    if ( !rawEvent->banks( LHCb::RawBank::HltRoutingBits ).empty() ) ++m_unexpected_presence;
     rawEvent->addBank( 0, LHCb::RawBank::HltRoutingBits, 0, bits );
   }
 
diff --git a/Hlt/HltDAQ/src/component/HltSelReportsDecoder.cpp b/Hlt/HltDAQ/src/component/HltSelReportsDecoder.cpp
index 340a34e9c42c277b1adf5f915bd48b45aac387cd..eb709e88e1c9eb48540eb694518a362de54b9699 100644
--- a/Hlt/HltDAQ/src/component/HltSelReportsDecoder.cpp
+++ b/Hlt/HltDAQ/src/component/HltSelReportsDecoder.cpp
@@ -8,32 +8,25 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-#include "boost/format.hpp"
-#include <numeric>
-
+#include "Event/CaloCluster.h"
 #include "Event/HltDecReports.h"
 #include "Event/HltObjectSummary.h"
 #include "Event/HltSelReports.h"
+#include "Event/Particle.h"
 #include "Event/RawEvent.h"
-
-// bank structure
+#include "Event/RecVertex.h"
+#include "Event/Track.h"
 #include "HltDAQ/HltSelRepRBExtraInfo.h"
 #include "HltDAQ/HltSelRepRBHits.h"
 #include "HltDAQ/HltSelRepRBObjTyp.h"
 #include "HltDAQ/HltSelRepRBStdInfo.h"
 #include "HltDAQ/HltSelRepRBSubstr.h"
 #include "HltDAQ/HltSelRepRawBank.h"
-
-// local
-#include "HltSelReportsDecoder.h"
-#include "HltSelReportsWriter.h"
-
-#include "Event/CaloCluster.h"
-#include "Event/Particle.h"
-#include "Event/RecVertex.h"
-#include "Event/Track.h"
+#include "HltDAQ/IReportConvert.h"
+#include "HltRawBankDecoderBase.h"
 #include "LHCbMath/bit_cast.h"
+#include "boost/format.hpp"
+#include <numeric>
 
 using namespace LHCb;
 
@@ -43,6 +36,41 @@ using namespace LHCb;
 // 2008-08-01 : Tomasz Skwarnicki
 //-----------------------------------------------------------------------------
 
+namespace {
+  bool order_by_sourceID( const LHCb::RawBank* lhs, const LHCb::RawBank* rhs ) {
+    auto l = lhs->sourceID() & SourceIDs::MinorMask;
+    auto r = rhs->sourceID() & SourceIDs::MinorMask;
+    return l < r;
+  }
+} // namespace
+
+/** @class HltSelReportsDecoder HltSelReportsDecoder.h
+ *
+ *
+ *  @author Tomasz Skwarnicki
+ *  @date   2008-08-02
+ *
+ *  Algorithm to read HltSelReports from Raw Data and create containers on TES
+ *
+ */
+
+class HltSelReportsDecoder : public HltRawBankMultiDecoder<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> {
+public:
+  /// Standard constructor
+  HltSelReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator );
+
+  ///< Algorithm initialization
+  StatusCode initialize() override;
+
+  ///< Algorithm execution
+  std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> operator()( const LHCb::RawEvent& ) const override;
+
+private:
+  enum HeaderIDs { kVersionNumber = 11 };
+  /// for converting objects in to summaries
+  mutable ToolHandle<IReportConvert> m_conv{this, "ReportConvertTool", "ReportConvertTool"};
+};
+
 // Declaration of the Algorithm Factory
 DECLARE_COMPONENT( HltSelReportsDecoder )
 
@@ -73,15 +101,10 @@ StatusCode HltSelReportsDecoder::initialize() {
   // const auto& summaryLoc = getProperty("OutputHltObjectSummariesLocation");
   // const auto& selrepLoc = getProperty("OutputHltSelReportsLocation");
   // const auto& expected = selrepLoc.toString()+"/Candidates";
-  // if (summaryLoc.toString().empty()) {
-  //  setProperty("OutputHltObjectSummariesLocation", expected );
-  //}
   // if ( symmaryLoc.toString() != expected ) {
   //  return Error("value of OutputHltObjectSummariesLocation not consistent", StatusCode::FAILURE);
   //}
-  // Initialise the converter tool
-  m_conv = tool<IReportConvert>( "ReportConvertTool", this );
-  return m_conv ? StatusCode::SUCCESS : Error( "Unable to retrieve the Report converter tool" );
+  return sc;
 }
 //=============================================================================
 // Main execution
@@ -99,9 +122,8 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
                           StatusCode::SUCCESS );
   }
   std::tuple<HltSelReports, HltObjectSummary::Container> outputs;
-  auto&                                                  output = std::get<0>( outputs );
   // output container for Object Summaries
-  auto& objectSummaries = std::get<1>( outputs );
+  auto& [output, objectSummaries] = outputs;
 
   const RawBank* hltselreportsRawBank0 = hltselreportsRawBanks.front();
 
@@ -148,25 +170,15 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
         .ignore();
   }
   // put the banks into the right order (in case the data was split across multiple banks...
-  std::sort( std::begin( hltselreportsRawBanks ), std::end( hltselreportsRawBanks ),
-             []( const RawBank* lhs, const RawBank* rhs ) {
-               auto l = lhs->sourceID() & HltSelReportsWriter::kSourceID_MinorMask;
-               auto r = rhs->sourceID() & HltSelReportsWriter::kSourceID_MinorMask;
-               return l < r;
-             } );
+  std::sort( begin( hltselreportsRawBanks ), end( hltselreportsRawBanks ), order_by_sourceID );
   // verify no duplicates...
-  auto adj = std::adjacent_find( std::begin( hltselreportsRawBanks ), std::end( hltselreportsRawBanks ),
-                                 []( const RawBank* lhs, const RawBank* rhs ) {
-                                   auto l = lhs->sourceID() & HltSelReportsWriter::kSourceID_MinorMask;
-                                   auto r = rhs->sourceID() & HltSelReportsWriter::kSourceID_MinorMask;
-                                   return l == r;
-                                 } );
-  if ( adj != std::end( hltselreportsRawBanks ) ) {
+  auto adj = std::adjacent_find( begin( hltselreportsRawBanks ), end( hltselreportsRawBanks ), order_by_sourceID );
+  if ( adj != end( hltselreportsRawBanks ) ) {
     Error( " Duplicate sequential Source ID HltSelReports. Aborting decoder ", StatusCode::SUCCESS, 20 ).ignore();
     return outputs; // TODO: review whether to throw an exception instead
   }
 
-  unsigned int nLastOne = hltselreportsRawBanks.back()->sourceID() & HltSelReportsWriter::kSourceID_MinorMask;
+  unsigned int nLastOne = hltselreportsRawBanks.back()->sourceID() & SourceIDs::MinorMask;
   if ( nLastOne + 1 != hltselreportsRawBanks.size() ) {
     Error( " Did not find the expected number of HltSelReports raw banks. Aborting decoder ", StatusCode::SUCCESS, 20 )
         .ignore();
@@ -174,10 +186,8 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
   }
 
   unsigned int bankSize =
-      std::accumulate( std::begin( hltselreportsRawBanks ), std::end( hltselreportsRawBanks ), 0,
-                       []( unsigned int s, const RawBank* bank ) {
-                         return s + std::distance( bank->begin<unsigned int>(), bank->end<unsigned int>() );
-                       } );
+      std::accumulate( begin( hltselreportsRawBanks ), end( hltselreportsRawBanks ), 0,
+                       []( unsigned int s, const RawBank* bank ) { return s + bank->range<unsigned int>().size(); } );
 
   if ( !bankSize ) {
     Warning( " No HltSelReports RawBank for requested SourceID in RawEvent. Quiting. ", StatusCode::SUCCESS, 10 )
@@ -189,7 +199,7 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
   // well...
   auto             pBank = new unsigned int[bankSize];
   HltSelRepRawBank hltSelReportsBank( pBank ); // bank assumes ownership
-  std::accumulate( std::begin( hltselreportsRawBanks ), std::end( hltselreportsRawBanks ), pBank,
+  std::accumulate( begin( hltselreportsRawBanks ), end( hltselreportsRawBanks ), pBank,
                    []( unsigned int* p, const LHCb::RawBank* bank ) {
                      return std::copy( bank->begin<unsigned int>(), bank->end<unsigned int>(), p );
                    } );
@@ -325,7 +335,7 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
 
   for ( unsigned int iObj = 0; iObj != nObj; ++iObj ) {
 
-    auto hos = new HltObjectSummary();
+    auto hos = std::make_unique<HltObjectSummary>();
 
     // =========== class ID
     hos->setSummarizedObjectCLID( objTypSubBank.next() );
@@ -377,12 +387,12 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
         if ( stdInfo.size() > 1 ) {
           int  id = (int)( bit_cast<float>( stdInfo[1] ) + 0.1 );
           auto iselName = idmap.find( id );
-          if ( iselName == std::end( idmap ) ) {
+          if ( iselName == end( idmap ) ) {
             Error( " Did not find string key for PV-selection-ID in trigger selection in storage id=" +
                        std::to_string( id ),
                    StatusCode::SUCCESS, 10 )
                 .ignore();
-            infoPersistent.insert( "10#Unknown", bit_cast<float, unsigned int>( id ) );
+            infoPersistent.insert( "10#Unknown", bit_cast<float>( stdInfo[1] ) );
           } else
             infoPersistent.insert( "10#" + iselName->second.str(), bit_cast<float>( stdInfo[1] ) );
         }
@@ -409,7 +419,7 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
     if ( exInfOn ) {
       for ( const auto& i : extraInfoSubBank.next() ) {
         auto infos = infomap.find( i.first );
-        if ( infos != std::end( infomap ) ) {
+        if ( infos != end( infomap ) ) {
           infoPersistent.insert( infos->second, i.second );
         } else {
           Warning( " String key for Extra Info item in storage not found id=" + std::to_string( i.first ),
@@ -419,7 +429,7 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
       }
     }
     hos->setNumericalInfo( infoPersistent );
-    objects.push_back( hos );
+    objects.push_back( hos.release() );
   }
 
   // -----------------------------------------------------------------
@@ -441,14 +451,14 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
           //                   for odd number of sequences saved - omit this hit
           if ( iSeq == 0 && hltselreportsRawBank0->version() == 0 && nSeq % 2 == 1 ) { hitseq.erase( hitseq.begin() ); }
           // ------------------------- end fix --------------------------------------------
-          if ( hitseq.size() ) { hits.insert( std::end( hits ), std::begin( hitseq ), std::end( hitseq ) ); }
+          if ( hitseq.size() ) { hits.insert( end( hits ), begin( hitseq ), end( hitseq ) ); }
         } else {
           Error( "Hit sequence index out of range", StatusCode::SUCCESS, 10 ).ignore();
         }
       }
       // Sort hits to make sure decode(write(X)) keeps the IDs ordered
       // (ordering is relied upon and enforced in HltSelReportsWriter)
-      std::sort( std::begin( hits ), std::end( hits ) );
+      std::sort( begin( hits ), end( hits ) );
       hos->setLhcbIDs( hits );
 
     } else {
@@ -514,19 +524,12 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
   // ---------------------------------------------------------
 
   for ( unsigned int iObj = 0; iObj != nObj; ++iObj ) {
-
     HltObjectSummary*& hos = objects[iObj];
     if ( hos->summarizedObjectCLID() != 1 ) continue;
-
-    auto selName = std::end( idmap );
-    auto i = std::find_if( std::begin( hos->numericalInfo() ), std::end( hos->numericalInfo() ),
+    auto i = std::find_if( begin( hos->numericalInfo() ), end( hos->numericalInfo() ),
                            []( const std::pair<std::string, double>& info ) { return info.first == "0#SelectionID"; } );
-    if ( i != std::end( hos->numericalInfo() ) ) {
-      int id  = (int)( i->second + 0.1 );
-      selName = idmap.find( id );
-    }
-    if ( selName != std::end( idmap ) ) {
-
+    auto selName = ( i != end( hos->numericalInfo() ) ? idmap.find( (int)( i->second + 0.1 ) ) : end( idmap ) );
+    if ( selName != end( idmap ) ) {
       // skip reports of the wrong type
       if ( !selName->second ) continue;
 
@@ -538,9 +541,15 @@ std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> HltSelReports
 
       // insert selection into the container
       if ( output.insert( selName->second, selSumOut ) == StatusCode::FAILURE ) {
-        Error( "  Failed to add Hlt selection name " + std::string{selName->second} + " to its container ",
-               StatusCode::SUCCESS, 10 )
-            .ignore();
+        // failed because already there -- check if entries are the samee...
+        auto prev = output.find( selName->second );
+        if ( prev != output.end() && prev->second == selSumOut ) {
+          Warning( "duplicate decoded entry for " + selName->second + " -- leaving initial one " ).ignore();
+        } else {
+          Error( "  Failed to add Hlt selection name " + std::string{selName->second} + " to its container ",
+                 StatusCode::SUCCESS, 10 )
+              .ignore();
+        }
       }
     } else {
       Error( " Did not find string key for trigger selection in storage", StatusCode::SUCCESS, 50 ).ignore();
diff --git a/Hlt/HltDAQ/src/component/HltSelReportsDecoder.h b/Hlt/HltDAQ/src/component/HltSelReportsDecoder.h
deleted file mode 100644
index f5e6946aff40d1c28e5aa5c5529c536b887be18d..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltSelReportsDecoder.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTSELREPORTSDECODER_H
-#define HLTSELREPORTSDECODER_H 1
-
-// Include files
-// from Gaudi
-#include "HltDAQ/IReportConvert.h"
-#include "HltRawBankDecoderBase.h"
-
-/** @class HltSelReportsDecoder HltSelReportsDecoder.h
- *
- *
- *  @author Tomasz Skwarnicki
- *  @date   2008-08-02
- *
- *  Algorithm to read HltSelReports from Raw Data and create containers on TES
- *
- */
-
-class HltSelReportsDecoder : public HltRawBankMultiDecoder<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> {
-public:
-  /// Standard constructor
-  HltSelReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator );
-
-  ///< Algorithm initialization
-  StatusCode initialize() override;
-
-  ///< Algorithm execution
-  std::tuple<LHCb::HltSelReports, LHCb::HltObjectSummary::Container> operator()( const LHCb::RawEvent& ) const override;
-
-private:
-  enum HeaderIDs { kVersionNumber = 11 };
-  /// for converting objects in to summaries
-  IReportConvert* m_conv = nullptr;
-};
-
-#endif // HLTSELREPORTSDECODER_H
diff --git a/Hlt/HltDAQ/src/component/HltSelReportsWriter.cpp b/Hlt/HltDAQ/src/component/HltSelReportsWriter.cpp
index bc285f7824d4bb6b49d0f9d5ac34a7318d8ab9fe..caf0c658ca797c9bb2409b7c064e7fe355095fae 100644
--- a/Hlt/HltDAQ/src/component/HltSelReportsWriter.cpp
+++ b/Hlt/HltDAQ/src/component/HltSelReportsWriter.cpp
@@ -8,25 +8,24 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#include <cctype>
-#include <memory>
-#include <numeric>
-
+#include "Event/HltDecReports.h"
 #include "Event/HltObjectSummary.h"
 #include "Event/HltSelReports.h"
 #include "Event/RawEvent.h"
-
-// bank structure
 #include "HltDAQ/HltSelRepRBExtraInfo.h"
 #include "HltDAQ/HltSelRepRBHits.h"
 #include "HltDAQ/HltSelRepRBObjTyp.h"
 #include "HltDAQ/HltSelRepRBStdInfo.h"
 #include "HltDAQ/HltSelRepRBSubstr.h"
 #include "HltDAQ/HltSelRepRawBank.h"
-
-// local
-#include "HltSelReportsWriter.h"
+#include "HltSourceID.h"
+#include "Kernel/IANNSvc.h"
+#include "Kernel/IIndexedANNSvc.h"
+#include "LHCbAlgs/Consumer.h"
 #include "LHCbMath/bit_cast.h"
+#include <cctype>
+#include <memory>
+#include <numeric>
 
 using namespace LHCb;
 
@@ -40,8 +39,8 @@ namespace {
 
   bool isStdInfo( const std::string& s ) {
     // check for [0-9]+# at the start, i.e. first non-numerical item is a '#', and it cannot be the first character
-    auto i = std::find_if( std::begin( s ), std::end( s ), []( const char& c ) { return std::isdigit( c ) == 0; } );
-    return i != std::begin( s ) && i != std::end( s ) && *i == '#';
+    auto i = std::find_if( begin( s ), end( s ), []( const char& c ) { return std::isdigit( c ) == 0; } );
+    return i != begin( s ) && i != end( s ) && *i == '#';
   }
 
   static const Gaudi::StringKey InfoID{"InfoID"};
@@ -134,6 +133,70 @@ namespace {
 // 2008-07-25 : Tomasz Skwarnicki
 //-----------------------------------------------------------------------------
 
+/** @class HltSelReportsWriter HltSelReportsWriter.h
+ *
+ *
+ *  @author Tomasz Skwarnicki
+ *  @date   2008-07-25
+ *
+ *  Algorithm to convert HltSelReports and HltObjectSummarys containers on TES to HltSelCandidates Raw Bank
+ *
+ */
+using HltSelReportsWriterBase_t = LHCb::Algorithm::Consumer<void(
+    LHCb::HltDecReports const&, LHCb::HltSelReports const&, LHCb::HltObjectSummary::Container const& )>;
+
+class HltSelReportsWriter : public HltSelReportsWriterBase_t {
+public:
+  HltSelReportsWriter( const std::string& name, ISvcLocator* pSvcLocator )
+      : HltSelReportsWriterBase_t( name, pSvcLocator,
+                                   {KeyValue{"DecReports", LHCb::HltDecReportsLocation::Default},
+                                    KeyValue{"SelReports", LHCb::HltSelReportsLocation::Default},
+                                    KeyValue{"ObjectSummaries", LHCb::HltObjectSummaryLocation::Default}} ) {}
+
+  StatusCode initialize() override; ///< Algorithm initialization
+  void       operator()( LHCb::HltDecReports const& decreps, LHCb::HltSelReports const& selreps,
+                   LHCb::HltObjectSummary::Container const& objectSummaries ) const override; ///< Algorithm
+                                                                                                    ///< execution
+
+  enum HeaderIDs { kVersionNumber = 11 };
+
+private:
+  DataObjectWriteHandle<LHCb::RawEvent> m_rawEvent{this, "RawEvent", LHCb::RawEventLocation::Default};
+
+  /// whether to try to use the TCK and the TCKANNSvc
+  Gaudi::Property<bool> m_useTCK{this, "UseTCK", false};
+
+  /// SourceID to insert in the bank header
+  Gaudi::Property<SourceIDs> m_sourceID{this, "SourceID", SourceIDs::Dummy};
+
+  /// HltANNSvc for making selection names to int selection ID
+  ServiceHandle<IANNSvc> m_hltANNSvc{this, "ANNSvc", "HltANNSvc", "Service to retrieve DecReport IDs"};
+  /// TCKANNSvc to be used in production
+  // ServiceHandle<IIndexedANNSvc> m_tckANNSvc{this, "IndexedANNSvc", "TCKANNSvc", "Service to retrieve DecReport IDs"};
+  SmartIF<IIndexedANNSvc> m_tckANNSvc;
+
+  using NameToNumberMap = std::map<std::string, unsigned int>;
+  mutable std::map<std::pair<unsigned int, Gaudi::StringKey>, NameToNumberMap> m_infoTable;
+
+  const NameToNumberMap& tckANNSvcMap( unsigned int tck, const Gaudi::StringKey& major ) const;
+
+  std::optional<int> optionalValue( const Gaudi::StringKey& major, const std::string& key ) const {
+    if ( const auto p = m_hltANNSvc->value( major, key ); p ) {
+      return p->second;
+    } else {
+      return std::nullopt;
+    }
+  }
+
+  std::optional<int> optionalFind( const NameToNumberMap& map, const std::string& key ) const {
+    if ( auto i = map.find( key ); i != end( map ) ) {
+      return i->second;
+    } else {
+      return std::nullopt;
+    }
+  }
+};
+
 // Declaration of the Algorithm Factory
 DECLARE_COMPONENT( HltSelReportsWriter )
 
@@ -149,12 +212,12 @@ StatusCode HltSelReportsWriter::initialize() {
 //=============================================================================
 // Main execution
 //=============================================================================
-LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decreps, LHCb::HltSelReports const& selreps,
-                                                LHCb::HltObjectSummary::Container const& objectSummaries ) const {
+void HltSelReportsWriter::operator()( LHCb::HltDecReports const& decreps, LHCb::HltSelReports const& selreps,
+                                      LHCb::HltObjectSummary::Container const& objectSummaries ) const {
   if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg;
 
   // create empty output RawEvent
-  RawEvent rawEvent;
+  RawEvent* rawEvent = m_rawEvent.getOrCreate();
 
   // const HltSelReportsWriter::NameToNumberMap* infoIDMap = nullptr;
   unsigned int const tck = m_useTCK ? decreps.configuredTCK() : 0;
@@ -165,7 +228,7 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
   if ( objectSummaries.size() > 0xFFFFL ) {
     error() << "Too many HltObjectSummaries to store " << objectSummaries.size()
             << " HltSelReports RawBank cannot be created " << endmsg;
-    return rawEvent;
+    return;
   }
 
   // --------------------------------------------------------------------------------------
@@ -179,36 +242,36 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
     const auto&                 ids = hos->lhcbIDs();
     LhcbidSequences::value_type thisIDset;
     thisIDset.reserve( ids.size() );
-    std::transform( std::begin( ids ), std::end( ids ), std::inserter( thisIDset, std::end( thisIDset ) ),
+    std::transform( begin( ids ), end( ids ), std::inserter( thisIDset, end( thisIDset ) ),
                     []( const LHCb::LHCbID& id ) { return id.lhcbID(); } );
     // Make sure the LHCbIDs are sorted or else the binary_search called
     // later does not work! (when connecting substructures with ids)
     // TODO check if its needed
-    std::sort( std::begin( thisIDset ), std::end( thisIDset ) );
+    std::sort( begin( thisIDset ), end( thisIDset ) );
 
     addToSequences( std::move( thisIDset ), lhcbidSequences );
   }
 
-  auto nHits = std::accumulate( std::begin( lhcbidSequences ), std::end( lhcbidSequences ), 0u,
+  auto nHits = std::accumulate( begin( lhcbidSequences ), end( lhcbidSequences ), 0u,
                                 []( unsigned int n, LhcbidSequences::const_reference s ) { return n + s.size(); } );
 
   if ( lhcbidSequences.size() / 2 + 1 + nHits > 0xFFFFL ) {
     error() << "Too many hits or hit-sequences to store hits=" << std::to_string( nHits )
             << " seq=" << std::to_string( lhcbidSequences.size() ) << " HltSelReports RawBank cannot be created "
             << endmsg;
-    return rawEvent;
+    return;
   }
 
   HltSelRepRBHits hitsSubBank;
   hitsSubBank.initialize( lhcbidSequences.size(), nHits );
-  std::copy( std::begin( lhcbidSequences ), std::end( lhcbidSequences ), std::back_inserter( hitsSubBank ) );
+  std::copy( begin( lhcbidSequences ), end( lhcbidSequences ), std::back_inserter( hitsSubBank ) );
 
   // --------------------------------------------------------------------------------------
   //  ---------------- in storage banks are ordered by summarizedClassCLID ----------------
   // -------------------------------- sort them -------------------------------------------
 
   std::vector<const HltObjectSummary*> sortedHosPtrs( objectSummaries.begin(), objectSummaries.end() );
-  std::sort( std::begin( sortedHosPtrs ), std::end( sortedHosPtrs ), sortByCLID_ );
+  std::sort( begin( sortedHosPtrs ), end( sortedHosPtrs ), sortByCLID_ );
   // inverse mapping
   std::vector<unsigned int> fromIndexToNewIndex( sortedHosPtrs.size() );
   for ( size_t i = 0; i != sortedHosPtrs.size(); ++i ) { fromIndexToNewIndex[sortedHosPtrs[i]->index()] = i; }
@@ -254,11 +317,11 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
                    " nInfo=" + std::to_string( nStdInfo ) + " No Std Info will be saved!"
             << endmsg;
     // save only selection IDs
-    nStdInfo = std::accumulate(
-        std::begin( sortedHosPtrs ), std::end( sortedHosPtrs ), 0, []( int n, const HltObjectSummary* hos ) {
+    nStdInfo =
+        std::accumulate( begin( sortedHosPtrs ), end( sortedHosPtrs ), 0, []( int n, const HltObjectSummary* hos ) {
           if ( hos->summarizedObjectCLID() == 1 ) {
             const auto& ni = hos->numericalInfo();
-            n += std::count_if( std::begin( ni ), std::end( ni ),
+            n += std::count_if( begin( ni ), end( ni ),
                                 []( HltObjectSummary::Info::const_reference i ) { return isStdInfo( i.first ); } );
           }
           return n;
@@ -307,7 +370,7 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
     const auto& subs    = hos->substructure();
     const auto& subsExt = hos->substructureExtended();
     if ( !subs.empty() || !subsExt.empty() ) {
-      std::transform( std::begin( subs ), std::end( subs ), std::back_inserter( svect ),
+      std::transform( begin( subs ), end( subs ), std::back_inserter( svect ),
                       [&]( const SmartRef<LHCb::HltObjectSummary>& i ) { return fromIndexToNewIndex[i->index()]; } );
       if ( !subsExt.empty() ) { // add Extended items if not in already
         for ( const auto& i : subsExt ) {
@@ -321,7 +384,7 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
       sHitType = 1;
       unsigned int iSeqID( 0 );
       for ( const auto& hitset : lhcbidSequences ) {
-        if ( std::binary_search( std::begin( hos->lhcbIDs() ), std::end( hos->lhcbIDs() ), LHCbID{hitset.front()} ) )
+        if ( std::binary_search( begin( hos->lhcbIDs() ), end( hos->lhcbIDs() ), LHCbID{hitset.front()} ) )
           svect.push_back( iSeqID );
         ++iSeqID;
       }
@@ -365,13 +428,13 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
                                              &( hltSelReportsBank_99.location()[hltSelReportsBank_99.size()] ) );
       // TODO handle the construction of the extended raw event differently, we would like to have a const tes in the
       // end. see https://its.cern.ch/jira/browse/LBCORE-1742
-      rawEvent.addBank( m_sourceID, RawBank::HltSelReports, 99, bankBody_99 );
+      rawEvent->addBank( m_sourceID, RawBank::HltSelReports, 99, bankBody_99 );
       hltSelReportsBank_99.deleteBank();
 
       error() << "Exceeded maximal size of substructure-subbank. HltSelReports RawBank cannot be created, instead "
                  "returning debugging bank"
               << endmsg;
-      return rawEvent;
+      return;
     }
   }
 
@@ -414,11 +477,11 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
   // RawBank is limited in size to 65535 bytes i.e. 16383 words; be conservative cut it off at a smaller limit.
   // Save in chunks if exceed this size.
   int nBank = 1 + ( hltSelReportsBank.size() == 0 ? 0 : ( hltSelReportsBank.size() - 1 ) / 16300 );
-  if ( nBank > kSourceID_MinorMask ) {
+  if ( nBank > static_cast<int>( SourceIDs::MinorMask ) ) {
     // delete the main bank
     hltSelReportsBank.deleteBank();
     error() << "HltSelReports too long to save" << endmsg;
-    return rawEvent;
+    return;
   }
   for ( int iBank = 0; iBank < nBank; ++iBank ) {
     int ioff  = iBank * 16300;
@@ -427,10 +490,10 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
     // TODO: can we avoid making a copy into bankBody??? ( call adoptBank( createBank( ... ) ) ? )
     std::vector<unsigned int> bankBody( &( hltSelReportsBank.location()[ioff] ),
                                         &( hltSelReportsBank.location()[ioff + isize] ) );
-    int                       sourceID = iBank | ( m_sourceID << kSourceID_BitShift );
+    int                       sourceID = iBank | ( m_sourceID << SourceIDs::BitShift );
     // TODO handle the construction of the extended raw event differently, we would like to have a const tes in the end.
     // see https://its.cern.ch/jira/browse/LBCORE-1742
-    rawEvent.addBank( sourceID, RawBank::HltSelReports, kVersionNumber, bankBody );
+    rawEvent->addBank( sourceID, RawBank::HltSelReports, kVersionNumber, bankBody );
   }
   if ( nBank > 1 ) {
     warning() << "HltSelReports is huge. Saved in " + std::to_string( nBank ) + " separate RawBanks " << endmsg;
@@ -452,8 +515,6 @@ LHCb::RawEvent HltSelReportsWriter::operator()( LHCb::HltDecReports const& decre
 
   // delete the main bank
   hltSelReportsBank.deleteBank();
-
-  return rawEvent;
 }
 
 const HltSelReportsWriter::NameToNumberMap& HltSelReportsWriter::tckANNSvcMap( unsigned int            tck,
@@ -461,7 +522,7 @@ const HltSelReportsWriter::NameToNumberMap& HltSelReportsWriter::tckANNSvcMap( u
   const auto key = std::pair{tck, major};
 
   auto itbl = m_infoTable.find( key );
-  if ( itbl != std::end( m_infoTable ) ) { return itbl->second; }
+  if ( itbl != end( m_infoTable ) ) { return itbl->second; }
 
   auto& map = m_infoTable[key];
   for ( auto p : m_tckANNSvc->i2s( tck, InfoID ) ) { map.insert( {p.second, p.first} ); }
diff --git a/Hlt/HltDAQ/src/component/HltSelReportsWriter.h b/Hlt/HltDAQ/src/component/HltSelReportsWriter.h
deleted file mode 100644
index 848d8e747ce6065dedc277c220cd695a7ef2c393..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltSelReportsWriter.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#pragma once
-#include "Event/HltDecReports.h"
-#include "Event/HltObjectSummary.h"
-#include "Event/HltSelReports.h"
-#include "Event/RawEvent.h"
-#include "Kernel/IANNSvc.h"
-#include "Kernel/IIndexedANNSvc.h"
-#include "LHCbAlgs/Transformer.h"
-
-/** @class HltSelReportsWriter HltSelReportsWriter.h
- *
- *
- *  @author Tomasz Skwarnicki
- *  @date   2008-07-25
- *
- *  Algorithm to convert HltSelReports and HltObjectSummarys containers on TES to HltSelCandidates Raw Bank
- *
- */
-using HltSelReportsWriterBase_t = LHCb::Algorithm::Transformer<LHCb::RawEvent(
-    LHCb::HltDecReports const&, LHCb::HltSelReports const&, LHCb::HltObjectSummary::Container const& )>;
-
-class HltSelReportsWriter : public HltSelReportsWriterBase_t {
-public:
-  HltSelReportsWriter( const std::string& name, ISvcLocator* pSvcLocator )
-      : HltSelReportsWriterBase_t( name, pSvcLocator,
-                                   {KeyValue{"DecReports", LHCb::HltDecReportsLocation::Default},
-                                    KeyValue{"SelReports", LHCb::HltSelReportsLocation::Default},
-                                    KeyValue{"ObjectSummaries", LHCb::HltObjectSummaryLocation::Default}},
-                                   {"RawEvent", LHCb::RawEventLocation::Default} ) {}
-
-  StatusCode     initialize() override; ///< Algorithm initialization
-  LHCb::RawEvent operator()( LHCb::HltDecReports const& decreps, LHCb::HltSelReports const& selreps,
-                             LHCb::HltObjectSummary::Container const& objectSummaries ) const override; ///< Algorithm
-                                                                                                        ///< execution
-
-  enum HeaderIDs { kVersionNumber = 11 };
-
-  enum SourceIDs {
-    kSourceID_Dummy     = 0,
-    kSourceID_Hlt       = kSourceID_Dummy,
-    kSourceID_Hlt1      = 1,
-    kSourceID_Hlt2      = 2,
-    kSourceID_Max       = 7,
-    kSourceID_BitShift  = 13,
-    kSourceID_MinorMask = 0x1FFF,
-    kSourceID_MajorMask = 0xE000
-  };
-
-private:
-  /// whether to try to use the TCK and the TCKANNSvc
-  Gaudi::Property<bool> m_useTCK{this, "UseTCK", false};
-
-  /// SourceID to insert in the bank header (0-7)
-  Gaudi::Property<int> m_sourceID{this, "SourceID", kSourceID_Dummy, [=]( auto&& ) {
-                                    if ( m_sourceID > kSourceID_Max || m_sourceID < 0 )
-                                      throw std::runtime_error{
-                                          "Illegal SourceID specified; maximal allowed value is 7"};
-                                  }};
-
-  /// HltANNSvc for making selection names to int selection ID
-  ServiceHandle<IANNSvc> m_hltANNSvc{this, "ANNSvc", "HltANNSvc", "Service to retrieve DecReport IDs"};
-  /// TCKANNSvc to be used in production
-  // ServiceHandle<IIndexedANNSvc> m_tckANNSvc{this, "IndexedANNSvc", "TCKANNSvc", "Service to retrieve DecReport IDs"};
-  SmartIF<IIndexedANNSvc> m_tckANNSvc;
-
-  using NameToNumberMap = std::map<std::string, unsigned int>;
-  mutable std::map<std::pair<unsigned int, Gaudi::StringKey>, NameToNumberMap> m_infoTable;
-
-  const NameToNumberMap& tckANNSvcMap( unsigned int tck, const Gaudi::StringKey& major ) const;
-
-  std::optional<int> optionalValue( const Gaudi::StringKey& major, const std::string& key ) const {
-    if ( const auto p = m_hltANNSvc->value( major, key ); p ) {
-      return p->second;
-    } else {
-      return std::nullopt;
-    }
-  }
-
-  std::optional<int> optionalFind( const NameToNumberMap& map, const std::string& key ) const {
-    if ( auto i = map.find( key ); i != std::end( map ) ) {
-      return i->second;
-    } else {
-      return std::nullopt;
-    }
-  }
-};
diff --git a/Hlt/HltDAQ/src/component/HltSourceID.cpp b/Hlt/HltDAQ/src/component/HltSourceID.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c4d357a3e8bde868c165e43f40fbc426de2fad4
--- /dev/null
+++ b/Hlt/HltDAQ/src/component/HltSourceID.cpp
@@ -0,0 +1,37 @@
+/*****************************************************************************\
+* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#include "HltSourceID.h"
+#include <string_view>
+
+namespace LHCb::Hlt::DAQ {
+  namespace {
+    using namespace std::literals;
+    constexpr auto names = std::array{std::pair{SourceID::Dummy, "Dummy"sv}, std::pair{SourceID::Hlt, "Hlt"sv},
+                                      std::pair{SourceID::Hlt1, "Hlt1"sv}, std::pair{SourceID::Hlt2, "Hlt2"sv},
+                                      std::pair{SourceID::Spruce, "Spruce"sv}};
+  } // namespace
+
+  StatusCode parse( SourceID& id, const std::string& in ) {
+    auto sv = std::string_view{in};
+    if ( sv.size() > 1 && ( sv.front() == '\'' || sv.front() == '\"' ) && sv.front() == sv.back() )
+      sv = sv.substr( 1, sv.size() - 2 );
+    auto i = std::find_if( names.begin(), names.end(), [sv]( const auto& p ) { return p.second == sv; } );
+    if ( i == names.end() ) return StatusCode::FAILURE;
+    id = i->first;
+    return StatusCode::SUCCESS;
+  }
+
+  std::string toString( SourceID id ) {
+    auto i = std::find_if( names.begin(), names.end(), [id]( const auto& p ) { return p.first == id; } );
+    if ( i == names.end() ) throw std::runtime_error( "Bad LHCb::Hlt::DAQ::SourceID value" );
+    return std::string{i->second};
+  }
+} // namespace LHCb::Hlt::DAQ
diff --git a/Hlt/HltDAQ/src/component/HltSourceID.h b/Hlt/HltDAQ/src/component/HltSourceID.h
new file mode 100644
index 0000000000000000000000000000000000000000..279b501a2994f56097509b50b96fa2d9a26e33e3
--- /dev/null
+++ b/Hlt/HltDAQ/src/component/HltSourceID.h
@@ -0,0 +1,39 @@
+/*****************************************************************************\
+* (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#pragma once
+#include "GaudiKernel/StatusCode.h"
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+namespace LHCb::Hlt::DAQ {
+
+  enum SourceID : unsigned int {
+    Dummy     = 0,
+    Hlt       = Dummy,
+    Hlt1      = 1,
+    Hlt2      = 2,
+    Spruce    = 3,
+    Max       = 7,
+    BitShift  = 13,
+    MinorMask = 0x1FFF,
+    MajorMask = 0xE000
+  };
+
+  StatusCode  parse( SourceID& id, const std::string& s );
+  std::string toString( SourceID );
+
+  inline std::ostream& toStream( SourceID id, std::ostream& os ) { return os << std::quoted( toString( id ), '\'' ); }
+  inline std::ostream& operator<<( std::ostream& s, SourceID e ) { return toStream( e, s ); }
+
+} // namespace LHCb::Hlt::DAQ
+
+using SourceIDs /* [[deprecated]] */ = LHCb::Hlt::DAQ::SourceID; // TODO: deprecate and remove
diff --git a/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.cpp b/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.cpp
deleted file mode 100644
index 8110f79a2845dc6b4b729b6643b6ac6a916783ff..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-// Include files
-#include "boost/format.hpp"
-#include <algorithm>
-#include <numeric>
-
-#include "Event/RawEvent.h"
-
-// local
-#include "HltDAQ/HltTrackingCoder.h"
-#include "HltTrackReportsDecoder.h"
-#include "HltTrackReportsWriter.h"
-
-#include "Event/Track.h"
-
-using namespace LHCb;
-
-namespace {
-  int sourceID( const RawBank& bank ) { return bank.sourceID() >> HltTrackReportsWriter::kSourceID_BitShift; }
-
-  struct cmp_sourceID_t {
-    bool operator()( int id, const RawBank* bank ) const { return id < sourceID( *bank ); }
-    bool operator()( const RawBank* bank, int id ) const { return sourceID( *bank ) < id; }
-  };
-  inline constexpr cmp_sourceID_t cmp_sourceID{};
-
-  int seq( const RawBank& bank ) { return bank.sourceID() & HltTrackReportsWriter::kSourceID_MinorMask; }
-  static const std::vector<std::string> DefaultLabels = {"Velo", "VeloTTHPT", "ForwardHPT"};
-
-  template <typename StringContainer>
-  std::vector<std::string> prefix( const std::string& prefix, const StringContainer& strs ) {
-    std::vector<std::string> vs;
-    vs.reserve( strs.size() );
-    std::transform( strs.begin(), strs.end(), std::back_inserter( vs ),
-                    [&]( const std::string& s ) { return prefix + "/" + s; } );
-    return vs;
-  }
-} // namespace
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : HltTrackReportsDecoder
-//
-// The actual decoding of tracks is delegated
-// to the functions in HltTrackingCoder.
-//
-// 2014-01-16 : Sebastian Neubert
-//-----------------------------------------------------------------------------
-
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT( HltTrackReportsDecoder )
-
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-HltTrackReportsDecoder::HltTrackReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator )
-    : HltRawBankSplittingDecoder<LHCb::Tracks>(
-          name, pSvcLocator,
-          KeyValue{"RawEventLocations", Gaudi::Functional::concat_alternatives( LHCb::RawEventLocation::Trigger,
-                                                                                LHCb::RawEventLocation::Copied,
-                                                                                LHCb::RawEventLocation::Default )},
-          KeyValues{"OutputHltTrackReportsLocation", prefix( "Hlt/Track", DefaultLabels )} ) {
-  declareProperty( "OutputSourceId", m_map = {1, 2, 4} );
-}
-
-//=============================================================================
-// Initialization
-//=============================================================================
-StatusCode HltTrackReportsDecoder::initialize() {
-  StatusCode sc = Decoder::AlgBase::initialize(); // must be executed first
-  if ( sc.isFailure() ) return sc;                // error printed already by GaudiAlgorithm
-
-  // Check validity of source IDs: max is 7, must be unique...
-  if ( std::any_of( std::begin( m_map ), std::end( m_map ),
-                    []( unsigned entry ) { return entry > HltTrackReportsWriter::kSourceID_Max; } ) ) {
-    return Error( "Illegal SourceID specified; maximal allowed value is 7", StatusCode::FAILURE );
-  }
-
-  std::vector<unsigned> ids = m_map;
-  std::sort( std::begin( ids ), std::end( ids ) );
-  if ( std::unique( std::begin( ids ), std::end( ids ) ) != std::end( ids ) ) {
-    return Error( "Duplicate SourceID specified", StatusCode::FAILURE );
-  }
-  return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-// Main execution
-//=============================================================================
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-variable"
-
-Gaudi::Functional::vector_of_optional_<Tracks> HltTrackReportsDecoder::
-                                               operator()( const LHCb::RawEvent& rawEvent ) const {
-  ++m_callcount;
-
-  // ----------------------------------------------------------
-  // get the bank from RawEvent
-  // ----------------------------------------------------------
-  const auto&                 htr_banks = rawEvent.banks( RawBank::HltTrackReports );
-  std::vector<const RawBank*> hltTrackReportsRawBanks = {htr_banks.begin(), htr_banks.end()};
-
-  // check for bad banks:
-  hltTrackReportsRawBanks.erase(
-      std::remove_if(
-          std::begin( hltTrackReportsRawBanks ), std::end( hltTrackReportsRawBanks ),
-          [=]( const RawBank* bank ) {
-            if ( bank->magic() != RawBank::MagicPattern ) {
-              Warning( " HltTrackReports RawBank has wrong magic number. Skipped ", StatusCode::SUCCESS, 20 ).ignore();
-              return true;
-            }
-            return false;
-          } ),
-      std::end( hltTrackReportsRawBanks ) );
-
-  // sort by sourceID ( which is 'origin << somebits | sequential number' )
-  std::sort( begin( hltTrackReportsRawBanks ), end( hltTrackReportsRawBanks ),
-             [=]( const RawBank* lhs, const RawBank* rhs ) { return lhs->sourceID() < rhs->sourceID(); } );
-
-  // TODO: add some counters to track how many tracks per source ID per event...
-  auto                                           indx = 0;
-  Gaudi::Functional::vector_of_optional_<Tracks> outputs( m_map.size() );
-  for ( const auto& entry : m_map ) {
-    auto& outputTracks = outputs[indx++];
-
-    auto range =
-        std::equal_range( begin( hltTrackReportsRawBanks ), end( hltTrackReportsRawBanks ), entry, cmp_sourceID );
-    // if there is a valid bank, create the output -- even if it is an empty bank...
-    // (which results in an empty output ;-). If there is no bank, then do NOT
-    // create the output...
-    if ( range.first == range.second ) {
-      // warning() << "Empty bank " << entry.first << endmsg;
-      continue;
-    }
-
-    // map source id -> index of outputs
-
-    outputTracks.emplace(); // create an empty container!
-
-    // verify all present in expected order...
-    bool ok = true;
-    std::accumulate( range.first, range.second, 0, [&ok]( int i, const RawBank* b ) {
-      ok = ok && i == seq( *b );
-      return ++i;
-    } );
-    if ( !ok )
-      throw GaudiException( "Missing Sequential HltTrackReports RawBank part - quiting.", name(), StatusCode::SUCCESS );
-
-    // figure out the total size -- zero length (i.e. empty) bank is NOT an error
-    unsigned int bankSize = std::accumulate( range.first, range.second, 0u, []( unsigned int s, const RawBank* bank ) {
-      return s + std::distance( bank->begin<unsigned int>(), bank->end<unsigned int>() );
-    } );
-    if ( std::distance( range.first, range.second ) == 1 ) {
-      // avoid allocating and copying the rawbank if there is only a single one...
-      // do the actual decoding: see HltTrackingCoder.cpp
-      decodeTracks( ( *range.first )->data(), bankSize, *outputTracks );
-    } else {
-      // concatenate banks into a local array
-      std::vector<unsigned int> completeBank( bankSize );
-      auto                      p =
-          std::accumulate( range.first, range.second, completeBank.data(), []( unsigned int* p, const RawBank* bank ) {
-            return std::copy( bank->begin<unsigned int>(), bank->end<unsigned int>(), p );
-          } );
-      assert( std::distance( completeBank.data(), p ) == bankSize );
-      // do the actual decoding: see HltTrackingCoder.cpp
-      decodeTracks( completeBank.data(), bankSize, *outputTracks );
-    }
-
-    counter( std::to_string( entry ) ) += outputTracks->size();
-    // for debug purposes print the contents of the outputLocation
-    if ( msgLevel( MSG::VERBOSE ) ) {
-      verbose() << "----------------------------------------\n";
-      verbose() << "Decoded event " << m_callcount << endmsg;
-      verbose() << "Decoding source id " << entry << endmsg;
-      verbose() << outputTracks->size() << " Resurrected tracks: \n";
-      std::for_each( std::begin( *outputTracks ), std::end( *outputTracks ), [&]( const LHCb::Track* track ) {
-        verbose() << *track << endmsg;
-        verbose() << "LHCbIDs: [\n";
-        std::for_each( std::begin( track->lhcbIDs() ), std::end( track->lhcbIDs() ),
-                       [&]( const LHCb::LHCbID& id ) { verbose() << id << ",\n"; } );
-        verbose() << "]" << endmsg;
-      } );
-    }
-  }
-  return outputs;
-}
-#pragma GCC diagnostic pop
diff --git a/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.h b/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.h
deleted file mode 100644
index 7a6542ed1cf1e11ac919439a63268cb74c67f473..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltTrackReportsDecoder.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTTRACKREPORTSDECODER_H
-#define HLTTRACKREPORTSDECODER_H 1
-
-// Include files
-#include <atomic>
-// from Gaudi
-#include "Event/Track.h"
-#include "HltRawBankDecoderBase.h"
-
-/** @class HltTrackReportsDecoder HltTrackReportsDecoder.h
- *
- *
- *  @author Sebastian Neubert
- *  @date   2014-01-16
- *
- *  Algorithm to read HltTracks from Raw Data and create containers on TES
- *
- */
-class HltTrackReportsDecoder : public HltRawBankSplittingDecoder<LHCb::Tracks> {
-public:
-  enum HeaderIDs { kVersionNumber = 1 };
-
-  /// Standard constructor
-  HltTrackReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator );
-
-  ///< Algorithm initialization
-  StatusCode initialize() override;
-
-  ///< Algorithm execution
-  Gaudi::Functional::vector_of_optional_<LHCb::Tracks> operator()( const LHCb::RawEvent& ) const override;
-
-private:
-  /// location of HltTrackReports
-  StringProperty m_HltTrackReportsLocation;
-
-  /// SourceID to decode. source ids are linked to track stages in TrackNames.trackingSources
-  std::vector<unsigned> m_map;
-
-  mutable std::atomic<unsigned int> m_callcount{0};
-};
-
-#endif // HLTTRACKREPORTSDECODER_H
diff --git a/Hlt/HltDAQ/src/component/HltTrackReportsWriter.cpp b/Hlt/HltDAQ/src/component/HltTrackReportsWriter.cpp
deleted file mode 100644
index 683d02ff0835bd3bd170ac646a838f063fc40c50..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltTrackReportsWriter.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-// Include files
-
-#include "Event/RawEvent.h"
-#include "Event/Track.h"
-#include "HltDAQ/HltTrackingCoder.h"
-#include <algorithm>
-
-// local
-#include "HltTrackReportsWriter.h"
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : HltTrackReportsWriter
-//
-// 2014-1-10 : Sebastian Neubert
-//-----------------------------------------------------------------------------
-
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT( HltTrackReportsWriter )
-
-using namespace LHCb;
-namespace {
-
-  struct select2nd_t {
-    template <typename U, typename V>
-    const V& operator()( const std::pair<U, V>& p ) const {
-      return p.second;
-    }
-  };
-  inline constexpr select2nd_t select2nd{};
-
-} // namespace
-
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-HltTrackReportsWriter::HltTrackReportsWriter( const std::string& name, ISvcLocator* pSvcLocator )
-    : GaudiAlgorithm( name, pSvcLocator ), m_callcount{0u} {
-  declareProperty( "Input2SourceId", m_map = {{"Hlt/Track/Velo", kSourceID_Hlt1_Velo},
-                                              {"Hlt/Track/ForwardHPT", kSourceID_Hlt1_ForwardHPT},
-                                              {"Hlt/Track/VeloTTHPT", kSourceID_Hlt1_VeloTT}} );
-  declareProperty( "OutputRawEventLocation", m_outputRawEventLocation = LHCb::RawEventLocation::Default );
-  declareProperty( "WriteStates", m_writeStates = true );
-}
-
-//=============================================================================
-// Initialization
-//=============================================================================
-StatusCode HltTrackReportsWriter::initialize() {
-  StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first
-  if ( sc.isFailure() ) return sc;              // error printed already by GaudiAlgorithm
-
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg;
-
-  // Check validity of source IDs: max is 7, must be unique...
-  if ( std::any_of( std::begin( m_map ), std::end( m_map ), []( const std::pair<std::string, int>& entry ) {
-         return entry.second > kSourceID_Max || entry.second < 0;
-       } ) ) {
-    return Error( "Illegal SourceID specified; maximal allowed value is 7", StatusCode::FAILURE );
-  }
-
-  std::vector<unsigned> ids;
-  ids.reserve( m_map.size() );
-  std::transform( std::begin( m_map ), std::end( m_map ), std::back_inserter( ids ), select2nd );
-  std::sort( std::begin( ids ), std::end( ids ) );
-  if ( std::unique( std::begin( ids ), std::end( ids ) ) != std::end( ids ) ) {
-    return Error( "Duplicate SourceID specified", StatusCode::FAILURE );
-  }
-
-  return StatusCode::SUCCESS;
-}
-
-//=============================================================================
-// Main execution
-//=============================================================================
-StatusCode HltTrackReportsWriter::execute() {
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg;
-  ++m_callcount;
-
-  // get output
-  RawEvent* rawEvent = getOrCreate<RawEvent, RawEvent>( m_outputRawEventLocation );
-
-  for ( const auto& entry : m_map ) convert( entry.first, entry.second, rawEvent );
-  return StatusCode::SUCCESS;
-}
-
-void HltTrackReportsWriter::convert( const std::string& location, unsigned sourceID, RawEvent* rawEvent ) const {
-  // get input
-  const LHCb::Tracks* inputTracks = getIfExists<LHCb::Tracks>( location );
-
-  if ( !inputTracks ) {
-    Warning( " No container at " + location, StatusCode::SUCCESS, 0 ).ignore();
-    return;
-  }
-
-  if ( msgLevel( MSG::VERBOSE ) ) {
-    verbose() << "----------------------------------------\n";
-    verbose() << " Written event " << m_callcount << endmsg;
-    verbose() << " Input tracks at " << location << "  -> source ID " << sourceID << "\n";
-    for ( const auto& i : *inputTracks ) {
-      verbose() << *i << endmsg;
-      // also dump IDs
-      verbose() << "LHCbIDs: [\n";
-      for ( const auto& id : i->lhcbIDs() ) verbose() << id << ",\n";
-      verbose() << "]" << endmsg;
-    }
-    verbose() << "\n----------------------------------------" << endmsg;
-  }
-
-  // compose the bank body
-  std::vector<unsigned int> bankBody;
-
-  // calling core encoder function see src/core/HltTrackingCoder.cxx
-  encodeTracks( *inputTracks, bankBody, m_writeStates );
-
-  // RawBank is limited in size to 65535 bytes i.e. 16383 words; be conservative cut it
-  // off at a smaller limit.
-  // Save in chunks if exceed this size.
-  // make sure that for an empty bank we write 1 bank...
-  int nBank = 1 + ( bankBody.empty() ? 0 : ( ( bankBody.size() - 1 ) / 16300 ) );
-  if ( nBank > kSourceID_MinorMask ) {
-    Warning( "HltTrackReports too large to save", StatusCode::SUCCESS, 50 ).ignore();
-    return;
-  }
-  for ( int iBank = 0; iBank < nBank; ++iBank ) {
-    int  ioff  = iBank * 16300;
-    auto isize = std::min( bankBody.size() - ioff, 16300ul );
-    rawEvent->addBank( ( sourceID << kSourceID_BitShift ) | iBank, RawBank::HltTrackReports, kVersionNumber,
-                       LHCb::make_span( bankBody ).subspan( ioff, isize ) );
-  }
-  if ( msgLevel( MSG::DEBUG ) && nBank > 1 ) {
-    debug() << "HltTrackReports is huge. Saved in " << nBank << " separate RawBanks " << endmsg;
-  }
-}
diff --git a/Hlt/HltDAQ/src/component/HltTrackReportsWriter.h b/Hlt/HltDAQ/src/component/HltTrackReportsWriter.h
deleted file mode 100644
index 21f89dcdea94c6cb9c1e14b8dd890f981182352c..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltTrackReportsWriter.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTTRACKREPORTSWRITER_H
-#define HLTTRACKREPORTSWRITER_H 1
-
-// Include files
-// from Gaudi
-#include "GaudiAlg/GaudiAlgorithm.h"
-
-namespace LHCb {
-  class RawEvent;
-}
-/** @class HltTrackReportsWriter HltTrackReportsWriter.h
- *
- *
- *  @author Sebastian Neubert
- *  @date   2014-01-10
- *
- *  Algorithm to convert Track containers on TES to HLT Raw Bank
- *
- *  Encoding of track information into RawBank
- *  For each track:
- *  (nLhHCbIDs, ID0, ID1, ... IDn)
- *
- *  tracks are just concatenated
- *
- */
-class HltTrackReportsWriter : public GaudiAlgorithm {
-public:
-  enum HeaderIDs { kVersionNumber = 1 };
-
-  enum SourceIDs {
-    kSourceID_Dummy              = 0,
-    kSourceID_Hlt                = kSourceID_Dummy,
-    kSourceID_Hlt1_Velo          = 1,
-    kSourceID_Hlt1_VeloTT        = 2,
-    kSourceID_Hlt1_Forward       = 3,
-    kSourceID_Hlt1_ForwardFitted = 5,
-    kSourceID_Hlt1_ForwardHPT    = 4,
-    kSourceID_Max                = 7,
-    kSourceID_BitShift           = 11, // will need bitshifting to distinguish minor and major sourceIDs
-    kSourceID_MinorMask          = 0x7FF,
-    kSourceID_MajorMask          = 0x3800
-  };
-
-  /// Standard constructor
-  HltTrackReportsWriter( const std::string& name, ISvcLocator* pSvcLocator );
-
-  ~HltTrackReportsWriter() override = default; ///< Destructor
-
-  StatusCode initialize() override; ///< Algorithm initialization
-  StatusCode execute() override;    ///< Algorithm execution
-
-private:
-  void convert( const std::string& location, unsigned sourceID, LHCb::RawEvent* rawEvent ) const;
-
-  /// mapping of input TES location to output bank header source ID
-  std::map<std::string, int> m_map;
-
-  /// location of output
-  StringProperty m_outputRawEventLocation;
-
-  /// Save track states or not
-  bool m_writeStates;
-
-  unsigned int m_callcount;
-};
-#endif // HLTDECREPORTSWRITER_H
diff --git a/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.cpp b/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.cpp
index 73faaad4cf6ff11b4047636fbcf202071eb62cf5..4090fcea0ca993262ac7612bd28b68eb50fd0c79 100644
--- a/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.cpp
+++ b/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.cpp
@@ -8,16 +8,12 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-#include <memory>
-
 #include "Event/HltVertexReports.h"
 #include "Event/RawEvent.h"
-
-// local
-#include "HltVertexReportsDecoder.h"
-#include "HltVertexReportsWriter.h"
+#include "Event/VertexBase.h"
+#include "HltRawBankDecoderBase.h"
 #include "LHCbMath/bit_cast.h"
+#include <memory>
 
 namespace {
   static const std::vector<std::string> DefaultLabels = {"PV3D", "ProtoPV3D"};
@@ -47,6 +43,29 @@ using namespace LHCb;
 // 2008-08-05 : Tomasz Skwarnicki
 //-----------------------------------------------------------------------------
 
+/** @class HltvertexReportsDecoder HltvertexReportsDecoder.h
+ *
+ *  @author Tomasz Skwarnicki
+ *  @date   2008-08-05
+ *
+ *  Algorithm to translate HltSummary  into HltVertexReports
+ *
+ */
+class HltVertexReportsDecoder : public HltRawBankSplittingDecoder<LHCb::VertexBase::Container> {
+public:
+  enum HeaderIDs { kVersionNumber = 2 };
+
+  /// Standard constructor
+  HltVertexReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator );
+
+  ///< Algorithm execution
+  Gaudi::Functional::vector_of_optional_<LHCb::VertexBase::Container>
+  operator()( const LHCb::RawEvent& ) const override;
+
+private:
+  std::vector<std::string> m_decode; /// which containers to decode
+};
+
 // Declaration of the Algorithm Factory
 DECLARE_COMPONENT( HltVertexReportsDecoder )
 
@@ -59,7 +78,8 @@ HltVertexReportsDecoder::HltVertexReportsDecoder( const std::string& name, ISvcL
           KeyValue{"RawEventLocations", Gaudi::Functional::concat_alternatives( LHCb::RawEventLocation::Trigger,
                                                                                 LHCb::RawEventLocation::Copied,
                                                                                 LHCb::RawEventLocation::Default )},
-          KeyValues{"OutputHltVertexLocations", prefix( LHCb::HltVertexReportsLocation::Default, DefaultLabels )} ) {
+          KeyValues{"OutputHltVertexReportsLocations",
+                    prefix( LHCb::HltVertexReportsLocation::Default, DefaultLabels )} ) {
   declareProperty( "Decode", m_decode = DefaultLabels, "List of containers to decode" );
   // TODO: verify/guarantee the match between 'Decode' and 'OutputHltVertexReportsLocation'...
 }
diff --git a/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.h b/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.h
deleted file mode 100644
index 512082ccdd5c0cf57632850039a96f4ce992a7cb..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltVertexReportsDecoder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTVERTEXREPORTSDECODER_H
-#define HLTVERTEXREPORTSDECODER_H 1
-
-#include "HltRawBankDecoderBase.h"
-
-#include "Event/VertexBase.h"
-
-/** @class HltvertexReportsDecoder HltvertexReportsDecoder.h
- *
- *  @author Tomasz Skwarnicki
- *  @date   2008-08-05
- *
- *  Algorithm to translate HltSummary  into HltVertexReports
- *
- */
-class HltVertexReportsDecoder : public HltRawBankSplittingDecoder<LHCb::VertexBase::Container> {
-public:
-  enum HeaderIDs { kVersionNumber = 2 };
-
-  /// Standard constructor
-  HltVertexReportsDecoder( const std::string& name, ISvcLocator* pSvcLocator );
-
-  ///< Algorithm execution
-  Gaudi::Functional::vector_of_optional_<LHCb::VertexBase::Container>
-  operator()( const LHCb::RawEvent& ) const override;
-
-private:
-  std::vector<std::string> m_decode; /// which containers to decode
-};
-
-#endif // HLTVERTEXREPORTSDECODER_H
diff --git a/Hlt/HltDAQ/src/component/HltVertexReportsWriter.cpp b/Hlt/HltDAQ/src/component/HltVertexReportsWriter.cpp
index 7afa47f1625ad67081ed313ae6dabd82c4efc0be..62230fa900fdf86c4f8012f044f7732d058f34cf 100644
--- a/Hlt/HltDAQ/src/component/HltVertexReportsWriter.cpp
+++ b/Hlt/HltDAQ/src/component/HltVertexReportsWriter.cpp
@@ -8,14 +8,13 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-
 #include "Event/HltVertexReports.h"
 #include "Event/RawEvent.h"
-
-// local
-#include "HltVertexReportsWriter.h"
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "HltSourceID.h"
+#include "Kernel/IANNSvc.h"
 #include "LHCbMath/bit_cast.h"
+#include <optional>
 
 using namespace LHCb;
 
@@ -23,6 +22,7 @@ namespace {
 
   static const Gaudi::StringKey Hlt1SelectionID{"Hlt1SelectionID"};
   static const Gaudi::StringKey Hlt2SelectionID{"Hlt2SelectionID"};
+  static const Gaudi::StringKey SpruceSelectionID{"SpruceSelectionID"};
 
 } // namespace
 
@@ -32,6 +32,46 @@ namespace {
 // 2008-08-05 : Tomasz Skwarnicki
 //-----------------------------------------------------------------------------
 
+/** @class HltvertexReportsWriter HltvertexReportsWriter.h
+ *
+ *  @author Tomasz Skwarnicki
+ *  @date   2008-08-05
+ *
+ *  Algorithm to translate HltSummary  into HltVertexReports
+ *
+ */
+class HltVertexReportsWriter : public GaudiAlgorithm {
+public:
+  enum HeaderIDs { kVersionNumber = 2 };
+
+  /// Standard constructor
+  using GaudiAlgorithm::GaudiAlgorithm;
+
+  StatusCode initialize() override; ///< Algorithm initialization
+  StatusCode execute() override;    ///< Algorithm execution
+
+private:
+  // ----------------------- methods
+
+  std::optional<int> selectionNameToInt( const IANNSvc& ann, const std::string& name ) const;
+
+  // ----------------------- data members
+
+  /// location of input
+  Gaudi::Property<std::string> m_inputHltVertexReportsLocation{this, "InputHltVertexReportsLocation",
+                                                               LHCb::HltVertexReportsLocation::Default};
+
+  /// location of output
+  Gaudi::Property<std::string> m_outputRawEventLocation{this, "OutputRawEventLocation",
+                                                        LHCb::RawEventLocation::Default};
+
+  /// SourceID to insert in the bank header
+  Gaudi::Property<SourceIDs> m_sourceID{this, "SourceID", SourceIDs::Dummy};
+
+  /// HltANNSvc for making selection names to int selection ID
+  SmartIF<IANNSvc> m_hltANNSvc;
+};
+
 // Declaration of the Algorithm Factory
 DECLARE_COMPONENT( HltVertexReportsWriter )
 
@@ -46,11 +86,7 @@ StatusCode HltVertexReportsWriter::initialize() {
 
   m_hltANNSvc = service( "HltANNSvc" );
 
-  if ( m_sourceID > kSourceID_Max || m_sourceID < 0 ) {
-    return Error( "Illegal SourceID specified; maximal allowed value is 7", StatusCode::FAILURE );
-  }
-
-  return StatusCode::SUCCESS;
+  return sc;
 }
 
 //=============================================================================
@@ -114,18 +150,18 @@ StatusCode HltVertexReportsWriter::execute() {
   // delete any previously inserted vtx reports
   const auto& bnks = rawEvent->banks( RawBank::HltVertexReports );
   for ( const auto& b : std::vector( bnks.begin(), bnks.end() ) ) {
-    auto sourceID = b->version() > 1 ? ( b->sourceID() >> kSourceID_BitShift ) : kSourceID_Hlt;
+    auto sourceID = b->version() > 1 ? static_cast<SourceIDs>( b->sourceID() >> SourceIDs::BitShift ) : SourceIDs::Hlt;
     if ( m_sourceID != sourceID ) continue;
     rawEvent->removeBank( b );
     warning() << " Deleted previously inserted HltVertexReports bank " << endmsg;
   }
   // shift bits in sourceID for the same convention as in HltSelReports
-  rawEvent->addBank( int( m_sourceID << kSourceID_BitShift ), RawBank::HltVertexReports, kVersionNumber,
+  rawEvent->addBank( int( m_sourceID.value() << SourceIDs::BitShift ), RawBank::HltVertexReports, kVersionNumber,
                      hltVertexReportsRawBank );
   if ( msgLevel( MSG::VERBOSE ) ) {
     verbose() << " ======= HltVertexReports RawBank size= " << hltVertexReportsRawBank.size() << endmsg;
     verbose() << " VersionNumber= " << kVersionNumber;
-    verbose() << " SourceID= " << m_sourceID;
+    verbose() << " SourceID= " << m_sourceID.value();
     verbose() << " number of selections stored = " << hltVertexReportsRawBank[0] << endmsg;
     unsigned int iWord = 1;
     for ( unsigned int i = 0; i != hltVertexReportsRawBank[0]; ++i ) {
@@ -155,17 +191,17 @@ StatusCode HltVertexReportsWriter::execute() {
 //=============================================================================
 std::optional<int> HltVertexReportsWriter::selectionNameToInt( const IANNSvc& ann, const std::string& name ) const {
   std::optional<IANNSvc::minor_value_type> v{};
-  switch ( m_sourceID ) {
-  case kSourceID_Hlt1:
+  switch ( m_sourceID.value() ) {
+  case SourceIDs::Hlt1:
     v = ann.value( Hlt1SelectionID, name );
     break;
-  case kSourceID_Hlt2:
+  case SourceIDs::Hlt2:
     v = ann.value( Hlt2SelectionID, name );
     break;
-  case kSourceID_Hlt:
-    v = ann.value( Hlt1SelectionID, name );
-    if ( !v ) v = ann.value( Hlt2SelectionID, name );
+  case SourceIDs::Spruce:
+    v = ann.value( SpruceSelectionID, name );
     break;
+  default: /* nothing */;
   }
   return v ? std::optional<int>{v->second} : std::optional<int>{};
 }
diff --git a/Hlt/HltDAQ/src/component/HltVertexReportsWriter.h b/Hlt/HltDAQ/src/component/HltVertexReportsWriter.h
deleted file mode 100644
index 97f4f39c70c40428e7a9ce4a359827d88d217008..0000000000000000000000000000000000000000
--- a/Hlt/HltDAQ/src/component/HltVertexReportsWriter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#ifndef HLTVERTEXREPORTSWRITER_H
-#define HLTVERTEXREPORTSWRITER_H 1
-
-#include "Event/HltVertexReports.h"
-#include "Event/RawEvent.h"
-#include "Kernel/IANNSvc.h"
-
-#include "GaudiAlg/GaudiAlgorithm.h"
-
-#include <optional>
-
-/** @class HltvertexReportsWriter HltvertexReportsWriter.h
- *
- *  @author Tomasz Skwarnicki
- *  @date   2008-08-05
- *
- *  Algorithm to translate HltSummary  into HltVertexReports
- *
- */
-class HltVertexReportsWriter : public GaudiAlgorithm {
-public:
-  enum HeaderIDs { kVersionNumber = 2 };
-
-  enum SourceIDs {
-    kSourceID_Dummy     = 0,
-    kSourceID_Hlt       = kSourceID_Dummy,
-    kSourceID_Hlt1      = 1,
-    kSourceID_Hlt2      = 2,
-    kSourceID_Max       = 7,
-    kSourceID_BitShift  = 13,
-    kSourceID_MinorMask = 0x1FFF,
-    kSourceID_MajorMask = 0xE000
-  };
-
-  /// Standard constructor
-  using GaudiAlgorithm::GaudiAlgorithm;
-
-  ~HltVertexReportsWriter() override = default; ///< Destructor
-
-  StatusCode initialize() override; ///< Algorithm initialization
-  StatusCode execute() override;    ///< Algorithm execution
-
-private:
-  // ----------------------- methods
-
-  std::optional<int> selectionNameToInt( const IANNSvc& ann, const std::string& name ) const;
-
-  // ----------------------- data members
-
-  /// location of input
-  Gaudi::Property<std::string> m_inputHltVertexReportsLocation{this, "InputHltVertexReportsLocation",
-                                                               LHCb::HltVertexReportsLocation::Default};
-
-  /// location of output
-  Gaudi::Property<std::string> m_outputRawEventLocation{this, "OutputRawEventLocation",
-                                                        LHCb::RawEventLocation::Default};
-
-  /// SourceID to insert in the bank header
-  Gaudi::Property<int> m_sourceID{this, "SourceID", kSourceID_Dummy};
-
-  /// HltANNSvc for making selection names to int selection ID
-  SmartIF<IANNSvc> m_hltANNSvc;
-};
-
-#endif // HLTVERTEXREPORTSWRITER_H
diff --git a/Hlt/HltDAQ/src/component/RoutingBitsWriter.cpp b/Hlt/HltDAQ/src/component/RoutingBitsWriter.cpp
index d226ad87453a7502e64bdde5bc3500078085fe1d..6f2c4d0b5f977dbf3b54ced96ae8c8425b01bcae 100644
--- a/Hlt/HltDAQ/src/component/RoutingBitsWriter.cpp
+++ b/Hlt/HltDAQ/src/component/RoutingBitsWriter.cpp
@@ -9,15 +9,12 @@
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
 // from Gaudi
-#include "GaudiKernel/Algorithm.h"
-#include "GaudiKernel/DataObjectHandle.h"
-#include "GaudiKernel/GaudiException.h"
-#include "GaudiKernel/ParsersFactory.h"
-
 #include "Event/HltDecReports.h"
 #include "Event/ODIN.h"
-
 #include "Event/RawEvent.h"
+#include "GaudiKernel/DataObjectHandle.h"
+#include "GaudiKernel/ParsersFactory.h"
+#include "LHCbAlgs/Consumer.h"
 
 /** @class RoutingBitsWriter RoutingBitsWriter.h
  *  @brief Write routing bits based on ODIN flags and DecReports into raw event.
@@ -42,20 +39,10 @@
  *  @endcode
  */
 
-namespace Hlt {
-  class RoutingBitsWriter : public Gaudi::Algorithm {
-  public:
-    /// Standard constructor
-    using Gaudi::Algorithm::Algorithm;
-
-    StatusCode execute( EventContext const& ) const override; ///< Algorithm execution
-
-  private:
+namespace LHCb::Hlt::DAQ {
+  class RoutingBitsWriter : public Algorithm::Consumer<void( LHCb::ODIN const&, LHCb::HltDecReports const& )> {
     enum { nBits = 3 * sizeof( unsigned int ) * 8 };
 
-    DataObjectReadHandle<LHCb::ODIN>          m_odin{this, "ODIN", ""};
-    DataObjectReadHandle<LHCb::HltDecReports> m_dec_reports{this, "DecReports", ""};
-
     DataObjectWriteHandle<LHCb::RawEvent> m_raw_event{this, "RawEventLocation", LHCb::RawEventLocation::Default};
 
     Gaudi::Property<std::map<unsigned int, std::vector<std::string>>> m_bits{
@@ -69,41 +56,41 @@ namespace Hlt {
             }
           }
         }};
-  };
-} // namespace Hlt
-
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT( Hlt::RoutingBitsWriter )
-
-namespace Hlt {
 
-  //=============================================================================
-  // Main execution
-  //=============================================================================
-  StatusCode RoutingBitsWriter::execute( EventContext const& ) const {
-    // auto const* odin        = m_odin.get();
-    // TODO: Add evaluators of odin bits
-    auto const* dec_reports = m_dec_reports.get();
-
-    // The routing bits
-    std::vector<unsigned int> bits( 3, 0 );
-
-    // Evaluate the routing bits
-    for ( auto const& entry : m_bits ) {
-      auto result = std::any_of( begin( entry.second ), end( entry.second ), [&dec_reports]( auto const& line ) {
-        auto const* dec_report = dec_reports->decReport( line );
-        if ( dec_report == nullptr ) { return false; }
-        return dec_report->decision() == 1;
-      } );
-      auto bit    = entry.first;
-      int  word   = bit / 32;
-      if ( result ) bits[word] |= ( 0x01UL << ( bit - 32 * word ) );
+  public:
+    /// Standard constructor
+    RoutingBitsWriter( const std::string& name, ISvcLocator* pSvcLocator )
+        : Consumer{name, pSvcLocator, {KeyValue{"ODIN", ""}, KeyValue{"DecReports", ""}}} {}
+
+    void operator()( LHCb::ODIN const&, LHCb::HltDecReports const& dec_reports ) const override {
+      // TODO: Add evaluators of odin bits
+
+      // The routing bits
+      std::array<unsigned int, 3> bits{0, 0, 0};
+
+      // Evaluate the routing bits
+      for ( auto const& entry : m_bits ) {
+        auto result = std::any_of( begin( entry.second ), end( entry.second ), [&dec_reports]( auto const& line ) {
+          auto const* dec_report = dec_reports.decReport( line );
+          return dec_report && dec_report->decision() == 1;
+        } );
+        auto bit    = entry.first;
+        int  word   = bit / 32;
+        if ( result ) bits[word] |= ( 0x01UL << ( bit - 32 * word ) );
+      }
+
+      // Get the raw event and add the routing bits bank.
+      auto rawEvent = m_raw_event.getOrCreate();
+      rawEvent->addBank( 0, LHCb::RawBank::HltRoutingBits, 0, bits );
     }
+  };
+} // namespace LHCb::Hlt::DAQ
 
-    // Get the raw event and add the routing bits bank.
-    auto rawEvent = m_raw_event.getOrCreate();
-    rawEvent->addBank( 0, LHCb::RawBank::HltRoutingBits, 0, bits );
-
-    return StatusCode::SUCCESS;
-  }
-} // namespace Hlt
\ No newline at end of file
+namespace Hlt {
+  // keep backwards compatible for now
+  struct RoutingBitsWriter : LHCb::Hlt::DAQ::RoutingBitsWriter {
+    using LHCb::Hlt::DAQ::RoutingBitsWriter::RoutingBitsWriter;
+  };
+  // Declaration of the Algorithm Factory
+  DECLARE_COMPONENT( Hlt::RoutingBitsWriter )
+} // namespace Hlt
diff --git a/Hlt/HltDAQ/tests/options/OnlyHltBanks.mdf b/Hlt/HltDAQ/tests/options/OnlyHltBanks.mdf
deleted file mode 100644
index 3a0484a139ba523ec8550a3de586d5bde13f222b..0000000000000000000000000000000000000000
Binary files a/Hlt/HltDAQ/tests/options/OnlyHltBanks.mdf and /dev/null differ
diff --git a/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode.py b/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode.py
index a8b712e7a38bf0a93d352c0e45d257414c362b5e..ad5088ea1a461cb6d5e9c748172bad2f043cc0d4 100644
--- a/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode.py
+++ b/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode.py
@@ -36,12 +36,14 @@ IODataManager().DisablePFNWarning = True
 
 dump.RawBanks.append("HltSelReports")
 decoders.Members.append("HltSelReportsDecoder")
-encoders.Members.append(HltSelReportsWriter(RawEvent=NEW_RAW_EVENT_LOC))
+encoders.Members.append(
+    HltSelReportsWriter(RawEvent=NEW_RAW_EVENT_LOC, SourceID='Hlt1'))
 
 dump.RawBanks.append("HltDecReports")
 decoders.Members.append("HltDecReportsDecoder")
 encoders.Members.append(
-    HltDecReportsWriter(OutputRawEventLocation=NEW_RAW_EVENT_LOC))
+    HltDecReportsWriter(
+        OutputRawEventLocation=NEW_RAW_EVENT_LOC, SourceID='Hlt1'))
 
 from Configurables import HltANNSvc
 HltANNSvc().Hlt1SelectionID = {'PV3D': 10103, 'ProtoPV3D': 10117}
@@ -58,6 +60,7 @@ IOHelper('MDF', 'MDF').outStream(
 
 #inputfile
 from PRConfig import TestFileDB
-TestFileDB.test_file_db["2012_raw_default"].run()
+tf = TestFileDB.test_file_db["2015_raw_full"]
+tf.run()
 from GaudiConf import IOExtension
-IOExtension().inputFiles(["../options/OnlyHltBanks.mdf"], clear=True)
+IOExtension().inputFiles(tf.filenames, clear=True)
diff --git a/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode_split.py b/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode_split.py
index 94382faac7e73b376e5f8683f2cca1ae2ef7ede4..bddc21f81383903d665f76dd06e48d5d55619964 100644
--- a/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode_split.py
+++ b/Hlt/HltDAQ/tests/options/dump_decode_wipe_encode_split.py
@@ -31,10 +31,15 @@ import Configurables
 from Configurables import IODataManager
 IODataManager().DisablePFNWarning = True
 
+
+def propertyName(io, t):
+    if t == 'Sel' and io == 'Input': return 'SelReports'
+    return "{0}Hlt{1}ReportsLocation".format(io, t)
+
+
 locs = {"Decoder": "Output", "Writer": "Input"}
 
-#can't do track just yet, can be added easily, though later
-bankTypes = ["Dec", "Sel", "Vertex"]
+bankTypes = ["Dec", "Sel"]
 
 from itertools import product
 for stage, t, (seq, at) in product((1, 2), bankTypes, ((decoders, "Decoder"),
@@ -42,9 +47,16 @@ for stage, t, (seq, at) in product((1, 2), bankTypes, ((decoders, "Decoder"),
     algType = "Hlt{0}Reports{1}".format(t, at)
     algName = "Hlt{0}{1}Reports{2}".format(stage, t, at)
     conf = getattr(Configurables, algType)(algName)
-    conf.SourceID = stage
-    conf.setProp("{0}Hlt{1}ReportsLocation".format(locs[at], t),
-                 "Hlt{0}/{1}Reports".format(stage, t))
+    conf.SourceID = "Hlt{0}".format(stage)
+    conf.setProp(
+        propertyName(locs[at], t), "Hlt{0}/{1}Reports".format(stage, t))
+    if (t == "Sel" and at == "Decoder"):
+        conf.setProp("OutputHltObjectSummariesLocation",
+                     "Hlt{0}/{1}Reports/Candidates".format(stage, t))
+    if (t == "Sel" and at == "Writer"):
+        conf.setProp("DecReports", "Hlt{0}/DecReports".format(stage))
+        conf.setProp("ObjectSummaries", "Hlt{0}/{1}Reports/Candidates".format(
+            stage, t))
     seq.Members.append(conf.getFullName())
 
 for atype in bankTypes:
@@ -69,6 +81,7 @@ IOHelper('MDF', 'MDF').outStream(
 
 #inputfile
 from PRConfig import TestFileDB
-TestFileDB.test_file_db["2012_raw_default"].run()
+tf = TestFileDB.test_file_db["2015_raw_full"]
+tf.run()
 from GaudiConf import IOExtension
-IOExtension().inputFiles(["../options/OnlyHltBanks.mdf"], clear=True)
+IOExtension().inputFiles(tf.filenames, clear=True)
diff --git a/Hlt/HltDAQ/tests/options/sel_reports_stripper.py b/Hlt/HltDAQ/tests/options/sel_reports_stripper.py
index ae82dea72d69c73dd5a3b3e86b790cf4426d47b3..a3feeefdfe048502ec7844b8b62f2a1183b65e31 100644
--- a/Hlt/HltDAQ/tests/options/sel_reports_stripper.py
+++ b/Hlt/HltDAQ/tests/options/sel_reports_stripper.py
@@ -79,7 +79,7 @@ stripper.SelectionNames = [
 stripper.OutputLevel = LEVEL
 
 writer = HltSelReportsWriter('Hlt2SelReportsWriter')
-writer.SourceID = 2
+writer.SourceID = 'Hlt2'
 writer.DecReports = str(decdecoder.OutputHltDecReportsLocation)
 writer.SelReports = str(stripper.OutputHltSelReportsLocation)
 writer.ObjectSummaries = str(stripper.OutputHltObjectSummariesLocation)
diff --git a/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/a_dumptolatestformat.qmt b/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/a_dumptolatestformat.qmt
index 7dd8697d271867eee8cf04a4e4e06253882ade88..aaab19b7e8be2013891b56d405cda65a30e91867 100644
--- a/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/a_dumptolatestformat.qmt
+++ b/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/a_dumptolatestformat.qmt
@@ -12,16 +12,15 @@
 <extension class="GaudiTest.GaudiExeTest" kind="test">
   <argument name="program"><text>gaudirun.py</text></argument>
   <argument name="args"><set>
-    <text>../options/dump_decode_wipe_encode.py</text>
+    <text>../options/dump_decode_wipe_encode_split.py</text>
   </set></argument>
   <argument name="validator"><text>
 
 # Author: rlambert
 # Purpose: to check if bank encoder changes are binary compatible
-# Pre-requisites: the file in ../options/OnlyHltBanks.mdf needs to exist
 # Common failure modes, severities and cures: see dumpafterreformat.qmt
 
-countErrorLines({"FATAL":0, "ERROR":0, "WARNING" :0})
+countErrorLines({"FATAL":0, "ERROR":4, "WARNING" :0})
 
 stdout=[s.strip() for s in stdout.split("\n") if "RawEventDump" in s]