diff --git a/Phys/FunTuple/src/FunTuple.cpp b/Phys/FunTuple/src/FunTuple.cpp
index 43c532352cae80cd515d9d114f4a1594a5ebbbfa..f5913032d5899eb5bb83b3d636aa6e5d6207af6a 100755
--- a/Phys/FunTuple/src/FunTuple.cpp
+++ b/Phys/FunTuple/src/FunTuple.cpp
@@ -937,19 +937,13 @@ LHCb::FTuple::retype<ObjType> FunTupleBase<T>::find_candidates( const ObjType& p
 
   // The following implementation will change for now
   // copy the input particles (will have to do it eventually (?) once we have the decay descriptor matching in place)
-  if constexpr ( std::is_same_v<T, LHCb::Event::ChargedBasics> ) {
-    // make a copy of Charged Basic
-    ObjType cands{particles};
-    return cands;
-  } else {
-    // make a copy of Composites (no deep copy constructor?)
-    ObjType cands{particles.zipIdentifier(), particles};
-    cands.reserve( particles.size() );
-    const SIMDWrapper::InstructionSet simd_inst{SIMDWrapper::InstructionSet::Best};
-    auto const                        iterable = LHCb::Event::make_zip<simd_inst>( particles );
-    for ( auto const& prts : iterable ) cands.template copy_back<simd_inst>( prts );
-    return cands;
-  }
+  // make a copy of Composites (no deep copy constructor?)
+  ObjType cands{particles.zipIdentifier(), particles};
+  cands.reserve( particles.size() );
+  const SIMDWrapper::InstructionSet simd_inst{SIMDWrapper::InstructionSet::Best};
+  auto const                        iterable = LHCb::Event::make_zip<simd_inst>( particles );
+  for ( auto const& prts : iterable ) cands.template copy_back<simd_inst>( prts );
+  return cands;
 }
 
 // Monitoring the size of the current event and updating corresponding counters
