From 8e99e88d5e76f2ecda0d7829154115ef8e17611c Mon Sep 17 00:00:00 2001
From: Tara Nanut <tara.nanut@cern.ch>
Date: Mon, 2 Oct 2023 14:23:19 +0200
Subject: [PATCH] add CaloChargedPID and BremInfo objects to ProtoParticle and
 add packing

---
 Event/EventPacker/CMakeLists.txt              |   1 +
 .../include/Event/PackedCaloChargedInfo_v1.h  | 313 ++++++++++++++++++
 .../include/Event/PackedProtoParticle.h       |  15 +-
 .../Event/PackedSharedObjectsContainer.h      |   6 +
 .../src/component/BufferUnpackerBaseAlg.h     |   1 -
 .../src/component/BufferUnpackers.cpp         |   3 +
 .../src/component/PackedDataChecksum.cpp      |   7 +-
 .../src/component/SelectivePacker.cpp         |   8 +-
 Event/EventPacker/src/component/Traits.h      |  40 ++-
 Event/EventPacker/src/component/Unpackers.cpp |   3 +
 .../src/lib/PackedCaloChargedInfo_v1.cpp      | 211 ++++++++++++
 .../src/lib/PackedProtoParticle.cpp           | 193 ++++++++++-
 Event/RecEvent/dict/dictionary.h              | 209 ++++++------
 Event/RecEvent/dict/selection.xml             |  14 +
 .../include/Event/CaloChargedInfo_v1.h        | 113 ++++++-
 Event/RecEvent/include/Event/ProtoParticle.h  |  65 +++-
 Event/RecEvent/src/ProtoParticle.cpp          |   3 +-
 .../src/ChargedProtoParticleAddCaloInfo.cpp   |  16 +-
 .../src/PrintProtoParticles.cpp               |   2 +
 GaudiConf/python/GaudiConf/reading.py         |   4 +
 PyConf/python/PyConf/packing.py               |  37 ++-
 21 files changed, 1091 insertions(+), 173 deletions(-)
 create mode 100644 Event/EventPacker/include/Event/PackedCaloChargedInfo_v1.h
 create mode 100644 Event/EventPacker/src/lib/PackedCaloChargedInfo_v1.cpp

diff --git a/Event/EventPacker/CMakeLists.txt b/Event/EventPacker/CMakeLists.txt
index 690efae06dc..69d37c7e8ed 100644
--- a/Event/EventPacker/CMakeLists.txt
+++ b/Event/EventPacker/CMakeLists.txt
@@ -19,6 +19,7 @@ gaudi_add_library(EventPackerLib
         src/lib/PackedCaloCluster.cpp
         src/lib/PackedCaloDigit.cpp
         src/lib/PackedCaloHypo.cpp
+        src/lib/PackedCaloChargedInfo_v1.cpp
         src/lib/PackedCluster.cpp
         src/lib/PackedEventChecks.cpp
         src/lib/PackedFlavourTag.cpp
diff --git a/Event/EventPacker/include/Event/PackedCaloChargedInfo_v1.h b/Event/EventPacker/include/Event/PackedCaloChargedInfo_v1.h
new file mode 100644
index 00000000000..850910bb743
--- /dev/null
+++ b/Event/EventPacker/include/Event/PackedCaloChargedInfo_v1.h
@@ -0,0 +1,313 @@
+/*****************************************************************************\
+* (c) Copyright 2023 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/CaloChargedInfo_v1.h"
+#include "Event/PackerBase.h"
+#include "Event/StandardPacker.h"
+
+#include "GaudiKernel/DataObject.h"
+#include "GaudiKernel/StatusCode.h"
+
+#include "fmt/format.h"
+
+#include <cstdint>
+
+namespace LHCb {
+
+  /**
+   *  Packed CaloChargedPID
+   *
+   */
+  struct PackedCaloChargedPID {
+    std::int32_t InAcc{0}; // combined variable for storing bools InEcal and InHcal
+    std::int32_t ClusterID{0};
+    std::int32_t ClusterMatch{0};
+    std::int32_t ElectronID{0};
+    std::int32_t ElectronMatch{0};
+    std::int32_t ElectronEnergy{0};
+    std::int32_t ElectronShowerEoP{0};
+    std::int32_t ElectronShowerDLL{0};
+    std::int32_t EcalPIDe{0};
+    std::int32_t EcalPIDmu{0};
+    std::int32_t HcalEoP{0};
+    std::int32_t HcalPIDe{0};
+    std::int32_t HcalPIDmu{0};
+    std::int64_t key{-1};
+
+#ifndef __CLING__
+    template <typename Buf>
+    void save( Buf& buf ) const {
+      Packer::io( buf, *this );
+    }
+
+    template <typename Buf>
+    void load( Buf& buf, unsigned int /*version*/ ) {
+      Packer::io( buf, *this );
+    }
+#endif
+  };
+
+  constexpr CLID CLID_PackedCaloChargedPIDs = 1572;
+
+  /// Namespace for locations in TDS
+  namespace PackedCaloChargedPIDLocation {
+    inline const std::string Default = "";
+  } // namespace PackedCaloChargedPIDLocation
+
+  /**
+   *  Packed CaloChargedPIDs
+   *
+   */
+  class PackedCaloChargedPIDs : public DataObject {
+
+  public:
+    /// Vector of packed objects
+    typedef std::vector<LHCb::PackedCaloChargedPID> Vector;
+
+    /// Default Packing Version
+    static char defaultPackingVersion() { return 0; }
+
+    /// Class ID
+    static const CLID& classID() { return CLID_PackedCaloChargedPIDs; }
+
+    /// Class ID
+    const CLID& clID() const override { return PackedCaloChargedPIDs::classID(); }
+
+    /// Write access to the data vector
+    Vector& data() { return m_vect; }
+
+    /// Read access to the data vector
+    const Vector& data() const { return m_vect; }
+
+    /// Access the packing version
+    [[nodiscard]] char packingVersion() const { return m_packingVersion; }
+
+    /// Describe serialization of object
+    template <typename T>
+    void save( T& buf ) const {
+      buf.save( static_cast<uint8_t>( m_packingVersion ) );
+      buf.save( static_cast<uint8_t>( version() ) );
+      buf.save( m_vect );
+    }
+
+    /// Describe de-serialization of object
+    template <typename T>
+    void load( T& buf ) {
+      m_packingVersion = buf.template load<uint8_t>();
+      setVersion( buf.template load<uint8_t>() );
+      buf.load( m_vect, m_packingVersion );
+    }
+
+    // Perform unpacking
+    friend StatusCode unpack( Gaudi::Algorithm const*, const PackedCaloChargedPIDs&,
+                              Event::Calo::v1::CaloChargedPIDs& );
+
+  private:
+    /// Data packing version
+    char m_packingVersion{defaultPackingVersion()};
+
+    /// The packed data objects
+    Vector m_vect;
+  };
+
+  /**
+   *  Utility class to handle the packing and unpacking of the CaloChargedPIDs
+   *
+   */
+  class CaloChargedPIDPacker : public PackerBase {
+  public:
+    // These are required by the templated algorithms
+    typedef LHCb::Event::Calo::v1::CaloChargedPID  Data;
+    typedef LHCb::PackedCaloChargedPID             PackedData;
+    typedef LHCb::Event::Calo::v1::CaloChargedPIDs DataVector;
+    typedef LHCb::PackedCaloChargedPIDs            PackedDataVector;
+    static const std::string& packedLocation() { return LHCb::PackedCaloChargedPIDLocation::Default; }
+    static const std::string& unpackedLocation() { return LHCb::Event::Calo::v1::CaloChargedPIDLocation::Default; }
+    static const char*        propertyName() { return "CaloChargedPIDs"; }
+
+    using PackerBase::PackerBase;
+
+    /// Pack CaloChargedPID
+    template <typename CaloChargedPIDsRange>
+    void pack( const CaloChargedPIDsRange& pids, PackedDataVector& ppids ) const {
+      const auto ver = ppids.packingVersion();
+      if ( !isSupportedVer( ver ) ) return;
+      ppids.data().reserve( pids.size() );
+      for ( const auto* pid : pids ) pack( *pid, ppids.data().emplace_back(), ppids );
+    }
+
+    /// Unpack a single CaloChargedPID
+    StatusCode unpack( const PackedData& ppid, Data& pid, const PackedDataVector& ppids ) const;
+
+    /// Unpack CaloChargedPIDs
+    StatusCode unpack( const PackedDataVector& ppids, DataVector& pids ) const;
+
+    /// Compare two CaloChargedPIDs to check the packing -> unpacking performance
+    StatusCode check( const Data* dataA, const Data* dataB ) const;
+
+  private:
+    /// Pack a CaloChargedPID
+    void pack( const Data& pid, PackedData& ppid, PackedDataVector& ppids ) const;
+
+    /// Check if the given packing version is supported
+    [[nodiscard]] static bool isSupportedVer( const char ver ) {
+      const bool OK = ( 0 == ver );
+      if ( !OK ) {
+        throw GaudiException( fmt::format( "Unknown packed data version {}", (int)ver ), "CaloChargedPIDPacker",
+                              StatusCode::FAILURE );
+      }
+      return OK;
+    }
+  };
+
+  /**
+   *  Packed BremInfo
+   *
+   */
+  struct PackedBremInfo {
+    std::int32_t BremAcc; // combined variable to store bools InBrem and HasBrem
+    std::int32_t BremHypoID{0};
+    std::int32_t BremHypoMatch{0};
+    std::int32_t BremHypoEnergy{0};
+    std::int32_t BremHypoDeltaX{0};
+    std::int32_t BremTrackBasedEnergy{0};
+    std::int16_t BremBendingCorrection{0};
+    std::int32_t BremEnergy{0};
+    std::int32_t BremPIDe{0};
+    std::int64_t key{-1};
+
+#ifndef __CLING__
+    template <typename Buf>
+    void save( Buf& buf ) const {
+      Packer::io( buf, *this );
+    }
+
+    template <typename Buf>
+    void load( Buf& buf, unsigned int /*version*/ ) {
+      Packer::io( buf, *this );
+    }
+#endif
+  };
+
+  constexpr CLID CLID_PackedBremInfos = 1573;
+
+  /// Namespace for locations in TDS
+  namespace PackedBremInfoLocation {
+    inline const std::string Default = "";
+  } // namespace PackedBremInfoLocation
+
+  /**
+   *  Packed BremInfos
+   *
+   */
+  class PackedBremInfos : public DataObject {
+
+  public:
+    /// Vector of packed objects
+    typedef std::vector<LHCb::PackedBremInfo> Vector;
+
+    /// Default Packing Version
+    static char defaultPackingVersion() { return 0; }
+
+    /// Class ID
+    static const CLID& classID() { return CLID_PackedBremInfos; }
+
+    /// Class ID
+    const CLID& clID() const override { return PackedBremInfos::classID(); }
+
+    /// Write access to the data vector
+    Vector& data() { return m_vect; }
+
+    /// Read access to the data vector
+    const Vector& data() const { return m_vect; }
+
+    /// Access the packing version
+    [[nodiscard]] char packingVersion() const { return m_packingVersion; }
+
+    /// Describe serialization of object
+    template <typename T>
+    void save( T& buf ) const {
+      buf.save( static_cast<uint8_t>( m_packingVersion ) );
+      buf.save( static_cast<uint8_t>( version() ) );
+      buf.save( m_vect );
+    }
+
+    /// Describe de-serialization of object
+    template <typename T>
+    void load( T& buf ) {
+      m_packingVersion = buf.template load<uint8_t>();
+      setVersion( buf.template load<uint8_t>() );
+      buf.load( m_vect, m_packingVersion );
+    }
+
+    // Perform unpacking
+    friend StatusCode unpack( Gaudi::Algorithm const*, const PackedBremInfos&, Event::Calo::v1::BremInfos& );
+
+  private:
+    /// Data packing version
+    char m_packingVersion{defaultPackingVersion()};
+
+    /// The packed data objects
+    Vector m_vect;
+  };
+
+  /**
+   *  Utility class to handle the packing and unpacking of the BremInfos
+   *
+   */
+  class BremInfoPacker : public PackerBase {
+  public:
+    // These are required by the templated algorithms
+    typedef LHCb::Event::Calo::v1::BremInfo  Data;
+    typedef LHCb::PackedBremInfo             PackedData;
+    typedef LHCb::Event::Calo::v1::BremInfos DataVector;
+    typedef LHCb::PackedBremInfos            PackedDataVector;
+    static const std::string&                packedLocation() { return LHCb::PackedBremInfoLocation::Default; }
+    static const std::string& unpackedLocation() { return LHCb::Event::Calo::v1::BremInfoLocation::Default; }
+    static const char*        propertyName() { return "BremInfos"; }
+
+    using PackerBase::PackerBase;
+
+    /// Pack BremInfo
+    template <typename BremInfosRange>
+    void pack( const BremInfosRange& pids, PackedDataVector& ppids ) const {
+      const auto ver = ppids.packingVersion();
+      if ( !isSupportedVer( ver ) ) return;
+      ppids.data().reserve( pids.size() );
+      for ( const auto* pid : pids ) pack( *pid, ppids.data().emplace_back(), ppids );
+    }
+
+    /// Unpack a single BremInfo
+    StatusCode unpack( const PackedData& ppid, Data& pid, const PackedDataVector& ppids ) const;
+
+    /// Unpack BremInfos
+    StatusCode unpack( const PackedDataVector& ppids, DataVector& pids ) const;
+
+    /// Compare two BremInfos to check the packing -> unpacking performance
+    StatusCode check( const Data* dataA, const Data* dataB ) const;
+
+  private:
+    /// Pack a BremInfo
+    void pack( const Data& pid, PackedData& ppid, PackedDataVector& ppids ) const;
+
+    /// Check if the given packing version is supported
+    [[nodiscard]] static bool isSupportedVer( const char ver ) {
+      const bool OK = ( 0 == ver );
+      if ( !OK ) {
+        throw GaudiException( fmt::format( "Unknown packed data version {}", (int)ver ), "BremInfoPacker",
+                              StatusCode::FAILURE );
+      }
+      return OK;
+    }
+  };
+
+} // namespace LHCb
diff --git a/Event/EventPacker/include/Event/PackedProtoParticle.h b/Event/EventPacker/include/Event/PackedProtoParticle.h
index 0b0810a2eef..b41ef386633 100644
--- a/Event/EventPacker/include/Event/PackedProtoParticle.h
+++ b/Event/EventPacker/include/Event/PackedProtoParticle.h
@@ -36,6 +36,8 @@ namespace LHCb {
     std::int64_t  key{0};
     std::int64_t  track{0};
     std::int64_t  richPID{0};
+    std::int64_t  caloChargedPID{0};
+    std::int64_t  bremInfo{0};
     std::int64_t  muonPID{0};
     std::int64_t  neutralPID{0};
     std::uint16_t firstHypo{0};
@@ -53,6 +55,8 @@ namespace LHCb {
     void load( T& buf, unsigned int version ) {
       if ( version < 2 ) {
         buf.io( key, track, richPID, muonPID, firstHypo, lastHypo, firstExtra, lastExtra );
+      } else if ( version == 2 ) {
+        buf.io( key, track, richPID, muonPID, neutralPID, firstHypo, lastHypo, firstExtra, lastExtra );
       } else {
         Packer::io( buf, *this ); // identical operation until version is incremented
       }
@@ -80,7 +84,7 @@ namespace LHCb {
 
   public:
     /// Default Packing Version
-    static char defaultPackingVersion() { return 2; }
+    static char defaultPackingVersion() { return 3; }
 
   public:
     const CLID&        clID() const override { return PackedProtoParticles::classID(); }
@@ -171,9 +175,12 @@ namespace LHCb {
 
     /// Unpack a single ProtoParticle -- this only works if `unpack` is called walking sequentially through the vector,
     /// without skipping any entries
-    /// an optional NeutralPIDs container is added for old versions where it needs to be created while unpacking
+    /// optional NeutralPIDs, CaloChargedPIDs and BremInfo containers are added for old versions where it needs to be
+    /// created while unpacking
     StatusCode unpack( const PackedData& pproto, Data& proto, const PackedDataVector& pprotos, DataVector& protos,
-                       LHCb::Packer::Carry& carry, const std::unique_ptr<NeutralPIDs>& npids = nullptr ) const;
+                       LHCb::Packer::Carry& carry, const std::unique_ptr<NeutralPIDs>& npids = nullptr,
+                       const std::unique_ptr<Event::Calo::v1::CaloChargedPIDs>& cpids  = nullptr,
+                       const std::unique_ptr<Event::Calo::v1::BremInfos>&       binfos = nullptr ) const;
 
     /// Compare two ProtoParticles to check the packing -> unpacking performance
     StatusCode check( const Data* dataA, const Data* dataB ) const;
@@ -183,7 +190,7 @@ namespace LHCb {
     void pack( const Data& proto, PackedData& pproto, PackedDataVector& pprotos ) const;
     /// Check if the given packing version is supported
     [[nodiscard]] static bool isSupportedVer( const char ver ) {
-      const bool OK = ( 2 == ver || 1 == ver || 0 == ver );
+      const bool OK = ( 3 == ver || 2 == ver || 1 == ver || 0 == ver );
       if ( !OK ) {
         throw GaudiException( fmt::format( "Unknown packed data version {}", (int)ver ), "ProtoParticlePacker",
                               StatusCode::FAILURE );
diff --git a/Event/EventPacker/include/Event/PackedSharedObjectsContainer.h b/Event/EventPacker/include/Event/PackedSharedObjectsContainer.h
index b3734d72d27..2b924ce8cc4 100644
--- a/Event/EventPacker/include/Event/PackedSharedObjectsContainer.h
+++ b/Event/EventPacker/include/Event/PackedSharedObjectsContainer.h
@@ -27,6 +27,8 @@ namespace LHCb {
   class RichPID;
   class MuonPID;
   class NeutralPID;
+  class CaloChargedPID;
+  class BremInfo;
   namespace Event {
     inline namespace v1 {
       class Track;
@@ -63,6 +65,10 @@ namespace LHCb {
       struct clid_<MuonPID> : std::integral_constant<CLID, 1871> {};
       template <>
       struct clid_<NeutralPID> : std::integral_constant<CLID, 1891> {};
+      template <>
+      struct clid_<Event::Calo::v1::CaloChargedPID> : std::integral_constant<CLID, 1892> {};
+      template <>
+      struct clid_<Event::Calo::v1::BremInfo> : std::integral_constant<CLID, 1893> {};
     } // namespace details
 
     template <typename T>
diff --git a/Event/EventPacker/src/component/BufferUnpackerBaseAlg.h b/Event/EventPacker/src/component/BufferUnpackerBaseAlg.h
index c8b8a278ddc..0cf55a1df1a 100644
--- a/Event/EventPacker/src/component/BufferUnpackerBaseAlg.h
+++ b/Event/EventPacker/src/component/BufferUnpackerBaseAlg.h
@@ -16,7 +16,6 @@
 #include "RegistryWrapper.h"
 #include "Traits.h"
 #include "expected.h"
-
 namespace {
   static const Gaudi::StringKey PackedObjectLocations{"PackedObjectLocations"};
 
diff --git a/Event/EventPacker/src/component/BufferUnpackers.cpp b/Event/EventPacker/src/component/BufferUnpackers.cpp
index 2d3f6a3fb50..8db224eee2d 100644
--- a/Event/EventPacker/src/component/BufferUnpackers.cpp
+++ b/Event/EventPacker/src/component/BufferUnpackers.cpp
@@ -13,6 +13,7 @@
 #include "RelationPackers.h"
 
 #include "Event/PackedCaloAdc.h"
+#include "Event/PackedCaloChargedInfo_v1.h"
 #include "Event/PackedCaloCluster.h"
 #include "Event/PackedCaloDigit.h"
 #include "Event/PackedCaloHypo.h"
@@ -45,6 +46,8 @@ namespace DataPacking::Buffer {
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::RichPID::Container>, "RichPIDUnpacker" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::MuonPID::Container>, "MuonPIDUnpacker" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::NeutralPID::Container>, "NeutralPIDUnpacker" )
+  DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::Event::Calo::v1::CaloChargedPID::Container>, "CaloChargedPIDUnpacker" )
+  DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::Event::Calo::v1::BremInfo::Container>, "BremInfoUnpacker" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::Particle::Container>, "ParticleUnpacker" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::Particle::Selection>, "ParticleSelectionUnpacker" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::Track::Container>, "TrackUnpacker" )
diff --git a/Event/EventPacker/src/component/PackedDataChecksum.cpp b/Event/EventPacker/src/component/PackedDataChecksum.cpp
index 24714197639..148a0f5b2a8 100644
--- a/Event/EventPacker/src/component/PackedDataChecksum.cpp
+++ b/Event/EventPacker/src/component/PackedDataChecksum.cpp
@@ -10,6 +10,7 @@
 \*****************************************************************************/
 #include "Event/PackedDataChecksum.h"
 #include "Event/PackedCaloAdc.h"
+#include "Event/PackedCaloChargedInfo_v1.h"
 #include "Event/PackedCaloCluster.h"
 #include "Event/PackedCaloDigit.h"
 #include "Event/PackedCaloHypo.h"
@@ -34,13 +35,15 @@ namespace LHCb::Hlt::PackedData {
 #ifdef __GNUC__
   static_assert( sizeof( PackedTrack ) == 56, "PackedTrack has changed!" ); // padded!
   static_assert( sizeof( PackedState ) == 68, "PackedState has changed!" );
-  static_assert( sizeof( PackedRichPID ) == 56, "PackedRichPID has changed!" );                   // padded!
+  static_assert( sizeof( PackedRichPID ) == 56, "PackedRichPID has changed!" ); // padded!
+  static_assert( sizeof( PackedCaloChargedPID ) == 64, "PackedCaloChargedPID has changed!" );
+  static_assert( sizeof( PackedBremInfo ) == 48, "PackedBremInfo has changed!" );
   static_assert( sizeof( PackedMuonPID ) == 64, "PackedMuonPID has changed!" );                   // padded!
   static_assert( sizeof( PackedNeutralPID ) == 64, "PackedNeutralPID has changed!" );             // padded!
   static_assert( sizeof( PackedCaloCluster ) == 72, "PackedCaloCluster has changed!" );           // padded!
   static_assert( sizeof( PackedCaloClusterEntry ) == 16, "PackedCaloClusterEntry has changed!" ); // padded!
   static_assert( sizeof( PackedCaloHypo ) == 76, "PackedCaloHypo has changed!" );
-  static_assert( sizeof( PackedProtoParticle ) == 48, "PackedProtoParticle has changed!" );
+  static_assert( sizeof( PackedProtoParticle ) == 64, "PackedProtoParticle has changed!" );
   static_assert( sizeof( PackedRecVertex ) == 60, "PackedRecVertex has changed!" ); // padded!
   static_assert( sizeof( PackedFlavourTag ) == 32, "PackedFlavourTag has changed!" );
   static_assert( sizeof( PackedTagger ) == 24, "PackedTagger has changed!" ); // padded!
diff --git a/Event/EventPacker/src/component/SelectivePacker.cpp b/Event/EventPacker/src/component/SelectivePacker.cpp
index 2229de40ebd..b4efe1464a8 100644
--- a/Event/EventPacker/src/component/SelectivePacker.cpp
+++ b/Event/EventPacker/src/component/SelectivePacker.cpp
@@ -174,7 +174,6 @@ namespace LHCb {
     const Gaudi::StringKey PackedObjectLocations{"PackedObjectLocations"};
 
     using Buffer = Hlt::PackedData::PackedDataOutBuffer;
-
     template <typename T>
     using VOC = Gaudi::Functional::vector_of_const_<T>;
 
@@ -854,6 +853,8 @@ namespace LHCb {
         if ( m_lists.add( p ) ) {
           add( p.track() );
           add( p.richPID() );
+          add( p.caloChargedPID() );
+          add( p.bremInfo() );
           add( p.muonPID() );
           add( p.neutralPID() );
           add( p.calo() );
@@ -870,6 +871,10 @@ namespace LHCb {
         if ( m_lists.add( r ) ) add( r.track() );
       }
 
+      void add( const Event::Calo::v1::CaloChargedPID& n ) { m_lists.add( n ); }
+
+      void add( const Event::Calo::v1::BremInfo& n ) { m_lists.add( n ); }
+
       void add( const MuonPID& m ) {
         if ( m_lists.add( m ) ) {
           add( m.idTrack() );
@@ -1094,7 +1099,6 @@ namespace LHCb {
       // list of all supported types
       Traits::expand_t<Maps> m_lists;
     };
-
     template <typename EventData>
     using input_t = Gaudi::Functional::vector_of_const_<EventData*> const&;
     template <typename... EventData>
diff --git a/Event/EventPacker/src/component/Traits.h b/Event/EventPacker/src/component/Traits.h
index 30e8f770681..d1877cac1b4 100644
--- a/Event/EventPacker/src/component/Traits.h
+++ b/Event/EventPacker/src/component/Traits.h
@@ -15,6 +15,7 @@
 #include "Event/FlavourTag.h"
 #include "Event/MCParticle.h"
 #include "Event/PackedCaloAdc.h"
+#include "Event/PackedCaloChargedInfo_v1.h"
 #include "Event/PackedCaloCluster.h"
 #include "Event/PackedCaloDigit.h"
 #include "Event/PackedCaloHypo.h"
@@ -166,6 +167,11 @@ namespace LHCb::Packers::Traits {
     template <>
     struct Info_for_<NeutralPID> : packer_mapping<NeutralPID, NeutralPIDPacker> {};
     template <>
+    struct Info_for_<Event::Calo::v1::CaloChargedPID>
+        : packer_mapping<Event::Calo::v1::CaloChargedPID, CaloChargedPIDPacker> {};
+    template <>
+    struct Info_for_<Event::Calo::v1::BremInfo> : packer_mapping<Event::Calo::v1::BremInfo, BremInfoPacker> {};
+    template <>
     struct Info_for_<ProtoParticle> : packer_mapping<ProtoParticle, ProtoParticlePacker> {};
     template <>
     struct Info_for_<Particle> : packer_mapping<Particle, ParticlePacker> {};
@@ -263,8 +269,9 @@ namespace LHCb::Packers::Traits {
   template <template <typename...> typename T, template <typename> typename Fun = id_>
   using Expand = details::apply_helper<
       T, Fun, RecVertex, PrimaryVertex, LHCb::Event::PV::PrimaryVertexContainer, Vertex, TwoProngVertex, RichPID,
-      MuonPID, NeutralPID, ProtoParticle, Particle, Track, FlavourTag, CaloHypo, CaloCluster, CaloDigit, CaloAdc,
-      WeightsVector, RecSummary, Relation1D<Particle, VertexBase>::Entry, Relation1D<Particle, RecVertex>::Entry,
+      MuonPID, NeutralPID, Event::Calo::v1::CaloChargedPID, Event::Calo::v1::BremInfo, ProtoParticle, Particle, Track,
+      FlavourTag, CaloHypo, CaloCluster, CaloDigit, CaloAdc, WeightsVector, RecSummary,
+      Relation1D<Particle, VertexBase>::Entry, Relation1D<Particle, RecVertex>::Entry,
       Relation1D<Particle, MCParticle>::Entry, RelationWeighted1D<ProtoParticle, MCParticle, double>::Entry,
       Relation1D<Particle, int>::Entry, Relation1D<Particle, RelatedInfoMap>::Entry>;
 
@@ -299,19 +306,22 @@ namespace LHCb::Packers::Traits {
   using expand_t = distribute_t<T, Traits::details::concat_t<SelectionTypes, ContainerTypes>>;
 
 #if 1
-  static_assert( std::is_same_v<
-                 expand_t<std::tuple>,
-                 std::tuple<RecVertex::Selection, PrimaryVertex::Selection, Vertex::Selection,
-                            TwoProngVertex::Selection, RichPID::Selection, MuonPID::Selection, NeutralPID::Selection,
-                            ProtoParticle::Selection, Particle::Selection, Track::Selection, FlavourTag::Selection,
-                            CaloHypo::Selection, CaloCluster::Selection, RecVertex::Container, PrimaryVertex::Container,
-                            LHCb::Event::PV::PrimaryVertexContainer, Vertex::Container, TwoProngVertex::Container,
-                            RichPID::Container, MuonPID::Container, NeutralPID::Container, ProtoParticle::Container,
-                            Particle::Container, Track::Container, FlavourTag::Container, CaloHypo::Container,
-                            CaloCluster::Container, CaloDigit::Container, CaloAdc::Container, WeightsVector::Container,
-                            RecSummary, Relation1D<Particle, VertexBase>, Relation1D<Particle, RecVertex>,
-                            Relation1D<Particle, MCParticle>, RelationWeighted1D<ProtoParticle, MCParticle, double>,
-                            Relation1D<Particle, int>, Relation1D<Particle, RelatedInfoMap>>> );
+  static_assert(
+      std::is_same_v<
+          expand_t<std::tuple>,
+          std::tuple<
+              RecVertex::Selection, PrimaryVertex::Selection, Vertex::Selection, TwoProngVertex::Selection,
+              RichPID::Selection, MuonPID::Selection, NeutralPID::Selection, Event::Calo::v1::CaloChargedPID::Selection,
+              Event::Calo::v1::BremInfo::Selection, ProtoParticle::Selection, Particle::Selection, Track::Selection,
+              FlavourTag::Selection, CaloHypo::Selection, CaloCluster::Selection, RecVertex::Container,
+              PrimaryVertex::Container, LHCb::Event::PV::PrimaryVertexContainer, Vertex::Container,
+              TwoProngVertex::Container, RichPID::Container, MuonPID::Container, NeutralPID::Container,
+              Event::Calo::v1::CaloChargedPID::Container, Event::Calo::v1::BremInfo::Container,
+              ProtoParticle::Container, Particle::Container, Track::Container, FlavourTag::Container,
+              CaloHypo::Container, CaloCluster::Container, CaloDigit::Container, CaloAdc::Container,
+              WeightsVector::Container, RecSummary, Relation1D<Particle, VertexBase>, Relation1D<Particle, RecVertex>,
+              Relation1D<Particle, MCParticle>, RelationWeighted1D<ProtoParticle, MCParticle, double>,
+              Relation1D<Particle, int>, Relation1D<Particle, RelatedInfoMap>>> );
 
 #else
 
diff --git a/Event/EventPacker/src/component/Unpackers.cpp b/Event/EventPacker/src/component/Unpackers.cpp
index cf739d0eddf..f903b69c6fe 100644
--- a/Event/EventPacker/src/component/Unpackers.cpp
+++ b/Event/EventPacker/src/component/Unpackers.cpp
@@ -11,6 +11,7 @@
 
 #include "UnpackerBaseAlg.h"
 
+#include "Event/PackedCaloChargedInfo_v1.h"
 #include "Event/PackedCaloHypo.h"
 #include "Event/PackedMuonPID.h"
 #include "Event/PackedNeutralPID.h"
@@ -62,6 +63,8 @@ namespace DataPacking {
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::RichPIDPacker>, "UnpackRichPIDs" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::MuonPIDPacker>, "UnpackMuonPIDs" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::NeutralPIDPacker>, "UnpackNeutralPIDs" )
+  DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::CaloChargedPIDPacker>, "UnpackCaloChargedPIDs" )
+  DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::BremInfoPacker>, "UnpackBremInfos" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::WeightsVectorPacker>, "UnpackWeightsVector" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::TrackPacker>, "UnpackTrack" )
   DECLARE_COMPONENT_WITH_ID( Unpack<LHCb::CaloHypoPacker>, "UnpackCaloHypo" )
diff --git a/Event/EventPacker/src/lib/PackedCaloChargedInfo_v1.cpp b/Event/EventPacker/src/lib/PackedCaloChargedInfo_v1.cpp
new file mode 100644
index 00000000000..a8e4dd5f5de
--- /dev/null
+++ b/Event/EventPacker/src/lib/PackedCaloChargedInfo_v1.cpp
@@ -0,0 +1,211 @@
+/*****************************************************************************\
+* (c) Copyright 2023 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 "Event/PackedCaloChargedInfo_v1.h"
+#include "Event/PackedEventChecks.h"
+#include <memory>
+
+using namespace LHCb;
+
+// using FLT_TYPE = float;
+using FLT = float;
+
+void CaloChargedPIDPacker::pack( const Data& pid, PackedData& ppid, PackedDataVector& ppids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return; }
+  // save the key
+  ppid.key = pid.key();
+  // save data
+  ppid.InAcc             = pid.InEcal() * 0x1 + pid.InHcal() * 0x2;
+  ppid.ClusterID         = pid.ClusterID().all();
+  ppid.ClusterMatch      = StandardPacker::fltPacked( pid.ClusterMatch() );
+  ppid.ElectronID        = pid.ElectronID().all();
+  ppid.ElectronMatch     = StandardPacker::fltPacked( pid.ElectronMatch() );
+  ppid.ElectronEnergy    = StandardPacker::energy( pid.ElectronEnergy() );
+  ppid.ElectronShowerEoP = StandardPacker::fltPacked( pid.ElectronShowerEoP() );
+  ppid.ElectronShowerDLL = StandardPacker::deltaLL( pid.ElectronShowerDLL() );
+  ppid.EcalPIDe          = StandardPacker::deltaLL( pid.EcalPIDe() );
+  ppid.EcalPIDmu         = StandardPacker::deltaLL( pid.EcalPIDmu() );
+  ppid.HcalEoP           = StandardPacker::fltPacked( pid.HcalEoP() );
+  ppid.HcalPIDe          = StandardPacker::deltaLL( pid.HcalPIDe() );
+  ppid.HcalPIDmu         = StandardPacker::deltaLL( pid.HcalPIDmu() );
+}
+
+StatusCode CaloChargedPIDPacker::unpack( const PackedData& ppid, Data& pid, const PackedDataVector& ppids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return StatusCode::FAILURE; }
+  // unpack the data
+  pid.setInEcal( ppid.InAcc & 0x1 );
+  pid.setClusterID( Detector::Calo::CellID( ppid.ClusterID ) );
+  pid.setClusterMatch( (FLT)StandardPacker::fltPacked( ppid.ClusterMatch ) );
+  pid.setElectronID( Detector::Calo::CellID( ppid.ElectronID ) );
+  pid.setElectronMatch( (FLT)StandardPacker::fltPacked( ppid.ElectronMatch ) );
+  pid.setElectronEnergy( (FLT)StandardPacker::energy( ppid.ElectronEnergy ) );
+  pid.setElectronShowerEoP( (FLT)StandardPacker::fltPacked( ppid.ElectronShowerEoP ) );
+  pid.setElectronShowerDLL( (FLT)StandardPacker::deltaLL( ppid.ElectronShowerDLL ) );
+  pid.setEcalPIDe( (FLT)StandardPacker::deltaLL( ppid.EcalPIDe ) );
+  pid.setEcalPIDmu( (FLT)StandardPacker::deltaLL( ppid.EcalPIDmu ) );
+  pid.setInHcal( ( ppid.InAcc & 0x2 ) );
+  pid.setHcalEoP( (FLT)StandardPacker::fltPacked( ppid.HcalEoP ) );
+  pid.setHcalPIDe( (FLT)StandardPacker::deltaLL( ppid.HcalPIDe ) );
+  pid.setHcalPIDmu( (FLT)StandardPacker::deltaLL( ppid.HcalPIDmu ) );
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode CaloChargedPIDPacker::unpack( const PackedDataVector& ppids, DataVector& pids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return StatusCode::FAILURE; }
+  pids.reserve( ppids.data().size() );
+  StatusCode sc = StatusCode::SUCCESS;
+  for ( const auto& ppid : ppids.data() ) {
+    // make new pid in container
+    auto pid = std::make_unique<Data>();
+    // Fill data from packed object
+    auto sc2 = unpack( ppid, *pid, ppids );
+    if ( sc.isSuccess() ) sc = sc2;
+    // give to container
+    pids.insert( pid.release(), ppid.key );
+  }
+  return sc;
+}
+
+StatusCode CaloChargedPIDPacker::check( const Data* dataA, const Data* dataB ) const {
+  // checker
+  const DataPacking::DataChecks ch( parent() );
+
+  // assume OK from the start
+  bool ok = true;
+
+  ok &= ch.compareInts( "Key", dataA->key(), dataB->key() );
+  ok &= ch.compareInts( "InEcal", dataA->InEcal(), dataB->InEcal() );
+  ok &= ch.compareInts( "ClusterID", dataA->ClusterID().all(), dataB->ClusterID().all() );
+  ok &= ch.compareFloats( "ClusterMatch", dataA->ClusterMatch(), dataB->ClusterMatch() );
+  ok &= ch.compareInts( "ElectronID", dataA->ElectronID().all(), dataB->ElectronID().all() );
+  ok &= ch.compareFloats( "ElectronMatch", dataA->ElectronMatch(), dataB->ElectronMatch() );
+  ok &= ch.compareEnergies( "ElectronEnergy", dataA->ElectronEnergy(), dataB->ElectronEnergy() );
+  ok &= ch.compareFloats( "ElectronShowerEoP", dataA->ElectronShowerEoP(), dataB->ElectronShowerEoP() );
+  ok &= ch.compareDeltaLLs( "ElectronShowerDLL", dataA->ElectronShowerDLL(), dataB->ElectronShowerDLL() );
+  ok &= ch.compareDeltaLLs( "EcalPIDe", dataA->EcalPIDe(), dataB->EcalPIDe() );
+  ok &= ch.compareDeltaLLs( "EcalPIDmu", dataA->EcalPIDmu(), dataB->EcalPIDmu() );
+  ok &= ch.compareInts( "InHcal", dataA->InHcal(), dataB->InHcal() );
+  ok &= ch.compareFloats( "HcalEoP", dataA->HcalEoP(), dataB->HcalEoP() );
+  ok &= ch.compareDeltaLLs( "HcalPIDe", dataA->HcalPIDe(), dataB->HcalPIDe() );
+  ok &= ch.compareDeltaLLs( "HcalPIDmu", dataA->HcalPIDmu(), dataB->HcalPIDmu() );
+
+  // force printout for tests
+  // ok = false;
+  // If comparison not OK, print full information
+  if ( !ok ) {
+    const std::string loc =
+        ( dataA->parent() && dataA->parent()->registry() ? dataA->parent()->registry()->identifier() : "Not in TES" );
+    parent().warning() << "Problem with CaloChargedPID data packing :-" << endmsg
+                       << "  Original PID key=" << dataA->key() << " in '" << loc << "'" << endmsg << dataA << endmsg
+                       << "  Unpacked PID" << endmsg << dataB << endmsg;
+  }
+
+  return ( ok ? StatusCode::SUCCESS : StatusCode::FAILURE );
+}
+
+void BremInfoPacker::pack( const Data& pid, PackedData& ppid, PackedDataVector& ppids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return; }
+  // save the key
+  ppid.key = pid.key();
+  // save data
+  ppid.BremAcc               = pid.InBrem() * 0x1 + pid.HasBrem() * 0x2;
+  ppid.BremHypoID            = pid.BremHypoID().all();
+  ppid.BremHypoMatch         = StandardPacker::fltPacked( pid.BremHypoMatch() );
+  ppid.BremHypoEnergy        = StandardPacker::energy( pid.BremHypoEnergy() );
+  ppid.BremHypoDeltaX        = StandardPacker::deltaLL( pid.BremHypoDeltaX() );
+  ppid.BremTrackBasedEnergy  = StandardPacker::energy( pid.BremTrackBasedEnergy() );
+  ppid.BremBendingCorrection = StandardPacker::fraction( pid.BremBendingCorrection() );
+  ppid.BremEnergy            = StandardPacker::energy( pid.BremEnergy() );
+  ppid.BremPIDe              = StandardPacker::deltaLL( pid.BremPIDe() );
+}
+
+StatusCode BremInfoPacker::unpack( const PackedData& ppid, Data& pid, const PackedDataVector& ppids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return StatusCode::FAILURE; }
+  // unpack the data
+  pid.setInBrem( ppid.BremAcc & 0x1 );
+  pid.setBremHypoID( Detector::Calo::CellID( ppid.BremHypoID ) );
+  pid.setBremHypoMatch( (FLT)StandardPacker::fltPacked( ppid.BremHypoMatch ) );
+  pid.setBremHypoEnergy( (FLT)StandardPacker::energy( ppid.BremHypoEnergy ) );
+  pid.setBremHypoDeltaX( (FLT)StandardPacker::deltaLL( ppid.BremHypoDeltaX ) );
+  pid.setBremTrackBasedEnergy( (FLT)StandardPacker::energy( ppid.BremTrackBasedEnergy ) );
+  pid.setBremBendingCorrection( (FLT)StandardPacker::fraction( ( ppid.BremBendingCorrection ) ) );
+  pid.setHasBrem( ppid.BremAcc & 0x2 );
+  pid.setBremEnergy( (FLT)StandardPacker::energy( ppid.BremEnergy ) );
+  pid.setBremPIDe( (FLT)StandardPacker::deltaLL( ppid.BremPIDe ) );
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode BremInfoPacker::unpack( const PackedDataVector& ppids, DataVector& pids ) const {
+  const auto ver = ppids.packingVersion();
+  if ( !isSupportedVer( ver ) ) { return StatusCode::FAILURE; }
+  pids.reserve( ppids.data().size() );
+  StatusCode sc = StatusCode::SUCCESS;
+  for ( const auto& ppid : ppids.data() ) {
+    // make new pid in container
+    auto pid = std::make_unique<Data>();
+    // Fill data from packed object
+    auto sc2 = unpack( ppid, *pid, ppids );
+    if ( sc.isSuccess() ) sc = sc2;
+    // give to container
+    pids.insert( pid.release(), ppid.key );
+  }
+  return sc;
+}
+
+StatusCode BremInfoPacker::check( const Data* dataA, const Data* dataB ) const {
+  // checker
+  const DataPacking::DataChecks ch( parent() );
+
+  // assume OK from the start
+  bool ok = true;
+
+  ok &= ch.compareInts( "Key", dataA->key(), dataB->key() );
+  ok &= ch.compareInts( "InBrem", dataA->InBrem(), dataB->InBrem() );
+  ok &= ch.compareInts( "BremHypoID", dataA->BremHypoID().all(), dataB->BremHypoID().all() );
+  ok &= ch.compareFloats( "BremHypoMatch", dataA->BremHypoMatch(), dataB->BremHypoMatch() );
+  ok &= ch.compareEnergies( "BremHypoEnergy", dataA->BremHypoEnergy(), dataB->BremHypoEnergy() );
+  ok &= ch.compareDeltaLLs( "BremHypoDeltaX", dataA->BremHypoDeltaX(), dataB->BremHypoDeltaX() );
+  ok &= ch.compareEnergies( "BremTrackBasedEnergy", dataA->BremTrackBasedEnergy(), dataB->BremTrackBasedEnergy() );
+  ok &= ch.compareFractions( "BremBendingCorrection", dataA->BremBendingCorrection(), dataB->BremBendingCorrection() );
+  ok &= ch.compareInts( "HasBrem", dataA->HasBrem(), dataB->HasBrem() );
+  ok &= ch.compareEnergies( "BremEnergy", dataA->BremEnergy(), dataB->BremEnergy() );
+  ok &= ch.compareDeltaLLs( "BremPIDe", dataA->BremPIDe(), dataB->BremPIDe() );
+
+  // force printout for tests
+  // ok = false;
+  // If comparison not OK, print full information
+  if ( !ok ) {
+    const std::string loc =
+        ( dataA->parent() && dataA->parent()->registry() ? dataA->parent()->registry()->identifier() : "Not in TES" );
+    parent().warning() << "Problem with BremInfo data packing :-" << endmsg << "  Original PID key=" << dataA->key()
+                       << " in '" << loc << "'" << endmsg << dataA << endmsg << "  Unpacked PID" << endmsg << dataB
+                       << endmsg;
+  }
+
+  return ( ok ? StatusCode::SUCCESS : StatusCode::FAILURE );
+}
+
+namespace LHCb {
+  StatusCode unpack( Gaudi::Algorithm const* parent, const CaloChargedPIDPacker::PackedDataVector& in,
+                     CaloChargedPIDPacker::DataVector& out ) {
+    return CaloChargedPIDPacker{parent}.unpack( in, out );
+  }
+  StatusCode unpack( Gaudi::Algorithm const* parent, const BremInfoPacker::PackedDataVector& in,
+                     BremInfoPacker::DataVector& out ) {
+    return BremInfoPacker{parent}.unpack( in, out );
+  }
+} // namespace LHCb
diff --git a/Event/EventPacker/src/lib/PackedProtoParticle.cpp b/Event/EventPacker/src/lib/PackedProtoParticle.cpp
index 70f5d905102..b3826305a89 100644
--- a/Event/EventPacker/src/lib/PackedProtoParticle.cpp
+++ b/Event/EventPacker/src/lib/PackedProtoParticle.cpp
@@ -10,10 +10,12 @@
 \*****************************************************************************/
 
 #include "Event/PackedProtoParticle.h"
+#include "Event/CaloChargedInfo_v1.h"
 #include "Event/NeutralPID.h"
 #include "Event/PackedEventChecks.h"
 #include "fmt/format.h"
 #include "fmt/ostream.h"
+#include <functional>
 
 #if FMT_VERSION >= 90000
 template <>
@@ -24,6 +26,20 @@ struct fmt::formatter<LHCb::ProtoParticle::additionalInfo> : ostream_formatter {
 #include <memory>
 #include <utility>
 
+template <typename T>
+struct std::hash<KeyedContainer<T, Containers::HashMap>> {
+  std::size_t operator()( const KeyedContainer<T, Containers::HashMap>& container ) const noexcept {
+    std::size_t combined_hash = 0;
+    for ( const T* pid : container ) {
+      if ( pid ) {
+        std::size_t pid_hash = std::hash<T>{}( *pid );
+        combined_hash ^= ( pid_hash + 0x9e3779b9 + ( combined_hash << 6 ) + ( combined_hash >> 2 ) );
+      }
+    }
+    return combined_hash;
+  }
+};
+
 using namespace LHCb;
 
 //-----------------------------------------------------------------------------
@@ -56,6 +72,24 @@ void ProtoParticlePacker::pack( const Data& proto, PackedData& pproto, PackedDat
     pproto.richPID = -1;
   }
 
+  if ( proto.caloChargedPID() ) {
+    pproto.caloChargedPID = ( StandardPacker::reference64( &pprotos, proto.caloChargedPID() ) );
+    parent().debug() << "Found a caloChargedPID with parent " << proto.caloChargedPID()->parent()->name() << " and key "
+                     << proto.caloChargedPID()->key() << endmsg;
+    parent().debug() << "Packed a caloChargedPID with key " << pproto.caloChargedPID << endmsg;
+  } else {
+    pproto.caloChargedPID = -1;
+  }
+
+  if ( proto.bremInfo() ) {
+    pproto.bremInfo = ( StandardPacker::reference64( &pprotos, proto.bremInfo() ) );
+    parent().debug() << "Found a bremInfo with parent " << proto.bremInfo()->parent()->name() << " and key "
+                     << proto.bremInfo()->key() << endmsg;
+    parent().debug() << "Packed a bremInfo with key " << pproto.bremInfo << endmsg;
+  } else {
+    pproto.bremInfo = -1;
+  }
+
   if ( proto.muonPID() ) {
     pproto.muonPID = ( 0 == ver ? StandardPacker::reference32( &parent(), &pprotos, proto.muonPID() )
                                 : StandardPacker::reference64( &pprotos, proto.muonPID() ) );
@@ -107,7 +141,10 @@ void ProtoParticlePacker::pack( const Data& proto, PackedData& pproto, PackedDat
 
 StatusCode ProtoParticlePacker::unpack( const PackedData& pproto, Data& proto, const PackedDataVector& pprotos,
                                         DataVector& protos, LHCb::Packer::Carry& with_carry,
-                                        const std::unique_ptr<NeutralPIDs>& npids ) const {
+                                        const std::unique_ptr<NeutralPIDs>&                      npids,
+                                        const std::unique_ptr<Event::Calo::v1::CaloChargedPIDs>& cpids,
+                                        const std::unique_ptr<Event::Calo::v1::BremInfos>&       binfos ) const {
+
   // packing version
   const auto ver = pprotos.packingVersion();
 
@@ -133,6 +170,112 @@ StatusCode ProtoParticlePacker::unpack( const PackedData& pproto, Data& proto, c
     }
   }
 
+  // if the proto is charged-like, unpack CaloChargedPID and BremInfo. If we are in old version without CaloChargedPID
+  // and BremInfo objects, create them from AdditionalInfo
+  if ( -1 != pproto.track ) {
+    if ( ( ver < 3 ) ) {
+      if ( !cpids || !binfos ) {
+        parent().error() << "Error creating CaloChargedPID and BremInfo objects: missing containers." << endmsg;
+      }
+      auto pid = std::make_unique<Event::Calo::v1::CaloChargedPID>();
+      proto.setCaloChargedPID( pid.get() );
+      auto binfo = std::make_unique<Event::Calo::v1::BremInfo>();
+      proto.setBremInfo( binfo.get() );
+      for ( const auto& [k, v] : with_carry( pprotos.extras(), pproto.firstExtra, pproto.lastExtra ) ) {
+        switch ( k ) {
+        case LHCb::ProtoParticle::InAccEcal:
+          pid->setInEcal( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloChargedID:
+          pid->setClusterID( Detector::Calo::CellID( StandardPacker::fltPacked( v ) ) );
+          break;
+        case LHCb::ProtoParticle::CaloTrMatch:
+          pid->setClusterMatch( StandardPacker::fltPacked( v ) );
+          break;
+        // missing fill for ElectronID - not in AdditionalInfo
+        case LHCb::ProtoParticle::CaloElectronMatch:
+          pid->setElectronMatch( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloChargedEcal:
+          pid->setElectronEnergy( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloEoverP:
+          pid->setElectronShowerEoP( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::ElectronShowerDLL:
+          pid->setElectronShowerDLL( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::EcalPIDe:
+          pid->setEcalPIDe( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::EcalPIDmu:
+          pid->setEcalPIDmu( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::InAccHcal:
+          pid->setInHcal( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloHcalE:
+          pid->setHcalEoP( proto.track() ? StandardPacker::fltPacked( v ) / proto.track()->p() : 0 );
+          break;
+        case LHCb::ProtoParticle::HcalPIDe:
+          pid->setHcalPIDe( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::HcalPIDmu:
+          pid->setHcalPIDmu( StandardPacker::fltPacked( v ) );
+          break;
+        // breminfo
+        case LHCb::ProtoParticle::InAccBrem:
+          binfo->setInBrem( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremHypoID:
+          binfo->setBremHypoID( Detector::Calo::CellID( StandardPacker::fltPacked( v ) ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremMatch:
+          binfo->setBremHypoMatch( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremHypoEnergy:
+          binfo->setBremHypoEnergy( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremHypoDeltaX:
+          binfo->setBremHypoDeltaX( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremTBEnergy:
+          binfo->setBremTrackBasedEnergy( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremBendingCorr:
+          binfo->setBremBendingCorrection( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloHasBrem:
+          binfo->setHasBrem( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::CaloBremEnergy:
+          binfo->setBremEnergy( StandardPacker::fltPacked( v ) );
+          break;
+        case LHCb::ProtoParticle::BremPIDe:
+          binfo->setBremPIDe( StandardPacker::fltPacked( v ) );
+          break;
+        }
+      }
+      cpids->insert( pid.release() );
+      binfos->insert( binfo.release() );
+    } else {
+      if ( -1 != pproto.caloChargedPID ) {
+        if ( StandardPacker::hintAndKey64( pproto.caloChargedPID, &pprotos, &protos, hintID, key ) ) {
+          proto.setCaloChargedPID( {&protos, hintID, key} );
+        } else {
+          parent().error() << "Corrupt ProtoParticle CaloChargedPID detected." << endmsg;
+        }
+      }
+      if ( -1 != pproto.bremInfo ) {
+        if ( StandardPacker::hintAndKey64( pproto.bremInfo, &pprotos, &protos, hintID, key ) ) {
+          proto.setBremInfo( {&protos, hintID, key} );
+        } else {
+          parent().error() << "Corrupt ProtoParticle BremInfo detected." << endmsg;
+        }
+      }
+    }
+  }
+
   if ( -1 != pproto.muonPID ) {
     if ( ( 0 != ver && StandardPacker::hintAndKey64( pproto.muonPID, &pprotos, &protos, hintID, key ) ) ||
          ( 0 == ver && StandardPacker::hintAndKey32( pproto.muonPID, &pprotos, &protos, hintID, key ) ) ) {
@@ -225,22 +368,41 @@ StatusCode ProtoParticlePacker::unpack( const PackedDataVector& pprotos, DataVec
   parent().debug() << "packing version " << (int)pprotos.packingVersion() << endmsg;
 
   StatusCode sc = StatusCode::SUCCESS;
-  // create a new container in TES for neutralPIDs if in an old version
-  auto npids = std::make_unique<NeutralPIDs>();
+  // create a new container in TES for neutralPIDs, caloChargedPIDs and BremInfo if in an old version
+  auto npids  = std::make_unique<NeutralPIDs>();
+  auto cpids  = std::make_unique<Event::Calo::v1::CaloChargedPIDs>();
+  auto binfos = std::make_unique<Event::Calo::v1::BremInfos>();
 
   LHCb::Packer::Carry carry{};
   for ( const auto& pproto : pprotos.data() ) {
     auto part = std::make_unique<LHCb::ProtoParticle>();
-    auto sc2  = unpack( pproto, *part, pprotos, protos, carry, npids );
+    auto sc2  = unpack( pproto, *part, pprotos, protos, carry, npids, cpids, binfos );
     protos.insert( part.release(), pproto.key );
     if ( sc.isSuccess() ) sc = sc2;
   }
 
-  // if a new container in TES for neutralPIDs was created, put it in TES
+  // if a new container in TES for neutralPIDs, caloChargedPIDs and BremInfo was created, put it in TES
   if ( ( (int)pprotos.packingVersion() < 2 ) && npids && !npids->empty() ) {
-    auto sc = parent().evtSvc()->registerObject( "/Event/Rec/NeutralPIDs", npids.release() );
-    if ( !sc ) {
-      throw GaudiException( "Error in unpacker putting NeutralPIDs container to TES ", "ProtoParticlePacker", sc );
+    auto sc3 = parent().evtSvc()->registerObject( "/Event/Rec/NeutralPIDs", npids.release() );
+    if ( !sc3 ) {
+      throw GaudiException( "Error in unpacker putting NeutralPIDs container to TES ", "ProtoParticlePacker", sc3 );
+    }
+  }
+
+  if ( ( (int)pprotos.packingVersion() < 3 ) && cpids && !cpids->empty() && binfos && !binfos->empty() ) {
+    std::string cpids_address = std::string( fmt::format(
+        "some/anonymous/location/CaloChargedPIDs/{}",
+        std::hash<KeyedContainer<LHCb::Event::Calo::v1::CaloChargedPID, Containers::HashMap>>{}( *cpids ) ) );
+    auto        sc4           = parent().evtSvc()->registerObject( cpids_address, cpids.release() );
+    if ( !sc4 ) {
+      throw GaudiException( "Error in unpacker putting CaloChargedPIDs container to TES ", "ProtoParticlePacker", sc4 );
+    }
+    std::string binfo_address = std::string(
+        fmt::format( "some/anonymous/location/BremInfo/{}",
+                     std::hash<KeyedContainer<LHCb::Event::Calo::v1::BremInfo, Containers::HashMap>>{}( *binfos ) ) );
+    auto sc4b = parent().evtSvc()->registerObject( binfo_address, binfos.release() );
+    if ( !sc4b ) {
+      throw GaudiException( "Error in unpacker putting BremInfo container to TES ", "ProtoParticlePacker", sc4b );
     }
   }
 
@@ -266,6 +428,8 @@ StatusCode ProtoParticlePacker::check( const Data* dataA, const Data* dataB ) co
   isOK &= ch.comparePointers( "RichPID", dataA->richPID(), dataB->richPID() );
   isOK &= ch.comparePointers( "MuonPID", dataA->muonPID(), dataB->muonPID() );
   isOK &= ch.comparePointers( "NeutralPID", dataA->neutralPID(), dataB->neutralPID() );
+  isOK &= ch.comparePointers( "CaloChargedPID", dataA->caloChargedPID(), dataB->caloChargedPID() );
+  isOK &= ch.comparePointers( "BremInfo", dataA->bremInfo(), dataB->bremInfo() );
 
   // calo hypos
   isOK &= ch.compareInts( "#CaloHypos", dataA->calo().size(), dataB->calo().size() );
@@ -295,14 +459,17 @@ StatusCode ProtoParticlePacker::check( const Data* dataA, const Data* dataB ) co
 
   if ( !isOK || MSG::DEBUG >= parent().msgLevel() ) {
     parent().info() << "===== ProtoParticle key " << dataA->key() << " Check OK = " << isOK << endmsg;
-    parent().info() << format( "Old   track %8x  richPID %8X  muonPID%8x  neutralPID%8x  nCaloHypo%4d nExtra%4d",
+    parent().info() << format( "Old   track %8x  richPID %8X  muonPID%8x  neutralPID%8x caloChargedPID %8X bremInfo%8X "
+                               "nCaloHypo%4d nExtra%4d",
                                dataA->track(), dataA->richPID(), dataA->muonPID(), dataA->neutralPID(),
-                               dataA->calo().size(), dataA->extraInfo().size() )
-
+                               dataA->caloChargedPID(), dataA->bremInfo(), dataA->calo().size(),
+                               dataA->extraInfo().size() )
                     << endmsg;
-    parent().info() << format( "Test  track %8x  richPID %8X  muonPID%8x  neutralPID%8x  nCaloHypo%4d nExtra%4d",
+    parent().info() << format( "Test  track %8x  richPID %8X  muonPID%8x  neutralPID%8x caloChargedPID %8X bremInfo%8X "
+                               " nCaloHypo%4d nExtra%4d",
                                dataB->track(), dataB->richPID(), dataB->muonPID(), dataB->neutralPID(),
-                               dataB->calo().size(), dataB->extraInfo().size() )
+                               dataB->caloChargedPID(), dataB->bremInfo(), dataB->calo().size(),
+                               dataB->extraInfo().size() )
                     << endmsg;
     for ( auto iC = std::make_pair( dataA->calo().begin(), dataB->calo().begin() );
           iC.first != dataA->calo().end() && iC.second != dataB->calo().end(); ++iC.first, ++iC.second ) {
diff --git a/Event/RecEvent/dict/dictionary.h b/Event/RecEvent/dict/dictionary.h
index 3349605880f..5ecab4b770f 100644
--- a/Event/RecEvent/dict/dictionary.h
+++ b/Event/RecEvent/dict/dictionary.h
@@ -10,6 +10,7 @@
 \*****************************************************************************/
 
 // begin include files
+#include "Event/CaloChargedInfo_v1.h"
 #include "Event/CaloCluster.h"
 #include "Event/CaloClusterEntry.h"
 #include "Event/CaloHypo.h"
@@ -42,104 +43,116 @@
 namespace {
   struct RecEvent_Instantiations {
     // begin instantiations
-    Gaudi::SymMatrix9x9                           _i5;
-    KeyedContainer<LHCb::CaloCluster>             m_KeyedContainer_LHCb__CaloCluster;
-    KeyedContainer<LHCb::CaloHypo>                m_KeyedContainer_LHCb__CaloHypo;
-    KeyedContainer<LHCb::MuonCluster>             m_KeyedContainer_LHCb__MuonCluster;
-    KeyedContainer<LHCb::MuonCoord>               m_KeyedContainer_LHCb__MuonCoord;
-    KeyedContainer<LHCb::MuonPID>                 m_KeyedContainer_LHCb__MuonPID;
-    KeyedContainer<LHCb::NeutralPID>              m_KeyedContainer_LHCb__NeutralPID;
-    KeyedContainer<LHCb::ProtoParticle>           m_KeyedContainer_LHCb__ProtoParticle;
-    KeyedContainer<LHCb::RecVertex>               m_KeyedContainer_LHCb__RecVertex;
-    KeyedContainer<LHCb::RichPID>                 m_KeyedContainer_LHCb__RichPID;
-    KeyedContainer<LHCb::RichSummaryTrack>        m_KeyedContainer_LHCb__RichSummaryTrack;
-    KeyedContainer<LHCb::TwoProngVertex>          m_KeyedContainer_LHCb__TwoProngVertex;
-    KeyedContainer<LHCb::VertexBase>              m_KeyedContainer_LHCb__VertexBase;
-    KeyedContainer<LHCb::WeightsVector>           m_KeyedContainer_LHCb__WeightsVector;
-    ObjectVector<LHCb::CaloCluster>               m_ObjectVector_LHCb__CaloCluster;
-    ObjectVector<LHCb::CaloHypo>                  m_ObjectVector_LHCb__CaloHypo;
-    ObjectVector<LHCb::MuonCluster>               m_ObjectVector_LHCb__MuonCluster;
-    ObjectVector<LHCb::MuonCoord>                 m_ObjectVector_LHCb__MuonCoord;
-    ObjectVector<LHCb::MuonPID>                   m_ObjectVector_LHCb__MuonPID;
-    ObjectVector<LHCb::NeutralPID>                m_ObjectVector_LHCb__NeutralPID;
-    ObjectVector<LHCb::ProtoParticle>             m_ObjectVector_LHCb__ProtoParticle;
-    ObjectVector<LHCb::RecVertex>                 m_ObjectVector_LHCb__RecVertex;
-    ObjectVector<LHCb::RichPID>                   m_ObjectVector_LHCb__RichPID;
-    ObjectVector<LHCb::RichSummaryTrack>          m_ObjectVector_LHCb__RichSummaryTrack;
-    ObjectVector<LHCb::TwoProngVertex>            m_ObjectVector_LHCb__TwoProngVertex;
-    ObjectVector<LHCb::VertexBase>                m_ObjectVector_LHCb__VertexBase;
-    ObjectVector<LHCb::WeightsVector>             m_ObjectVector_LHCb__WeightsVector;
-    SmartRef<LHCb::CaloCluster>                   m_SmartRef_LHCb__CaloCluster;
-    SmartRef<LHCb::CaloHypo>                      m_SmartRef_LHCb__CaloHypo;
-    SmartRef<LHCb::MuonCluster>                   m_SmartRef_LHCb__MuonCluster;
-    SmartRef<LHCb::MuonCoord>                     m_SmartRef_LHCb__MuonCoord;
-    SmartRef<LHCb::MuonPID>                       m_SmartRef_LHCb__MuonPID;
-    SmartRef<LHCb::NeutralPID>                    m_SmartRef_LHCb__NeutralPID;
-    SmartRef<LHCb::ProcStatus>                    m_SmartRef_LHCb__ProcStatus;
-    SmartRef<LHCb::ProtoParticle>                 m_SmartRef_LHCb__ProtoParticle;
-    SmartRef<LHCb::RecHeader>                     m_SmartRef_LHCb__RecHeader;
-    SmartRef<LHCb::RecSummary>                    m_SmartRef_LHCb__RecSummary;
-    SmartRef<LHCb::RecVertex>                     m_SmartRef_LHCb__RecVertex;
-    SmartRef<LHCb::RichPID>                       m_SmartRef_LHCb__RichPID;
-    SmartRef<LHCb::RichSummaryTrack>              m_SmartRef_LHCb__RichSummaryTrack;
-    SmartRef<LHCb::TwoProngVertex>                m_SmartRef_LHCb__TwoProngVertex;
-    SmartRef<LHCb::UTSummary>                     m_SmartRef_LHCb__UTSummary;
-    SmartRef<LHCb::VertexBase>                    m_SmartRef_LHCb__VertexBase;
-    SmartRef<LHCb::WeightsVector>                 m_SmartRef_LHCb__WeightsVector;
-    SmartRefVector<LHCb::CaloCluster>             m_SmartRefVector_LHCb__CaloCluster;
-    SmartRefVector<LHCb::CaloHypo>                m_SmartRefVector_LHCb__CaloHypo;
-    SmartRefVector<LHCb::MuonCluster>             m_SmartRefVector_LHCb__MuonCluster;
-    SmartRefVector<LHCb::MuonCoord>               m_SmartRefVector_LHCb__MuonCoord;
-    SmartRefVector<LHCb::MuonPID>                 m_SmartRefVector_LHCb__MuonPID;
-    SmartRefVector<LHCb::NeutralPID>              m_SmartRefVector_LHCb__NeutralPID;
-    SmartRefVector<LHCb::ProcStatus>              m_SmartRefVector_LHCb__ProcStatus;
-    SmartRefVector<LHCb::ProtoParticle>           m_SmartRefVector_LHCb__ProtoParticle;
-    SmartRefVector<LHCb::RecHeader>               m_SmartRefVector_LHCb__RecHeader;
-    SmartRefVector<LHCb::RecSummary>              m_SmartRefVector_LHCb__RecSummary;
-    SmartRefVector<LHCb::RecVertex>               m_SmartRefVector_LHCb__RecVertex;
-    SmartRefVector<LHCb::RichPID>                 m_SmartRefVector_LHCb__RichPID;
-    SmartRefVector<LHCb::RichSummaryTrack>        m_SmartRefVector_LHCb__RichSummaryTrack;
-    SmartRefVector<LHCb::TwoProngVertex>          m_SmartRefVector_LHCb__TwoProngVertex;
-    SmartRefVector<LHCb::UTSummary>               m_SmartRefVector_LHCb__UTSummary;
-    SmartRefVector<LHCb::VertexBase>              m_SmartRefVector_LHCb__VertexBase;
-    SmartRefVector<LHCb::WeightsVector>           m_SmartRefVector_LHCb__WeightsVector;
-    std::pair<int, float>                         _i3;
-    std::vector<LHCb::CaloCluster*>               m_std_vector_LHCb__CaloClusterp;
-    std::vector<LHCb::CaloClusterEntry>           m_std_vector_LHCb__CaloClusterEntry;
-    std::vector<LHCb::CaloHypo*>                  m_std_vector_LHCb__CaloHypop;
-    std::vector<LHCb::MuonCluster*>               m_std_vector_LHCb__MuonClusterp;
-    std::vector<LHCb::MuonCoord*>                 m_std_vector_LHCb__MuonCoordp;
-    std::vector<LHCb::MuonPID*>                   m_std_vector_LHCb__MuonPIDp;
-    std::vector<LHCb::NeutralPID*>                m_std_vector_LHCb__NeutralPIDp;
-    std::vector<LHCb::ProtoParticle*>             m_std_vector_LHCb__ProtoParticlep;
-    std::vector<LHCb::RecVertex*>                 m_std_vector_LHCb__RecVertexp;
-    std::vector<LHCb::RichPID*>                   m_std_vector_LHCb__RichPIDp;
-    std::vector<LHCb::RichSummaryPhoton>          m_std_vector_LHCb__RichSummaryPhoton;
-    std::vector<LHCb::RichSummaryRadSegment>      m_std_vector_LHCb__RichSummaryRadSegment;
-    std::vector<LHCb::RichSummaryTrack*>          m_std_vector_LHCb__RichSummaryTrackp;
-    std::vector<LHCb::TwoProngVertex*>            m_std_vector_LHCb__TwoProngVertexp;
-    std::vector<LHCb::VertexBase*>                m_std_vector_LHCb__VertexBasep;
-    std::vector<LHCb::WeightsVector*>             m_std_vector_LHCb__WeightsVectorp;
-    std::vector<SmartRef<LHCb::CaloCluster>>      m_std_vector_SmartRef_LHCb__CaloCluster;
-    std::vector<SmartRef<LHCb::CaloHypo>>         m_std_vector_SmartRef_LHCb__CaloHypo;
-    std::vector<SmartRef<LHCb::MuonCluster>>      m_std_vector_SmartRef_LHCb__MuonCluster;
-    std::vector<SmartRef<LHCb::MuonCoord>>        m_std_vector_SmartRef_LHCb__MuonCoord;
-    std::vector<SmartRef<LHCb::MuonPID>>          m_std_vector_SmartRef_LHCb__MuonPID;
-    std::vector<SmartRef<LHCb::NeutralPID>>       m_std_vector_SmartRef_LHCb__NeutralPID;
-    std::vector<SmartRef<LHCb::ProcStatus>>       m_std_vector_SmartRef_LHCb__ProcStatus;
-    std::vector<SmartRef<LHCb::ProtoParticle>>    m_std_vector_SmartRef_LHCb__ProtoParticle;
-    std::vector<SmartRef<LHCb::RecHeader>>        m_std_vector_SmartRef_LHCb__RecHeader;
-    std::vector<SmartRef<LHCb::RecSummary>>       m_std_vector_SmartRef_LHCb__RecSummary;
-    std::vector<SmartRef<LHCb::RecVertex>>        m_std_vector_SmartRef_LHCb__RecVertex;
-    std::vector<SmartRef<LHCb::RichPID>>          m_std_vector_SmartRef_LHCb__RichPID;
-    std::vector<SmartRef<LHCb::RichSummaryTrack>> m_std_vector_SmartRef_LHCb__RichSummaryTrack;
-    std::vector<SmartRef<LHCb::TwoProngVertex>>   m_std_vector_SmartRef_LHCb__TwoProngVertex;
-    std::vector<SmartRef<LHCb::UTSummary>>        m_std_vector_SmartRef_LHCb__UTSummary;
-    std::vector<SmartRef<LHCb::VertexBase>>       m_std_vector_SmartRef_LHCb__VertexBase;
-    std::vector<SmartRef<LHCb::WeightsVector>>    m_std_vector_SmartRef_LHCb__WeightsVector;
-    std::vector<const LHCb::RecVertex*>           _i1;
-    std::vector<const LHCb::VertexBase*>          _i2;
-    std::vector<std::pair<int, float>>            _i4;
+    Gaudi::SymMatrix9x9                                          _i5;
+    KeyedContainer<LHCb::Event::Calo::v1::BremInfo>              m_KeyedContainer_LHCb__BremInfo;
+    KeyedContainer<LHCb::CaloCluster>                            m_KeyedContainer_LHCb__CaloCluster;
+    KeyedContainer<LHCb::CaloHypo>                               m_KeyedContainer_LHCb__CaloHypo;
+    KeyedContainer<LHCb::Event::Calo::v1::CaloChargedPID>        m_KeyedContainer_LHCb__CaloChargedPID;
+    KeyedContainer<LHCb::MuonCluster>                            m_KeyedContainer_LHCb__MuonCluster;
+    KeyedContainer<LHCb::MuonCoord>                              m_KeyedContainer_LHCb__MuonCoord;
+    KeyedContainer<LHCb::MuonPID>                                m_KeyedContainer_LHCb__MuonPID;
+    KeyedContainer<LHCb::NeutralPID>                             m_KeyedContainer_LHCb__NeutralPID;
+    KeyedContainer<LHCb::ProtoParticle>                          m_KeyedContainer_LHCb__ProtoParticle;
+    KeyedContainer<LHCb::RecVertex>                              m_KeyedContainer_LHCb__RecVertex;
+    KeyedContainer<LHCb::RichPID>                                m_KeyedContainer_LHCb__RichPID;
+    KeyedContainer<LHCb::RichSummaryTrack>                       m_KeyedContainer_LHCb__RichSummaryTrack;
+    KeyedContainer<LHCb::TwoProngVertex>                         m_KeyedContainer_LHCb__TwoProngVertex;
+    KeyedContainer<LHCb::VertexBase>                             m_KeyedContainer_LHCb__VertexBase;
+    KeyedContainer<LHCb::WeightsVector>                          m_KeyedContainer_LHCb__WeightsVector;
+    ObjectVector<LHCb::Event::Calo::v1::BremInfo>                m_ObjectVector_LHCb__BremInfo;
+    ObjectVector<LHCb::Event::Calo::v1::CaloChargedPID>          m_ObjectVector_LHCb__CaloChargedPID;
+    ObjectVector<LHCb::CaloCluster>                              m_ObjectVector_LHCb__CaloCluster;
+    ObjectVector<LHCb::CaloHypo>                                 m_ObjectVector_LHCb__CaloHypo;
+    ObjectVector<LHCb::MuonCluster>                              m_ObjectVector_LHCb__MuonCluster;
+    ObjectVector<LHCb::MuonCoord>                                m_ObjectVector_LHCb__MuonCoord;
+    ObjectVector<LHCb::MuonPID>                                  m_ObjectVector_LHCb__MuonPID;
+    ObjectVector<LHCb::NeutralPID>                               m_ObjectVector_LHCb__NeutralPID;
+    ObjectVector<LHCb::ProtoParticle>                            m_ObjectVector_LHCb__ProtoParticle;
+    ObjectVector<LHCb::RecVertex>                                m_ObjectVector_LHCb__RecVertex;
+    ObjectVector<LHCb::RichPID>                                  m_ObjectVector_LHCb__RichPID;
+    ObjectVector<LHCb::RichSummaryTrack>                         m_ObjectVector_LHCb__RichSummaryTrack;
+    ObjectVector<LHCb::TwoProngVertex>                           m_ObjectVector_LHCb__TwoProngVertex;
+    ObjectVector<LHCb::VertexBase>                               m_ObjectVector_LHCb__VertexBase;
+    ObjectVector<LHCb::WeightsVector>                            m_ObjectVector_LHCb__WeightsVector;
+    SmartRef<LHCb::Event::Calo::v1::BremInfo>                    m_SmartRef_LHCb__BremInfo;
+    SmartRef<LHCb::Event::Calo::v1::CaloChargedPID>              m_SmartRef_LHCb__CaloChargedPID;
+    SmartRef<LHCb::CaloCluster>                                  m_SmartRef_LHCb__CaloCluster;
+    SmartRef<LHCb::CaloHypo>                                     m_SmartRef_LHCb__CaloHypo;
+    SmartRef<LHCb::MuonCluster>                                  m_SmartRef_LHCb__MuonCluster;
+    SmartRef<LHCb::MuonCoord>                                    m_SmartRef_LHCb__MuonCoord;
+    SmartRef<LHCb::MuonPID>                                      m_SmartRef_LHCb__MuonPID;
+    SmartRef<LHCb::NeutralPID>                                   m_SmartRef_LHCb__NeutralPID;
+    SmartRef<LHCb::ProcStatus>                                   m_SmartRef_LHCb__ProcStatus;
+    SmartRef<LHCb::ProtoParticle>                                m_SmartRef_LHCb__ProtoParticle;
+    SmartRef<LHCb::RecHeader>                                    m_SmartRef_LHCb__RecHeader;
+    SmartRef<LHCb::RecSummary>                                   m_SmartRef_LHCb__RecSummary;
+    SmartRef<LHCb::RecVertex>                                    m_SmartRef_LHCb__RecVertex;
+    SmartRef<LHCb::RichPID>                                      m_SmartRef_LHCb__RichPID;
+    SmartRef<LHCb::RichSummaryTrack>                             m_SmartRef_LHCb__RichSummaryTrack;
+    SmartRef<LHCb::TwoProngVertex>                               m_SmartRef_LHCb__TwoProngVertex;
+    SmartRef<LHCb::UTSummary>                                    m_SmartRef_LHCb__UTSummary;
+    SmartRef<LHCb::VertexBase>                                   m_SmartRef_LHCb__VertexBase;
+    SmartRef<LHCb::WeightsVector>                                m_SmartRef_LHCb__WeightsVector;
+    SmartRefVector<LHCb::Event::Calo::v1::BremInfo>              m_SmartRefVector_LHCb__BremInfo;
+    SmartRefVector<LHCb::Event::Calo::v1::CaloChargedPID>        m_SmartRefVector_LHCb__CaloChargedPID;
+    SmartRefVector<LHCb::CaloCluster>                            m_SmartRefVector_LHCb__CaloCluster;
+    SmartRefVector<LHCb::CaloHypo>                               m_SmartRefVector_LHCb__CaloHypo;
+    SmartRefVector<LHCb::MuonCluster>                            m_SmartRefVector_LHCb__MuonCluster;
+    SmartRefVector<LHCb::MuonCoord>                              m_SmartRefVector_LHCb__MuonCoord;
+    SmartRefVector<LHCb::MuonPID>                                m_SmartRefVector_LHCb__MuonPID;
+    SmartRefVector<LHCb::NeutralPID>                             m_SmartRefVector_LHCb__NeutralPID;
+    SmartRefVector<LHCb::ProcStatus>                             m_SmartRefVector_LHCb__ProcStatus;
+    SmartRefVector<LHCb::ProtoParticle>                          m_SmartRefVector_LHCb__ProtoParticle;
+    SmartRefVector<LHCb::RecHeader>                              m_SmartRefVector_LHCb__RecHeader;
+    SmartRefVector<LHCb::RecSummary>                             m_SmartRefVector_LHCb__RecSummary;
+    SmartRefVector<LHCb::RecVertex>                              m_SmartRefVector_LHCb__RecVertex;
+    SmartRefVector<LHCb::RichPID>                                m_SmartRefVector_LHCb__RichPID;
+    SmartRefVector<LHCb::RichSummaryTrack>                       m_SmartRefVector_LHCb__RichSummaryTrack;
+    SmartRefVector<LHCb::TwoProngVertex>                         m_SmartRefVector_LHCb__TwoProngVertex;
+    SmartRefVector<LHCb::UTSummary>                              m_SmartRefVector_LHCb__UTSummary;
+    SmartRefVector<LHCb::VertexBase>                             m_SmartRefVector_LHCb__VertexBase;
+    SmartRefVector<LHCb::WeightsVector>                          m_SmartRefVector_LHCb__WeightsVector;
+    std::pair<int, float>                                        _i3;
+    std::vector<LHCb::Event::Calo::v1::BremInfo*>                m_std_vector_LHCb__BremInfop;
+    std::vector<LHCb::Event::Calo::v1::CaloChargedPID*>          m_std_vector_LHCb__CaloChargedPIDp;
+    std::vector<LHCb::CaloCluster*>                              m_std_vector_LHCb__CaloClusterp;
+    std::vector<LHCb::CaloClusterEntry>                          m_std_vector_LHCb__CaloClusterEntry;
+    std::vector<LHCb::CaloHypo*>                                 m_std_vector_LHCb__CaloHypop;
+    std::vector<LHCb::MuonCluster*>                              m_std_vector_LHCb__MuonClusterp;
+    std::vector<LHCb::MuonCoord*>                                m_std_vector_LHCb__MuonCoordp;
+    std::vector<LHCb::MuonPID*>                                  m_std_vector_LHCb__MuonPIDp;
+    std::vector<LHCb::NeutralPID*>                               m_std_vector_LHCb__NeutralPIDp;
+    std::vector<LHCb::ProtoParticle*>                            m_std_vector_LHCb__ProtoParticlep;
+    std::vector<LHCb::RecVertex*>                                m_std_vector_LHCb__RecVertexp;
+    std::vector<LHCb::RichPID*>                                  m_std_vector_LHCb__RichPIDp;
+    std::vector<LHCb::RichSummaryPhoton>                         m_std_vector_LHCb__RichSummaryPhoton;
+    std::vector<LHCb::RichSummaryRadSegment>                     m_std_vector_LHCb__RichSummaryRadSegment;
+    std::vector<LHCb::RichSummaryTrack*>                         m_std_vector_LHCb__RichSummaryTrackp;
+    std::vector<LHCb::TwoProngVertex*>                           m_std_vector_LHCb__TwoProngVertexp;
+    std::vector<LHCb::VertexBase*>                               m_std_vector_LHCb__VertexBasep;
+    std::vector<LHCb::WeightsVector*>                            m_std_vector_LHCb__WeightsVectorp;
+    std::vector<SmartRef<LHCb::Event::Calo::v1::BremInfo>>       m_std_vector_SmartRef_LHCb__BremInfo;
+    std::vector<SmartRef<LHCb::Event::Calo::v1::CaloChargedPID>> m_std_vector_SmartRef_LHCb__CaloChargedPID;
+    std::vector<SmartRef<LHCb::CaloCluster>>                     m_std_vector_SmartRef_LHCb__CaloCluster;
+    std::vector<SmartRef<LHCb::CaloHypo>>                        m_std_vector_SmartRef_LHCb__CaloHypo;
+    std::vector<SmartRef<LHCb::MuonCluster>>                     m_std_vector_SmartRef_LHCb__MuonCluster;
+    std::vector<SmartRef<LHCb::MuonCoord>>                       m_std_vector_SmartRef_LHCb__MuonCoord;
+    std::vector<SmartRef<LHCb::MuonPID>>                         m_std_vector_SmartRef_LHCb__MuonPID;
+    std::vector<SmartRef<LHCb::NeutralPID>>                      m_std_vector_SmartRef_LHCb__NeutralPID;
+    std::vector<SmartRef<LHCb::ProcStatus>>                      m_std_vector_SmartRef_LHCb__ProcStatus;
+    std::vector<SmartRef<LHCb::ProtoParticle>>                   m_std_vector_SmartRef_LHCb__ProtoParticle;
+    std::vector<SmartRef<LHCb::RecHeader>>                       m_std_vector_SmartRef_LHCb__RecHeader;
+    std::vector<SmartRef<LHCb::RecSummary>>                      m_std_vector_SmartRef_LHCb__RecSummary;
+    std::vector<SmartRef<LHCb::RecVertex>>                       m_std_vector_SmartRef_LHCb__RecVertex;
+    std::vector<SmartRef<LHCb::RichPID>>                         m_std_vector_SmartRef_LHCb__RichPID;
+    std::vector<SmartRef<LHCb::RichSummaryTrack>>                m_std_vector_SmartRef_LHCb__RichSummaryTrack;
+    std::vector<SmartRef<LHCb::TwoProngVertex>>                  m_std_vector_SmartRef_LHCb__TwoProngVertex;
+    std::vector<SmartRef<LHCb::UTSummary>>                       m_std_vector_SmartRef_LHCb__UTSummary;
+    std::vector<SmartRef<LHCb::VertexBase>>                      m_std_vector_SmartRef_LHCb__VertexBase;
+    std::vector<SmartRef<LHCb::WeightsVector>>                   m_std_vector_SmartRef_LHCb__WeightsVector;
+    std::vector<const LHCb::RecVertex*>                          _i1;
+    std::vector<const LHCb::VertexBase*>                         _i2;
+    std::vector<std::pair<int, float>>                           _i4;
     // end instantiations
   };
 } // namespace
diff --git a/Event/RecEvent/dict/selection.xml b/Event/RecEvent/dict/selection.xml
index 20a9c965e4c..e4c518e35e0 100755
--- a/Event/RecEvent/dict/selection.xml
+++ b/Event/RecEvent/dict/selection.xml
@@ -15,6 +15,8 @@
   <class name = "std::vector<const LHCb::RecVertex*>"    />
   <class name = "std::vector<const LHCb::VertexBase*>"   />
   <class name = "std::vector<std::pair<int,float> >"     />
+  <class name="KeyedContainer<LHCb::Event::Calo::v1::BremInfo,Containers::KeyedObjectManager<Containers::hashmap> >" id="000607d6-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
+  <class name="KeyedContainer<LHCb::Event::Calo::v1::CaloChargedPID,Containers::KeyedObjectManager<Containers::hashmap> >" id="000607d5-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
   <class name="KeyedContainer<LHCb::CaloCluster,Containers::KeyedObjectManager<Containers::hashmap> >" id="000607d3-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
   <class name="KeyedContainer<LHCb::CaloHypo,Containers::KeyedObjectManager<Containers::hashmap> >" id="000607d4-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
   <class name="KeyedContainer<LHCb::MuonCluster,Containers::KeyedObjectManager<Containers::hashmap> >" id="00062b21-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
@@ -28,6 +30,8 @@
   <class name="KeyedContainer<LHCb::TwoProngVertex,Containers::KeyedObjectManager<Containers::hashmap> >" id="00062738-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
   <class name="KeyedContainer<LHCb::VertexBase,Containers::KeyedObjectManager<Containers::hashmap> >" id="0006032b-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
   <class name="KeyedContainer<LHCb::WeightsVector,Containers::KeyedObjectManager<Containers::hashmap> >" id="0006272f-0000-0000-0000-000000000000"> <field name="m_cont" transient="true"/> <field name="m_random" transient="true"/> </class>
+  <class name="LHCb::Event::Calo::v1::BremInfo" id="000007d6-0000-0000-0000-000000000000"/>
+  <class name="LHCb::Event::Calo::v1::CaloChargedPID" id="000007d5-0000-0000-0000-000000000000"/>
   <class name="LHCb::CaloCluster" id="000007d3-0000-0000-0000-000000000000"/>
   <class name="LHCb::CaloClusterEntry"/>
   <class name="LHCb::CaloHypo" id="000007d4-0000-0000-0000-000000000000"/>
@@ -51,6 +55,8 @@
   <class name="LHCb::UTSummary" id="0000232d-0000-0000-0000-000000000000"/>
   <class name="LHCb::VertexBase" id="0000032b-0000-0000-0000-000000000000"/>
   <class name="LHCb::WeightsVector" id="0000272f-0000-0000-0000-000000000000"/>
+  <class name="ObjectVector<LHCb::Event::Calo::v1::BremInfo>" id="000207d6-0000-0000-0000-000000000000"/>
+  <class name="ObjectVector<LHCb::Event::Calo::v1::CaloChargedPID>" id="000207d5-0000-0000-0000-000000000000"/>
   <class name="ObjectVector<LHCb::CaloCluster>" id="000207d3-0000-0000-0000-000000000000"/>
   <class name="ObjectVector<LHCb::CaloHypo>" id="000207d4-0000-0000-0000-000000000000"/>
   <class name="ObjectVector<LHCb::MuonCluster>" id="00022b21-0000-0000-0000-000000000000"/>
@@ -64,6 +70,8 @@
   <class name="ObjectVector<LHCb::TwoProngVertex>" id="00022738-0000-0000-0000-000000000000"/>
   <class name="ObjectVector<LHCb::VertexBase>" id="0002032b-0000-0000-0000-000000000000"/>
   <class name="ObjectVector<LHCb::WeightsVector>" id="0002272f-0000-0000-0000-000000000000"/>
+  <class name="SmartRef<LHCb::Event::Calo::v1::BremInfo>"> <field name="m_target" transient="true"/> </class>
+  <class name="SmartRef<LHCb::Event::Calo::v1::CaloChargedPID>"> <field name="m_target" transient="true"/> </class>
   <class name="SmartRef<LHCb::CaloCluster>"> <field name="m_target" transient="true"/> </class>
   <class name="SmartRef<LHCb::CaloHypo>"> <field name="m_target" transient="true"/> </class>
   <class name="SmartRef<LHCb::MuonCluster>"> <field name="m_target" transient="true"/> </class>
@@ -81,6 +89,8 @@
   <class name="SmartRef<LHCb::UTSummary>"> <field name="m_target" transient="true"/> </class>
   <class name="SmartRef<LHCb::VertexBase>"> <field name="m_target" transient="true"/> </class>
   <class name="SmartRef<LHCb::WeightsVector>"> <field name="m_target" transient="true"/> </class>
+  <class name="SmartRefVector<LHCb::Event::Calo::v1::BremInfo>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
+  <class name="SmartRefVector<LHCb::Event::Calo::v1::CaloChargedPID>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
   <class name="SmartRefVector<LHCb::CaloCluster>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
   <class name="SmartRefVector<LHCb::CaloHypo>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
   <class name="SmartRefVector<LHCb::MuonCluster>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
@@ -98,6 +108,8 @@
   <class name="SmartRefVector<LHCb::UTSummary>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
   <class name="SmartRefVector<LHCb::VertexBase>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
   <class name="SmartRefVector<LHCb::WeightsVector>"> <field name="m_contd" transient="true"/> <field name="m_data" transient="true"/> </class>
+  <class name="std::vector<LHCb::Event::Calo::v1::BremInfo*>"/>
+  <class name="std::vector<LHCb::Event::Calo::v1::CaloChargedPID*>"/>
   <class name="std::vector<LHCb::CaloCluster*>"/>
   <class name="std::vector<LHCb::CaloClusterEntry>"/>
   <class name="std::vector<LHCb::CaloHypo*>"/>
@@ -114,6 +126,8 @@
   <class name="std::vector<LHCb::TwoProngVertex*>"/>
   <class name="std::vector<LHCb::VertexBase*>"/>
   <class name="std::vector<LHCb::WeightsVector*>"/>
+  <class name="std::vector<SmartRef<LHCb::Event::Calo::v1::BremInfo> >"/>
+  <class name="std::vector<SmartRef<LHCb::Event::Calo::v1::CaloChargedPID> >"/>
   <class name="std::vector<SmartRef<LHCb::CaloCluster> >"/>
   <class name="std::vector<SmartRef<LHCb::CaloHypo> >"/>
   <class name="std::vector<SmartRef<LHCb::MuonCluster> >"/>
diff --git a/Event/RecEvent/include/Event/CaloChargedInfo_v1.h b/Event/RecEvent/include/Event/CaloChargedInfo_v1.h
index 6b0e9efd68b..642f3eea39a 100644
--- a/Event/RecEvent/include/Event/CaloChargedInfo_v1.h
+++ b/Event/RecEvent/include/Event/CaloChargedInfo_v1.h
@@ -13,27 +13,44 @@
 #include "Event/Track.h"
 #include "GaudiKernel/KeyedContainer.h"
 #include "GaudiKernel/KeyedObject.h"
+#include "GaudiKernel/SharedObjectsContainer.h"
 #include "GaudiKernel/SmartRef.h"
+#include <functional>
+#include <vector>
 
 namespace LHCb::Event::Calo {
 
   inline namespace v1 {
 
     // Class ID definitions
-    static const CLID CLID_ChargedPID = 2005;
-    static const CLID CLID_BremInfo   = 2006;
+    static const CLID CLID_CaloChargedPID = 2005;
+    static const CLID CLID_BremInfo       = 2006;
+
+    // locations (needed for packing)
+    namespace CaloChargedPIDLocation {
+      inline const std::string Default = "";
+    } // namespace CaloChargedPIDLocation
+    namespace BremInfoLocation {
+      inline const std::string Default = "";
+    } // namespace BremInfoLocation
 
     // class for Calo Charged PID info
-    class ChargedPID final : public KeyedObject<int> {
+    class CaloChargedPID final : public KeyedObject<int> {
       using CellID = LHCb::Detector::Calo::CellID;
 
     public:
-      /// typedef for KeyedContainer of ChargedPID
-      typedef KeyedContainer<ChargedPID, Containers::HashMap> Container;
+      using Vector      = std::vector<CaloChargedPID*>;
+      using ConstVector = std::vector<const CaloChargedPID*>;
+
+      /// typedef for KeyedContainer of CaloChargedPID
+      typedef KeyedContainer<CaloChargedPID, Containers::HashMap> Container;
+
+      using Selection = SharedObjectsContainer<CaloChargedPID>;
+      using Range     = Gaudi::Range_<ConstVector>;
 
       // Retrieve pointer to class definition structure
       const CLID&        clID() const override { return classID(); }
-      static const CLID& classID() { return CLID_ChargedPID; }
+      static const CLID& classID() { return CLID_CaloChargedPID; }
 
       // related track
       const LHCb::Track* idTrack() const { return m_IDTrack; }
@@ -79,6 +96,22 @@ namespace LHCb::Event::Calo {
         m_HcalPIDmu = proxy.HcalPIDmu().cast();
       }
 
+      // setters for (un)packer
+      void setInEcal( bool value ) noexcept { m_InEcal = value; }
+      void setClusterID( CellID value ) noexcept { m_ClusterID = value; }
+      void setClusterMatch( float value ) noexcept { m_ClusterMatch = value; }
+      void setElectronID( CellID value ) noexcept { m_ElectronID = value; }
+      void setElectronMatch( float value ) noexcept { m_ElectronMatch = value; }
+      void setElectronEnergy( float value ) noexcept { m_ElectronEnergy = value; }
+      void setElectronShowerEoP( float value ) noexcept { m_ElectronShowerEoP = value; }
+      void setElectronShowerDLL( float value ) noexcept { m_ElectronShowerDLL = value; }
+      void setEcalPIDe( float value ) noexcept { m_EcalPIDe = value; }
+      void setEcalPIDmu( float value ) noexcept { m_EcalPIDmu = value; }
+      void setInHcal( bool value ) noexcept { m_InHcal = value; }
+      void setHcalEoP( float value ) noexcept { m_HcalEoP = value; }
+      void setHcalPIDe( float value ) noexcept { m_HcalPIDe = value; }
+      void setHcalPIDmu( float value ) noexcept { m_HcalPIDmu = value; }
+
     private:
       // Ecal
       bool   m_InEcal{false};
@@ -93,22 +126,28 @@ namespace LHCb::Event::Calo {
       float  m_EcalPIDmu{0.f};
       // Hcal
       bool  m_InHcal{false};
-      float m_HcalEoP{-1.f};
+      float m_HcalEoP{0.f};
       float m_HcalPIDe{0.f};
       float m_HcalPIDmu{0.f};
       // related track
       SmartRef<LHCb::Track> m_IDTrack;
 
-    }; // class ChargedPID
+    }; // class CaloChargedPID
 
     // class bremsstrahlung information
     class BremInfo final : public KeyedObject<int> {
       using CellID = LHCb::Detector::Calo::CellID;
 
     public:
+      using Vector      = std::vector<BremInfo*>;
+      using ConstVector = std::vector<const BremInfo*>;
+
       /// typedef for KeyedContainer of BremInfo
       typedef KeyedContainer<BremInfo, Containers::HashMap> Container;
 
+      using Selection = SharedObjectsContainer<BremInfo>;
+      using Range     = Gaudi::Range_<ConstVector>;
+
       // Retrieve pointer to class definition structure
       const CLID&        clID() const override { return classID(); }
       static const CLID& classID() { return CLID_BremInfo; }
@@ -145,6 +184,18 @@ namespace LHCb::Event::Calo {
         m_BremPIDe              = proxy.BremPIDe().cast();
       }
 
+      // setters for (un)packer
+      void setInBrem( bool value ) noexcept { m_InBrem = value; }
+      void setBremHypoID( CellID value ) noexcept { m_BremHypoID = value; }
+      void setBremHypoMatch( float value ) noexcept { m_BremHypoMatch = value; }
+      void setBremHypoEnergy( float value ) noexcept { m_BremHypoEnergy = value; }
+      void setBremHypoDeltaX( float value ) noexcept { m_BremHypoDeltaX = value; }
+      void setBremTrackBasedEnergy( float value ) noexcept { m_BremTrackBasedEnergy = value; }
+      void setBremBendingCorrection( float value ) noexcept { m_BremBendingCorrection = value; }
+      void setHasBrem( bool value ) noexcept { m_HasBrem = value; }
+      void setBremEnergy( float value ) noexcept { m_BremEnergy = value; }
+      void setBremPIDe( float value ) noexcept { m_BremPIDe = value; }
+
     private:
       bool                  m_InBrem{false};
       CellID                m_BremHypoID{};
@@ -161,8 +212,50 @@ namespace LHCb::Event::Calo {
     }; // class BremInfo
 
     /// Definition of Keyed Containers
-    typedef KeyedContainer<ChargedPID, Containers::HashMap> ChargedPIDs;
-    typedef KeyedContainer<BremInfo, Containers::HashMap>   BremInfos;
+    using CaloChargedPIDs = CaloChargedPID::Container;
+    using BremInfos       = BremInfo::Container;
 
   } // namespace v1
 } // namespace LHCb::Event::Calo
+
+template <>
+struct std::hash<LHCb::Event::Calo::v1::CaloChargedPID> {
+  std::size_t operator()( const LHCb::Event::Calo::v1::CaloChargedPID& pid ) const noexcept {
+    auto hashes = std::array{std::hash<float>{}( pid.InEcal() ),
+                             std::hash<float>{}( pid.ClusterID().all() ),
+                             std::hash<float>{}( pid.ClusterMatch() ),
+                             std::hash<float>{}( pid.ElectronID().all() ),
+                             std::hash<float>{}( pid.ElectronMatch() ),
+                             std::hash<float>{}( pid.ElectronEnergy() ),
+                             std::hash<float>{}( pid.ElectronShowerEoP() ),
+                             std::hash<float>{}( pid.ElectronShowerDLL() ),
+                             std::hash<float>{}( pid.EcalPIDe() ),
+                             std::hash<float>{}( pid.EcalPIDmu() ),
+                             std::hash<float>{}( pid.InHcal() ),
+                             std::hash<float>{}( pid.HcalEoP() ),
+                             std::hash<float>{}( pid.HcalPIDe() ),
+                             std::hash<float>{}( pid.HcalPIDmu() )};
+    return std::accumulate( hashes.begin(), hashes.end(), std::size_t{0}, []( std::size_t i, std::size_t h ) {
+      return i ^ ( h + 0x9e3779b9 + ( i << 6 ) + ( i >> 2 ) );
+    } );
+  }
+};
+
+template <>
+struct std::hash<LHCb::Event::Calo::v1::BremInfo> {
+  std::size_t operator()( const LHCb::Event::Calo::v1::BremInfo& pid ) const noexcept {
+    auto hashes = std::array{std::hash<float>{}( pid.InBrem() ),
+                             std::hash<float>{}( pid.BremHypoID().all() ),
+                             std::hash<float>{}( pid.BremHypoMatch() ),
+                             std::hash<float>{}( pid.BremHypoEnergy() ),
+                             std::hash<float>{}( pid.BremHypoDeltaX() ),
+                             std::hash<float>{}( pid.BremTrackBasedEnergy() ),
+                             std::hash<float>{}( pid.BremBendingCorrection() ),
+                             std::hash<float>{}( pid.HasBrem() ),
+                             std::hash<float>{}( pid.BremEnergy() ),
+                             std::hash<float>{}( pid.BremPIDe() )};
+    return std::accumulate( hashes.begin(), hashes.end(), std::size_t{0}, []( std::size_t i, std::size_t h ) {
+      return i ^ ( h + 0x9e3779b9 + ( i << 6 ) + ( i >> 2 ) );
+    } );
+  }
+};
\ No newline at end of file
diff --git a/Event/RecEvent/include/Event/ProtoParticle.h b/Event/RecEvent/include/Event/ProtoParticle.h
index 335711bdab5..6b37c2d2c34 100644
--- a/Event/RecEvent/include/Event/ProtoParticle.h
+++ b/Event/RecEvent/include/Event/ProtoParticle.h
@@ -11,7 +11,11 @@
 #pragma once
 
 // Include files
+#include "Event/CaloChargedInfo_v1.h"
 #include "Event/CaloHypo.h"
+#include "Event/MuonPID.h"
+#include "Event/NeutralPID.h"
+#include "Event/RichPID.h"
 #include "Event/Track.h"
 #include "GaudiKernel/KeyedContainer.h"
 #include "GaudiKernel/KeyedObject.h"
@@ -41,9 +45,6 @@ namespace LHCb {
 
   // Forward declarations
   class ParticleID;
-  class RichPID;
-  class MuonPID;
-  class NeutralPID;
 
   // Class ID definition
   static const CLID CLID_ProtoParticle = 803;
@@ -207,7 +208,9 @@ namespace LHCb {
         , m_track( proto.track() )
         , m_richPID( proto.richPID() )
         , m_muonPID( proto.muonPID() )
-        , m_neutralPID( proto.neutralPID() ) {}
+        , m_neutralPID( proto.neutralPID() )
+        , m_caloChargedPID( proto.caloChargedPID() )
+        , m_bremInfo( proto.bremInfo() ) {}
 
     /// Default Constructor
     ProtoParticle() = default;
@@ -338,17 +341,36 @@ namespace LHCb {
     /// Update (pointer)  Reference to possible NeutralPID result
     void setNeutralPID( const LHCb::NeutralPID* value );
 
+    /// Retrieve (const)  Reference to possible CaloChargedPID result
+    const LHCb::Event::Calo::v1::CaloChargedPID* caloChargedPID() const;
+
+    /// Update  Reference to possible CaloChargedPID result
+    void setCaloChargedPID( const SmartRef<LHCb::Event::Calo::v1::CaloChargedPID>& value );
+
+    /// Update (pointer)  Reference to possible CaloChargedPID result
+    void setCaloChargedPID( const LHCb::Event::Calo::v1::CaloChargedPID* value );
+
+    /// Retrieve (const)  Reference to possible BremInfo result
+    const LHCb::Event::Calo::v1::BremInfo* bremInfo() const;
+
+    /// Update  Reference to possible BremInfo result
+    void setBremInfo( const SmartRef<LHCb::Event::Calo::v1::BremInfo>& value );
+
+    /// Update (pointer)  Reference to possible BremInfo result
+    void setBremInfo( const LHCb::Event::Calo::v1::BremInfo* value );
+
     friend std::ostream& operator<<( std::ostream& str, const ProtoParticle& obj ) { return obj.fillStream( str ); }
 
   private:
     ExtraInfo m_extraInfo; ///< Additional particle ID and user information. Do not access directly, use *Info() methods
                            ///< instead.
-    SmartRefVector<LHCb::CaloHypo> m_calo;       ///< References to possible calorimeter results
-    SmartRef<LHCb::Track>          m_track;      ///< Reference to possible track used
-    SmartRef<LHCb::RichPID>        m_richPID;    ///< Reference to possible RichPID result
-    SmartRef<LHCb::MuonPID>        m_muonPID;    ///< Reference to possible MuonPID result
-    SmartRef<LHCb::NeutralPID>     m_neutralPID; ///< Reference to possible NeutralPID result
-
+    SmartRefVector<LHCb::CaloHypo>                  m_calo;           ///< References to possible calorimeter results
+    SmartRef<LHCb::Track>                           m_track;          ///< Reference to possible track used
+    SmartRef<LHCb::RichPID>                         m_richPID;        ///< Reference to possible RichPID result
+    SmartRef<LHCb::MuonPID>                         m_muonPID;        ///< Reference to possible MuonPID result
+    SmartRef<LHCb::NeutralPID>                      m_neutralPID;     ///< Reference to possible NeutralPID result
+    SmartRef<LHCb::Event::Calo::v1::CaloChargedPID> m_caloChargedPID; ///< Reference to possible CaloChargedPID result
+    SmartRef<LHCb::Event::Calo::v1::BremInfo>       m_bremInfo;       ///< Reference to possible BremInfo result
     static const GaudiUtils::VectorMap<std::string, additionalInfo>& s_additionalInfoTypMap();
 
   }; // class ProtoParticle
@@ -580,9 +602,6 @@ namespace LHCb {
 // -----------------------------------------------------------------------------
 
 // Including forward declarations
-#include "Event/MuonPID.h"
-#include "Event/NeutralPID.h"
-#include "Event/RichPID.h"
 #include "Kernel/ParticleID.h"
 
 inline const CLID& LHCb::ProtoParticle::clID() const { return LHCb::ProtoParticle::classID(); }
@@ -753,6 +772,26 @@ inline void LHCb::ProtoParticle::setNeutralPID( const SmartRef<LHCb::NeutralPID>
 
 inline void LHCb::ProtoParticle::setNeutralPID( const LHCb::NeutralPID* value ) { m_neutralPID = value; }
 
+inline const LHCb::Event::Calo::v1::CaloChargedPID* LHCb::ProtoParticle::caloChargedPID() const {
+  return m_caloChargedPID;
+}
+
+inline void LHCb::ProtoParticle::setCaloChargedPID( const SmartRef<LHCb::Event::Calo::v1::CaloChargedPID>& value ) {
+  m_caloChargedPID = value;
+}
+
+inline void LHCb::ProtoParticle::setCaloChargedPID( const LHCb::Event::Calo::v1::CaloChargedPID* value ) {
+  m_caloChargedPID = value;
+}
+
+inline const LHCb::Event::Calo::v1::BremInfo* LHCb::ProtoParticle::bremInfo() const { return m_bremInfo; }
+
+inline void LHCb::ProtoParticle::setBremInfo( const SmartRef<LHCb::Event::Calo::v1::BremInfo>& value ) {
+  m_bremInfo = value;
+}
+
+inline void LHCb::ProtoParticle::setBremInfo( const LHCb::Event::Calo::v1::BremInfo* value ) { m_bremInfo = value; }
+
 inline LHCb::ProtoParticle* LHCb::ProtoParticle::clone() const { return new LHCb::ProtoParticle( *this ); }
 
 inline bool LHCb::ProtoParticle::hasInfo( const int key ) const { return m_extraInfo.end() != m_extraInfo.find( key ); }
diff --git a/Event/RecEvent/src/ProtoParticle.cpp b/Event/RecEvent/src/ProtoParticle.cpp
index acd59437f37..d19f8abd5ac 100644
--- a/Event/RecEvent/src/ProtoParticle.cpp
+++ b/Event/RecEvent/src/ProtoParticle.cpp
@@ -57,7 +57,8 @@ namespace Gaudi::Parsers {
 std::ostream& LHCb::ProtoParticle::fillStream( std::ostream& s ) const {
   s << "{"
     << " Track " << this->track() << " CaloHypos " << this->calo() << " RichPID " << this->richPID() << " MuonPID "
-    << this->muonPID() << " NeutralPID " << this->neutralPID() << " ExtraInfo [";
+    << this->muonPID() << " NeutralPID " << this->neutralPID() << this->caloChargedPID() << " BremInfo "
+    << this->bremInfo() << " ExtraInfo [";
   for ( const auto& i : extraInfo() ) {
     const auto info = static_cast<LHCb::ProtoParticle::additionalInfo>( i.first );
     s << " " << info << "=" << i.second;
diff --git a/Event/RecreatePIDTools/src/ChargedProtoParticleAddCaloInfo.cpp b/Event/RecreatePIDTools/src/ChargedProtoParticleAddCaloInfo.cpp
index 18d925050fa..f0f785a5f05 100644
--- a/Event/RecreatePIDTools/src/ChargedProtoParticleAddCaloInfo.cpp
+++ b/Event/RecreatePIDTools/src/ChargedProtoParticleAddCaloInfo.cpp
@@ -94,11 +94,11 @@ namespace LHCb::Rec::ProtoParticle::Charged {
     using additionalInfo = LHCb::ProtoParticle::additionalInfo;
 
     // Ecal info
-    class AddEcalInfo final : public AddCaloInfoBase<ChargedPID> {
+    class AddEcalInfo final : public AddCaloInfoBase<CaloChargedPID> {
     public:
       // constructor
       AddEcalInfo( std::string const& type, std::string const& name, IInterface const* parent )
-          : AddCaloInfoBase<ChargedPID>::AddCaloInfoBase( type, name, parent ) {}
+          : AddCaloInfoBase<CaloChargedPID>::AddCaloInfoBase( type, name, parent ) {}
 
       // main execution
       StatusCode operator()( ProtoParticles& protos, IGeometryInfo const& ) const override {
@@ -137,6 +137,8 @@ namespace LHCb::Rec::ProtoParticle::Charged {
           proto->addInfo( additionalInfo::EcalPIDmu, pid->EcalPIDmu() );
           // add relevant CaloHypo
           addCaloHypo( etable, cellid, proto );
+          // reference to CaloChargedPID object
+          proto->setCaloChargedPID( pid );
         }
         return StatusCode::SUCCESS;
       }
@@ -147,10 +149,10 @@ namespace LHCb::Rec::ProtoParticle::Charged {
     };
 
     // Hcal info
-    struct AddHcalInfo final : AddCaloInfoBase<ChargedPID> {
+    struct AddHcalInfo final : AddCaloInfoBase<CaloChargedPID> {
       // constructor
       AddHcalInfo( std::string const& type, std::string const& name, IInterface const* parent )
-          : AddCaloInfoBase<ChargedPID>::AddCaloInfoBase( type, name, parent ) {}
+          : AddCaloInfoBase<CaloChargedPID>::AddCaloInfoBase( type, name, parent ) {}
 
       // main execution
       StatusCode operator()( ProtoParticles& protos, IGeometryInfo const& ) const override {
@@ -224,6 +226,8 @@ namespace LHCb::Rec::ProtoParticle::Charged {
           proto->addInfo( additionalInfo::BremPIDe, pid->BremPIDe() );
           // add relevant CaloHypo
           addCaloHypo( phtable, cellid, proto );
+          // reference to BremInfo object
+          proto->setBremInfo( pid );
         }
         return StatusCode::SUCCESS;
       }
@@ -234,11 +238,11 @@ namespace LHCb::Rec::ProtoParticle::Charged {
     };
 
     // (re)add CaloHypo info
-    class AddHypos final : public AddCaloInfoBase<ChargedPID> {
+    class AddHypos final : public AddCaloInfoBase<CaloChargedPID> {
     public:
       // constructor
       AddHypos( std::string const& type, std::string const& name, IInterface const* parent )
-          : AddCaloInfoBase<ChargedPID>::AddCaloInfoBase( type, name, parent ) {}
+          : AddCaloInfoBase<CaloChargedPID>::AddCaloInfoBase( type, name, parent ) {}
 
       // main execution
       StatusCode operator()( ProtoParticles& protos, IGeometryInfo const& ) const override {
diff --git a/Event/RecreatePIDTools/src/PrintProtoParticles.cpp b/Event/RecreatePIDTools/src/PrintProtoParticles.cpp
index 72aa0823dce..f11241385cb 100644
--- a/Event/RecreatePIDTools/src/PrintProtoParticles.cpp
+++ b/Event/RecreatePIDTools/src/PrintProtoParticles.cpp
@@ -24,6 +24,8 @@ namespace LHCb {
                  << " Track " << ( proto->track() != nullptr ) << " CaloHypos " << proto->calo().size() << " RichPID "
                  << ( proto->richPID() != nullptr ) << " MuonPID " << ( proto->muonPID() != nullptr ) << " NeutralPID "
                  << ( proto->neutralPID() != nullptr ) << "\n"
+                 << " CaloChargedPID " << ( proto->caloChargedPID() != nullptr ) << " BremInfo "
+                 << ( proto->bremInfo() != nullptr ) << "\n"
                  << "ExtraInfo ["
                  << "\n";
         for ( const auto& i : proto->extraInfo() ) {
diff --git a/GaudiConf/python/GaudiConf/reading.py b/GaudiConf/python/GaudiConf/reading.py
index 285533e43b3..423d3e19dca 100644
--- a/GaudiConf/python/GaudiConf/reading.py
+++ b/GaudiConf/python/GaudiConf/reading.py
@@ -54,6 +54,10 @@ def type_map():
         "Tracks",
         "KeyedContainer<LHCb::RichPID,Containers::KeyedObjectManager<Containers::hashmap> >":
         "RichPIDs",
+        "KeyedContainer<LHCb::CaloChargedPID,Containers::KeyedObjectManager<Containers::hashmap> >":
+        "CaloChargedPIDs",
+        "KeyedContainer<LHCb::BremInfo,Containers::KeyedObjectManager<Containers::hashmap> >":
+        "BremInfos",
         "KeyedContainer<LHCb::MuonPID,Containers::KeyedObjectManager<Containers::hashmap> >":
         "MuonPIDs",
         "KeyedContainer<LHCb::NeutralPID,Containers::KeyedObjectManager<Containers::hashmap> >":
diff --git a/PyConf/python/PyConf/packing.py b/PyConf/python/PyConf/packing.py
index cf144a09773..0fad2367fca 100644
--- a/PyConf/python/PyConf/packing.py
+++ b/PyConf/python/PyConf/packing.py
@@ -107,18 +107,39 @@ def packers_map():
 def unpackers_map():
 
     from PyConf.Algorithms import (
-        RecVertexUnpacker, PrimaryVertexUnpacker, TrackUnpacker,
-        RichPIDUnpacker, MuonPIDUnpacker, NeutralPIDUnpacker, CaloHypoUnpacker,
-        CaloClusterUnpacker, CaloDigitUnpacker, CaloAdcUnpacker,
-        ProtoParticleUnpacker, ParticleUnpacker, ParticleSelectionUnpacker,
-        VertexUnpacker, FlavourTagUnpacker, P2VRelationUnpacker,
-        P2MCPRelationUnpacker, PP2MCPRelationUnpacker, P2IntRelationUnpacker,
-        P2InfoRelationUnpacker, RecSummaryUnpacker, SOATrackUnpacker,
-        SOACaloClusterUnpacker, SOACaloHypoUnpacker, SOAPVUnpacker)
+        RecVertexUnpacker,
+        PrimaryVertexUnpacker,
+        TrackUnpacker,
+        RichPIDUnpacker,
+        MuonPIDUnpacker,
+        NeutralPIDUnpacker,
+        CaloChargedPIDUnpacker,
+        BremInfoUnpacker,
+        CaloHypoUnpacker,
+        CaloClusterUnpacker,
+        CaloDigitUnpacker,
+        CaloAdcUnpacker,
+        ProtoParticleUnpacker,
+        ParticleUnpacker,
+        ParticleSelectionUnpacker,
+        VertexUnpacker,
+        FlavourTagUnpacker,
+        P2VRelationUnpacker,
+        P2MCPRelationUnpacker,
+        PP2MCPRelationUnpacker,
+        P2IntRelationUnpacker,
+        P2InfoRelationUnpacker,
+        RecSummaryUnpacker,
+        SOATrackUnpacker,
+        SOACaloClusterUnpacker,
+        SOACaloHypoUnpacker,
+    )
 
     return {
         "Tracks": TrackUnpacker,
         "RichPIDs": RichPIDUnpacker,
+        "CaloChargedPIDs": CaloChargedPIDUnpacker,
+        "BremInfos": BremInfoUnpacker,
         "MuonPIDs": MuonPIDUnpacker,
         "NeutralPIDs": NeutralPIDUnpacker,
         "CaloHypos": CaloHypoUnpacker,
-- 
GitLab