diff --git a/Phys/FunTuple/src/InvalidValue.h b/Phys/FunTuple/src/InvalidValue.h
index 7c5d2bbfc1b205616930475c9b833aaa44506883..2723c965a9dfabf25125d1937ee046900d57e3ed 100644
--- a/Phys/FunTuple/src/InvalidValue.h
+++ b/Phys/FunTuple/src/InvalidValue.h
@@ -97,24 +97,6 @@ namespace LHCb {
     // assign a value to static member
     inline Gaudi::XYZPoint InvalidValue<Gaudi::XYZPoint>::value = InvalidValue<Gaudi::XYZPoint>::get_invalid_val();
 
-    /// Invalid value for LinAlg::Vec3
-    template <typename T>
-    using Vec3 = LHCb::LinAlg::Vec3<T>;
-    template <typename T>
-    struct InvalidValue<Vec3<T>> {
-      // helper function to get invalid value
-      static Vec3<T> get_invalid_val() {
-        std::array<T, 3> v{};
-        for ( auto& x : v ) x = InvalidValue<T>::value;
-        return Vec3<T>{v[0], v[1], v[2]};
-      }
-      // not a literal type. Cannot be constexpr and cannot be instantiated within the class declaration
-      static Vec3<T> value;
-    };
-    // assign a value to static member
-    template <typename T>
-    inline Vec3<T> InvalidValue<Vec3<T>>::value = InvalidValue<Vec3<T>>::get_invalid_val();
-
     /// Invalid value for LinAlg::Vec
     template <typename T, auto N>
     using Vec = LHCb::LinAlg::Vec<T, N>;
@@ -122,9 +104,9 @@ namespace LHCb {
     struct InvalidValue<Vec<T, N>> {
       // helper function to get invalid value
       static Vec<T, N> get_invalid_val() {
-        std::array<T, N> v{};
-        for ( auto& x : v ) x = InvalidValue<T>::value;
-        return Vec<T, N>{v};
+        Vec<T, N> v{};
+        v.m.fill( InvalidValue<T>::value );
+        return v;
       }
       // not a literal type. Cannot be constexpr and cannot be instantiated within the class declaration
       static Vec<T, N> value;
diff --git a/Phys/FunTuple/src/MakeDummyData.cpp b/Phys/FunTuple/src/MakeDummyData.cpp
index cd474c9b6faf7dc1401b06a0610bba9d39363d3b..c65bc5f1e56fcf50d1d371de9724d1d9f4513c69 100755
--- a/Phys/FunTuple/src/MakeDummyData.cpp
+++ b/Phys/FunTuple/src/MakeDummyData.cpp
@@ -504,10 +504,8 @@ namespace ChargedBasicsTag = LHCb::Event::ChargedBasicsTag;
 using MuonStatusMasks      = LHCb::Event::v2::Muon::StatusMasks;
 using MuonFlags            = LHCb::Event::flags_v<SIMDWrapper::scalar::types, MuonStatusMasks>;
 
-using output_t = std::tuple<LHCb::Event::ChargedBasics, std::unique_ptr<LHCb::Event::AssignedMasses>,
-                            std::unique_ptr<LHCb::Event::v2::RichPIDs>, std::unique_ptr<LHCb::Event::v2::Muon::PIDs>,
-                            std::unique_ptr<LHCb::Event::ParticleIDs>, std::unique_ptr<LHCb::Event::v3::Tracks>,
-                            std::unique_ptr<LHCb::Event::CombDLLs>>;
+using output_t = std::tuple<LHCb::Event::ChargedBasics, std::unique_ptr<LHCb::Event::v2::Muon::PIDs>,
+                            std::unique_ptr<LHCb::Event::v3::Tracks>>;
 
 class ChargedBasicsProducer
     : public Gaudi::Functional::MultiTransformer<output_t( EventContext const&, LHCb::UniqueIDGenerator const& )> {
@@ -516,16 +514,8 @@ public:
       : MultiTransformer( name, pSvcLocator,
                           {// input
                            KeyValue{"InputUniqueIDGenerator", LHCb::UniqueIDGeneratorLocation::Default}},
-                          {
-                              // output
-                              KeyValue{"Particles", ""},
-                              KeyValue{"Masses", ""},
-                              KeyValue{"RichPIDs", ""},
-                              KeyValue{"MuonPIDs", ""},
-                              KeyValue{"ParticleIDs", ""},
-                              KeyValue{"Tracks", ""},
-                              KeyValue{"CombDLLs", ""},
-                          } ) {}
+                          {// output
+                           KeyValue{"Particles", ""}, KeyValue{"MuonPIDs", ""}, KeyValue{"Tracks", ""}} ) {}
   StatusCode initialize() override {
     this->info() << "Initialising ChargedBasicsProducer" << endmsg;
 
@@ -559,35 +549,19 @@ public:
   output_t operator()( EventContext const& evtCtx, LHCb::UniqueIDGenerator const& unique_id_gen ) const override {
     this->info() << "Executing ChargedBasicsProducer" << endmsg;
 
-    /// create some particles with random values
-    auto zn = Zipping::generateZipIdentifier();
-
-    /// generate some tracks
-    auto tracks = std::make_unique<LHCb::Event::v3::Tracks>( LHCb::Event::v3::generate_tracks(
+    auto                       zn        = Zipping::generateZipIdentifier();
+    auto                       muon_pids = std::make_unique<LHCb::Event::v2::Muon::PIDs>( zn );
+    auto                       tracks    = std::make_unique<LHCb::Event::v3::Tracks>( LHCb::Event::v3::generate_tracks(
         m_nTracks, unique_id_gen, m_eventCount.value(), zn, LHCb::getMemResource( evtCtx ) ) );
+    LHCb::Event::ChargedBasics chargedbasics{tracks.get(), muon_pids.get()};
 
-    /// make RichPid and reserve memory for n tracks
-    auto rich_pids = std::make_unique<LHCb::Event::v2::RichPIDs>( zn );
-    rich_pids->reserve( m_nTracks );
-
-    /// make muonPid and reserve memory for n tracks
-    auto muon_pids = std::make_unique<LHCb::Event::v2::Muon::PIDs>( zn );
-    muon_pids->reserve( m_nTracks );
-
-    /// make assigned masses and reserve for tracks
-    auto masses = std::make_unique<LHCb::Event::AssignedMasses>( zn );
-    masses->reserve( m_nTracks );
-
-    /// make particle ids and reserve for n tracks
-    auto particle_ids = std::make_unique<LHCb::Event::ParticleIDs>( zn );
-    particle_ids->reserve( m_nTracks );
+    /// zip the SOA collection and loop through all the tracks
+    for ( const auto& track : tracks->scalar() ) {
 
-    /// make combdlls and reserve for n tracks
-    auto combdlls = std::make_unique<LHCb::Event::CombDLLs>( zn );
-    combdlls->reserve( m_nTracks );
+      auto part = chargedbasics.emplace_back<SIMDWrapper::InstructionSet::Scalar>();
 
-    /// zip the SOA collection and loop through all the tracks
-    for ( const auto& track : LHCb::Event::make_zip<SIMDWrapper::Scalar>( *tracks ) ) {
+      /// set track
+      part.field<ChargedBasicsTag::Track>().set( track.offset() );
 
       /// Get the (anti)particle property according charge of the track
       const LHCb::ParticleProperty* prop = nullptr;
@@ -600,42 +574,32 @@ public:
       }
 
       /// set RICHPIDCode
-      rich_pids->emplace_back<SIMDWrapper::InstructionSet::Scalar>().field<ChargedBasicsTag::RichPIDCode>().set( 0 );
+      part.field<ChargedBasicsTag::RichPIDCode>().set( 0 );
 
       /// set Status (?) and Chi2Corr (?)
       auto mu_pid = muon_pids->emplace_back<SIMDWrapper::InstructionSet::Scalar>();
+      part.field<ChargedBasicsTag::MuonPID>().set( mu_pid.offset() );
       mu_pid.field<MuonTag::Status>().set( MuonFlags( 0 ) );
       mu_pid.field<MuonTag::Chi2Corr>().set( std::numeric_limits<float>::lowest() );
 
       /// set mass
-      masses->emplace_back<SIMDWrapper::InstructionSet::Scalar>().field<ChargedBasicsTag::Masse>().set( prop->mass() );
+      part.field<ChargedBasicsTag::Mass>().set( prop->mass() );
 
       /// set particle id
-      particle_ids->emplace_back<SIMDWrapper::InstructionSet::Scalar>().field<ChargedBasicsTag::PID>().set(
-          prop->particleID().pid() );
-
-      /// set comdll related quantities
-      auto combdll = combdlls->emplace_back<SIMDWrapper::InstructionSet::Scalar>();
-      combdll.field<ChargedBasicsTag::CombDLLp>().set( std::numeric_limits<float>::lowest() );
-      combdll.field<ChargedBasicsTag::CombDLLe>().set( std::numeric_limits<float>::lowest() );
-      combdll.field<ChargedBasicsTag::CombDLLpi>().set( std::numeric_limits<float>::lowest() );
-      combdll.field<ChargedBasicsTag::CombDLLk>().set( std::numeric_limits<float>::lowest() );
-      combdll.field<ChargedBasicsTag::CombDLLmu>().set( std::numeric_limits<float>::lowest() );
+      part.field<ChargedBasicsTag::ParticleID>().set( prop->particleID().pid() );
+
+      /// set combDLL related quantities
+      part.field<ChargedBasicsTag::CombDLL>( ChargedBasicsTag::Hypo::p ).set( std::numeric_limits<float>::lowest() );
+      part.field<ChargedBasicsTag::CombDLL>( ChargedBasicsTag::Hypo::e ).set( std::numeric_limits<float>::lowest() );
+      part.field<ChargedBasicsTag::CombDLL>( ChargedBasicsTag::Hypo::pi ).set( std::numeric_limits<float>::lowest() );
+      part.field<ChargedBasicsTag::CombDLL>( ChargedBasicsTag::Hypo::K ).set( std::numeric_limits<float>::lowest() );
+      part.field<ChargedBasicsTag::CombDLL>( ChargedBasicsTag::Hypo::mu ).set( std::numeric_limits<float>::lowest() );
     }
 
     // event counter
     ++m_eventCount;
 
-    // we must be careful here, since doing a copy/move instruction will change the
-    // instruction set to "Best", giving problems comparing SIMD value types
-    return std::make_tuple(
-        // LHCb::Event::ChargedBasics
-        LHCb::Event::make_zip<SIMDWrapper::InstructionSet::Scalar>(
-            std::as_const( *tracks ), std::as_const( *rich_pids ), std::as_const( *muon_pids ),
-            std::as_const( *masses ), std::as_const( *particle_ids ), std::as_const( *combdlls ) ),
-        // return pointers of other objects
-        std::move( masses ), std::move( rich_pids ), std::move( muon_pids ), std::move( particle_ids ),
-        std::move( tracks ), std::move( combdlls ) );
+    return std::make_tuple( std::move( chargedbasics ), std::move( muon_pids ), std::move( tracks ) );
   }
 
 private: