diff --git a/PhysicsAnalysis/D3PDMaker/D3PDMakerTest/src/HitsFillerAlg.cxx b/PhysicsAnalysis/D3PDMaker/D3PDMakerTest/src/HitsFillerAlg.cxx
index 6b282e4f24953b74b3cce05efec4d74a39c3857c..99108713bd3a5f7cdf0067cf552beba59315ce01 100644
--- a/PhysicsAnalysis/D3PDMaker/D3PDMakerTest/src/HitsFillerAlg.cxx
+++ b/PhysicsAnalysis/D3PDMaker/D3PDMakerTest/src/HitsFillerAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id$
@@ -99,11 +99,13 @@ StatusCode HitsFillerAlg::fillTrackRecordCollection()
     CLHEP::Hep3Vector p(j+11,j+12,j+13);
     CLHEP::Hep3Vector x(j+14,j+15,j+16);
     c->Emplace(j, // PDG
+               j+20, // status
                (j+10)*1000, // energy
                p, //position
                x, //momentum
                j+17, // time
                j+18, // barcode
+               j+19, // id
                "volname" // volume name
                );
   }
diff --git a/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/MuonTruthHitsFillerTool.cxx b/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/MuonTruthHitsFillerTool.cxx
index ff522f3b1fb0ecde767affd180a30bc743e0b1ef..9fdbd5d5288cc8f1bcf379eca990cff8ea711358 100644
--- a/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/MuonTruthHitsFillerTool.cxx
+++ b/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/MuonTruthHitsFillerTool.cxx
@@ -35,7 +35,7 @@ MuonTruthHitsFillerTool::MuonTruthHitsFillerTool (const std::string& type,
   m_PRD_TruthNames.emplace_back("MM_TruthMap");
   m_PRD_TruthNames.emplace_back("STGC_TruthMap");
 
- 
+
 }
 
 
@@ -44,7 +44,7 @@ MuonTruthHitsFillerTool::MuonTruthHitsFillerTool (const std::string& type,
  */
 StatusCode MuonTruthHitsFillerTool::initialize()
 {
-  CHECK(book());  
+  CHECK(book());
   CHECK( m_idHelperSvc.retrieve() );
   return StatusCode::SUCCESS;
 }
@@ -90,9 +90,9 @@ StatusCode MuonTruthHitsFillerTool::book()
 /**
  * @brief Fill one block --- type-safe version.
  */
-StatusCode MuonTruthHitsFillerTool::fill (const TrackRecord& p)
+StatusCode MuonTruthHitsFillerTool::fill (const TrackRecord& trackRecord)
 {
-  CHECK( fillHitCounts (p.barcode()) ); // FIXME barcode-based
+  CHECK( fillHitCounts (trackRecord.barcode()) );  // FIXME barcode-based
   return StatusCode::SUCCESS;
 }
 
@@ -122,7 +122,11 @@ StatusCode MuonTruthHitsFillerTool::fillHitCounts (int barcode)
 
     for (const PRD_MultiTruthCollection::value_type& mc : *collection) {
       // check if gen particle same as input
-      if( HepMC::barcode(mc.second) != barcode ) continue;
+      // TODO Here barcode is being used purely as a unique
+      // identifier, so we can use HepMC::uniqueID once TrackRecord
+      // and xAOD::TruthParticle and PRD_MultiTruthCollection support
+      // it.
+      if ( HepMC::barcode(mc.second) != barcode ) continue; // FIXME barcode-based
       found = true;
       const Identifier& id = mc.first;
       ATH_MSG_VERBOSE("found matching hit " << m_idHelperSvc->toString(id) );
@@ -149,7 +153,7 @@ StatusCode MuonTruthHitsFillerTool::fillHitCounts (int barcode)
         }else{
           Muon::MuonStationIndex::ChIndex chIndex = m_idHelperSvc->chamberIndex(id);
           ++*(m_nprecHitsPerChamberLayer[chIndex]);
-        }	    
+        }
       }
     }
   }
@@ -192,9 +196,9 @@ StatusCode MuonTruthHitsFillerTool::fillHitCounts (int barcode)
     if( *ntrig[MSI::T3]  > 0 )  ++*m_ntrigEtaLayers;
     if( *ntrig[MSI::T4]  > 0 )  ++*m_ntrigEtaLayers;
     if( *ntrig[MSI::CSC] > 2 )  ++*m_ntrigEtaLayers;
-    if( *ntrig[MSI::STGC1] + 
+    if( *ntrig[MSI::STGC1] +
         *ntrig[MSI::STGC2] > 3 )  ++*m_ntrigEtaLayers;
-    
+
     ATH_MSG_DEBUG("Muon hits: prec " << *m_nprecLayers <<
                   " phi " << *m_nphiLayers
                   << " trig eta " << *m_ntrigEtaLayers );
diff --git a/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/TrackRecordFillerTool.cxx b/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/TrackRecordFillerTool.cxx
index 1169cb847a04ea4ed74636b0814c1a07364d0715..2a2ea57375c2db2a8aa3799426d2128348334fb7 100644
--- a/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/TrackRecordFillerTool.cxx
+++ b/PhysicsAnalysis/D3PDMaker/MuonD3PDMaker/src/TrackRecordFillerTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // Gaudi/Athena include(s):
diff --git a/Simulation/G4Sim/MCTruth/src/TrackHelper.cxx b/Simulation/G4Sim/MCTruth/src/TrackHelper.cxx
index 86667e91187f70144d155ac29d772e35a27af77d..563e89961fb9c8ff99cb48c5d1a06385702a825c 100644
--- a/Simulation/G4Sim/MCTruth/src/TrackHelper.cxx
+++ b/Simulation/G4Sim/MCTruth/src/TrackHelper.cxx
@@ -34,11 +34,13 @@ int TrackHelper::GetBarcode() const  // TODO Drop this once UniqueID and Status
   if (m_trackInfo==0 || std::as_const(m_trackInfo)->GetHepMCParticle()==0) return 0;
   return m_trackInfo->GetParticleBarcode();
 }
+
 int TrackHelper::GetUniqueID() const
 {
   if (m_trackInfo==0 || std::as_const(m_trackInfo)->GetHepMCParticle()==0) return 0;
   return m_trackInfo->GetParticleUniqueID();
 }
+
 int TrackHelper::GetStatus() const
 {
   if (m_trackInfo==0 || std::as_const(m_trackInfo)->GetHepMCParticle()==0) return 0;
diff --git a/Simulation/G4Sim/MCTruthBase/src/RecordingEnvelope.cxx b/Simulation/G4Sim/MCTruthBase/src/RecordingEnvelope.cxx
index d1e9c39b6a6bbce83ca16dadd92d20d8b048c066..27b8e70d0b25f747ffb0a6f9e5ef2edb6b5d0124 100644
--- a/Simulation/G4Sim/MCTruthBase/src/RecordingEnvelope.cxx
+++ b/Simulation/G4Sim/MCTruthBase/src/RecordingEnvelope.cxx
@@ -71,6 +71,8 @@ void RecordingEnvelope::AddTrackRecord(const G4Step* aStep)
   const int pdgcode = (pname=="geantino") ? 999 : aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
   TrackHelper trHelp(aStep->GetTrack());
   const int barcode = trHelp.GetBarcode();
+  const int status = trHelp.GetStatus();
+  const int id = trHelp.GetUniqueID();
 
   G4StepPoint *postStep=aStep->GetPostStepPoint();
   G4ThreeVector pos=postStep->GetPosition();
@@ -81,7 +83,7 @@ void RecordingEnvelope::AddTrackRecord(const G4Step* aStep)
   G4StepPoint *preStep=aStep->GetPreStepPoint();
   G4VPhysicalVolume *preVol=preStep->GetPhysicalVolume();
 
-  m_trackRecordCollection->Emplace(pdgcode,ener,mom,pos,time,barcode,preVol->GetName());
+  m_trackRecordCollection->Emplace(pdgcode,status,ener,mom,pos,time,barcode,id,preVol->GetName());
 
   return;
 }
diff --git a/Simulation/G4Sim/TrackRecord/TrackRecord/TrackRecord.h b/Simulation/G4Sim/TrackRecord/TrackRecord/TrackRecord.h
index 9165119180e30786a806b4a93f9dab28b91593ac..ffe30069c737f95e27846b02500ad8c21aad61ff 100755
--- a/Simulation/G4Sim/TrackRecord/TrackRecord/TrackRecord.h
+++ b/Simulation/G4Sim/TrackRecord/TrackRecord/TrackRecord.h
@@ -18,39 +18,47 @@ public:
   /** @brief Constructor */
   TrackRecord(
               int pdg,
+              int status,
               double energy,
               const CLHEP::Hep3Vector& momentum,
               const CLHEP::Hep3Vector& postition,
               double time,
               int barcode,
+              int id,
               const std::string& volumeName)
     : m_pdgCode(pdg)
+    , m_status(status)
     , m_energy(energy)
     , m_momentum(momentum)
     , m_position(postition)
     , m_time(time)
     , m_barcode(barcode)
+    , m_id(id)
     , m_volName(volumeName) {}
 
   /** @brief Constructor */
   TrackRecord(const TrackRecord& trc)
     : m_pdgCode(trc.m_pdgCode)
+    , m_status(trc.m_status)
     , m_energy(trc.m_energy)
     , m_momentum(trc.m_momentum)
     , m_position(trc.m_position)
     , m_time(trc.m_time)
     , m_barcode(trc.m_barcode)
+    , m_id(trc.m_id)
     , m_volName(trc.m_volName){}
 
   /** @brief Assignement Operator */
   TrackRecord &operator=(const TrackRecord& trc) {
     if (this != &trc) {
       m_pdgCode = trc.m_pdgCode;
+      m_status = trc.m_status;
       m_energy = trc.m_energy;
       m_momentum = trc.m_momentum;
       m_position = trc.m_position;
       m_time = trc.m_time;
       m_barcode = trc.m_barcode;
+      m_id = trc.m_id;
       m_volName = trc.m_volName;
     }
     return *this;
@@ -92,6 +100,18 @@ public:
   /** @brief Set Volume name */
   void SetVolName(const std::string& theName){m_volName = theName;}
 
+  /** @brief status. */
+  int status() const {return m_status;}
+
+  /** @brief Set status */
+  void SetStatus(int status) {m_status = status;}
+
+  /** @brief unique ID */
+  int id() const {return m_id;}
+
+  /** @brief Set uniqueID */
+  void SetID(int uniqueID){m_id = uniqueID;}
+
   /** @brief bar code. Alias function. */
   int barcode() const {return m_barcode;}
 
@@ -100,11 +120,13 @@ public:
 
 private:
   int m_pdgCode{0};
+  int m_status{0};
   double m_energy{0};
   CLHEP::Hep3Vector m_momentum{0,0,0};
   CLHEP::Hep3Vector m_position{0,0,0};
   double m_time{0.};
   int m_barcode{0};
+  int m_id{0};
   std::string m_volName{""};
 };
 
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/CMakeLists.txt b/Simulation/G4SimCnv/G4SimTPCnv/CMakeLists.txt
index fb06de8ab77801d55af6b19d06e6b5b13834cd89..e1f998b6dbfce3fbed22ec4e6dabd1b0e113587b 100644
--- a/Simulation/G4SimCnv/G4SimTPCnv/CMakeLists.txt
+++ b/Simulation/G4SimCnv/G4SimTPCnv/CMakeLists.txt
@@ -16,7 +16,7 @@ atlas_add_tpcnv_library( G4SimTPCnv
                          INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
                          PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                          DEFINITIONS ${CLHEP_DEFINITIONS}
-                         LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolServicesLib AthenaKernel TrackRecordLib )
+                         LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolServicesLib AthenaKernel TrackRecordLib TruthUtils)
 
 atlas_add_dictionary( G4SimTPCnvDict
                       G4SimTPCnv/G4SimTPCnvDict.h
@@ -34,3 +34,8 @@ atlas_add_test( TrackRecordCnv_p1_test
                 SOURCES
                 test/TrackRecordCnv_p1_test.cxx
                 LINK_LIBRARIES G4SimTPCnv TestTools CxxUtils )
+
+atlas_add_test( TrackRecordCnv_p2_test
+                SOURCES
+                test/TrackRecordCnv_p2_test.cxx
+                LINK_LIBRARIES G4SimTPCnv TestTools CxxUtils )
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/G4SimTPCnvDict.h b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/G4SimTPCnvDict.h
index 6cf20df2d24243eaf40114b7cf84cd83f70c0626..b4e72ceca75b9e582a1ef2aef86473a61150a81c 100755
--- a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/G4SimTPCnvDict.h
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/G4SimTPCnvDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef G4SIMCNVDICT_H
@@ -8,6 +8,7 @@
 #include "G4SimTPCnv/TrackRecord_p1.h"
 #include "G4SimTPCnv/TrackRecordCollection_p1.h"
 #include "G4SimTPCnv/TrackRecordCollection_p2.h"
+#include "G4SimTPCnv/TrackRecordCollection_p3.h"
 
 // For Root streamer:
 // for ROOT streamer
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCnv_p2.h b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCnv_p2.h
new file mode 100755
index 0000000000000000000000000000000000000000..1c4ed296d17f830665be4a4f826f77607a765844
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCnv_p2.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef G4SIMTPCNV_TRACKRECORDCNV_P2_H
+#define G4SIMTPCNV_TRACKRECORDCNV_P2_H
+
+/*
+Transient/Persistent converter for TrackRecord class
+Author: Davide Costanzo
+*/
+
+class TrackRecord;
+class TrackRecord_p2;
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h"
+
+class MsgStream;
+
+
+class TrackRecordCnv_p2  : public T_AthenaPoolTPCnvConstBase<TrackRecord, TrackRecord_p2>
+{
+public:
+  using base_class::transToPers;
+  using base_class::persToTrans;
+
+
+  TrackRecordCnv_p2() {}
+
+  virtual void          persToTrans(const TrackRecord_p2* persObj, TrackRecord* transObj, MsgStream &log) const override;
+  virtual void          transToPers(const TrackRecord* transObj, TrackRecord_p2* persObj, MsgStream &log) const override;
+};
+
+
+#endif // G4SIMTPCNV_TRACKRECORDCNV_P2_H
+
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollectionCnv_p3.h b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollectionCnv_p3.h
new file mode 100755
index 0000000000000000000000000000000000000000..0f4f42ab2e67532069ed8224fc0c9278a1e291ca
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollectionCnv_p3.h
@@ -0,0 +1,16 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef G4SIMTPCNV_TRACKRECORDCOLLECTIONCNV_P3_H
+#define G4SIMTPCNV_TRACKRECORDCOLLECTIONCNV_P3_H
+
+#include "G4SimTPCnv/TrackRecordCollection_p3.h"
+#include "TrackRecord/TrackRecordCollection.h"
+#include "G4SimTPCnv/TrackRecordCnv_p2.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h"
+
+typedef T_AtlasHitsVectorCnv< TrackRecordCollection, TrackRecordCollection_p3, TrackRecordCnv_p2 >  TrackRecordCollectionCnv_p3;
+
+
+#endif // not G4SIMTPCNV_TRACKRECORDCOLLECTIONCNV_P3_H
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollection_p3.h b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollection_p3.h
new file mode 100755
index 0000000000000000000000000000000000000000..6cf6e99e88d1e5fd965790f0ce24ad2f6d2de56f
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecordCollection_p3.h
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRACKRECORDCOLLECTION_P3_H
+#define TRACKRECORDCOLLECTION_P3_H
+
+/*
+
+Persistent represenation of TrackRecordCollection
+Author: Davide Costanzo
+
+*/
+
+#include <vector>
+#include <string>
+#include "G4SimTPCnv/TrackRecord_p2.h"
+
+
+class TrackRecordCollection_p3
+{
+public:
+    /// typedefs
+    typedef std::vector<TrackRecord_p2> HitVector;
+    typedef HitVector::const_iterator const_iterator;
+    typedef HitVector::iterator       iterator;
+
+
+    /// Default constructor
+    TrackRecordCollection_p3 ();
+
+    // Accessors
+    const std::string&  name() const;
+    const HitVector&    getVector() const;
+
+    std::vector<TrackRecord_p2>   m_cont;
+    std::string m_name;
+};
+
+
+// inlines
+
+inline
+TrackRecordCollection_p3::TrackRecordCollection_p3 () {}
+
+inline
+const std::string&
+TrackRecordCollection_p3::name() const
+{return m_name;}
+
+inline
+const std::vector<TrackRecord_p2>&
+TrackRecordCollection_p3::getVector() const
+{return m_cont;}
+
+#endif
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecord_p2.h b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecord_p2.h
new file mode 100755
index 0000000000000000000000000000000000000000..4f1221e06bc0eac37e3c80d761af9cab925e0024
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/TrackRecord_p2.h
@@ -0,0 +1,37 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef G4SIMTPCNV_TRACKRECORD_P2_H
+#define G4SIMTPCNV_TRACKRECORD_P2_H
+#include <string>
+
+class TrackRecord_p2 {
+public:
+  TrackRecord_p2() {};
+  int PDG_code() const {return m_PDG_code;}
+  int status() const {return m_status;}
+  float energy() const {return m_energy;}
+  float momentumX() const {return m_momentumX;}
+  float momentumY() const {return m_momentumY;}
+  float momentumZ() const {return m_momentumZ;}
+  float positionX() const {return m_positionX;}
+  float positionY() const {return m_positionY;}
+  float positionZ() const {return m_positionZ;}
+  float time() const {return m_time;}
+  int uniqueID() const {return m_uniqueID;}
+  std::string volName() const {return m_volName;}
+  friend class TrackRecordCnv_p2;
+
+private:
+  int m_PDG_code{0};
+  int m_status{0};
+  float m_energy{0};
+  float m_momentumX{0}, m_momentumY{0}, m_momentumZ{0};
+  float m_positionX{0}, m_positionY{0}, m_positionZ{0};
+  float m_time{0};
+  int m_uniqueID{0};
+  std::string m_volName{""};
+};
+
+#endif // G4SIMTPCNV_TRACKRECORD_P2_H
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/selection.xml b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/selection.xml
index b8891376899dfd3b920f3b9489deeea54dea138c..47d5bd694aae328f88333360683d3153a316d3fc 100755
--- a/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/selection.xml
+++ b/Simulation/G4SimCnv/G4SimTPCnv/G4SimTPCnv/selection.xml
@@ -2,5 +2,9 @@
    <class name="TrackRecordCollection_p2" id="22D044AD-A13A-42BF-B2A4-BDAF5BE2D819" />
    <class name="std::vector<TrackRecord_p1>" />
    <class name="TrackRecord_p1" />
+
+   <class name="TrackRecordCollection_p3" id="C17DB0DC-C53D-4993-A222-B1F4E01C9004" />
+   <class name="std::vector<TrackRecord_p2>" />
+   <class name="TrackRecord_p2" />
 </lcgdict>
 
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/share/TrackRecordCnv_p2_test.ref b/Simulation/G4SimCnv/G4SimTPCnv/share/TrackRecordCnv_p2_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..289656b29581cd40be015aed7b1be922a9d2fbb6
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/share/TrackRecordCnv_p2_test.ref
@@ -0,0 +1,2 @@
+G4SimTPCnv/TrackRecordCnv_p2_test
+test1
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/share/rackRecordCnv_p1_test.ref b/Simulation/G4SimCnv/G4SimTPCnv/share/rackRecordCnv_p1_test.ref
deleted file mode 100644
index ca89c78d17891ff3da7f5cbfa1584ac29709a89a..0000000000000000000000000000000000000000
--- a/Simulation/G4SimCnv/G4SimTPCnv/share/rackRecordCnv_p1_test.ref
+++ /dev/null
@@ -1,2 +0,0 @@
-G4SimTPCnv/TrackRecordCnv_p1_test
-test1
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/src/G4SimTPCnv.cxx b/Simulation/G4SimCnv/G4SimTPCnv/src/G4SimTPCnv.cxx
index e8b0010a81315e3c534e85cbbf61f535f6fae93f..489bc253931886197bf400a29d2b52547ea03e2a 100644
--- a/Simulation/G4SimCnv/G4SimTPCnv/src/G4SimTPCnv.cxx
+++ b/Simulation/G4SimCnv/G4SimTPCnv/src/G4SimTPCnv.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
 */
 
 // generate the T/P converter entries
@@ -7,9 +7,11 @@
 
 #include "G4SimTPCnv/TrackRecordCollectionCnv_p1.h"
 #include "G4SimTPCnv/TrackRecordCollectionCnv_p2.h"
+#include "G4SimTPCnv/TrackRecordCollectionCnv_p3.h"
 #include "G4SimTPCnv/TrackRecord_p1.h"
 #include "G4SimTPCnv/TrackRecordCollection_p1.h"
 #include "G4SimTPCnv/TrackRecordCollection_p2.h"
+#include "G4SimTPCnv/TrackRecordCollection_p3.h"
 
 // For Root streamer:
 // for ROOT streamer
@@ -28,3 +30,8 @@ DECLARE_NAMED_TPCNV_FACTORY(TrackRecordCollectionCnv_p2,
                             TrackRecordCollection_p2,
                             Athena::TPCnvVers::Current)
                       
+DECLARE_NAMED_TPCNV_FACTORY(TrackRecordCollectionCnv_p3,
+                            TrackRecordCollectionCnv_p3,
+                            AtlasHitsVector<TrackRecord>,
+                            TrackRecordCollection_p3,
+                            Athena::TPCnvVers::Old)
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p1.cxx b/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p1.cxx
index ed1768dea61c5549f309dde0d6fe6b5c4c634eb6..c1ac35d1463686e654e41b21f35508fd5b3735f3 100755
--- a/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p1.cxx
+++ b/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p1.cxx
@@ -7,6 +7,7 @@
 
 #include "G4SimTPCnv/TrackRecord_p1.h"
 #include "G4SimTPCnv/TrackRecordCnv_p1.h"
+#include "TruthUtils/MagicNumbers.h"
 
 
 void
@@ -18,6 +19,8 @@ TrackRecordCnv_p1::persToTrans(const TrackRecord_p1* persObj, TrackRecord* trans
    transObj->SetEnergy((double) persObj->energy());
    transObj->SetMomentum(CLHEP::Hep3Vector(persObj->momentumX(), persObj->momentumY(), persObj->momentumZ() ));
    transObj->SetPosition(CLHEP::Hep3Vector(persObj->positionX(), persObj->positionY(), persObj->positionZ() ));
+   const int oldStatus = 1; // Given how TrackRecords are used currently; this will be correct for all but some very exotic samples.
+   transObj->SetStatus(HepMC::new_particle_status_from_old(oldStatus, persObj->barCode()));
    transObj->SetTime((double) persObj->time());
    transObj->SetBarcode(persObj->barCode()); // FIXME barcode-based
    transObj->SetVolName(persObj->volName());
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p2.cxx b/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p2.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..17b3f2a2b9fdb855f0cf4bf83785dd07a6aebf11
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/src/TrackRecordCnv_p2.cxx
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4SimTPCnv/TrackRecordCnv_p2.h"
+#include "G4SimTPCnv/TrackRecord_p2.h"
+#include "TrackRecord/TrackRecord.h"
+
+void
+TrackRecordCnv_p2::persToTrans(const TrackRecord_p2* persObj, TrackRecord* transObj, MsgStream &log) const
+{
+  log << MSG::DEBUG << "TrackRecordCnv_p2::persToTrans called " << endmsg;
+
+  transObj->SetPDGCode (persObj->PDG_code());
+  transObj->SetStatus (persObj->status());
+  transObj->SetEnergy ((double) persObj->energy());
+  transObj->SetMomentum (CLHEP::Hep3Vector( persObj->momentumX(), persObj->momentumY(), persObj->momentumZ() ));
+  transObj->SetPosition (CLHEP::Hep3Vector( persObj->positionX(), persObj->positionY(), persObj->positionZ() ));
+  transObj->SetTime ((double) persObj->time());
+  transObj->SetID (persObj->uniqueID());
+  transObj->SetVolName (persObj->volName());
+}
+
+
+void
+TrackRecordCnv_p2::transToPers(const TrackRecord* transObj, TrackRecord_p2* persObj, MsgStream &log) const
+{
+  log << MSG::DEBUG << "TrackRecordCnv_p2::transToPers called " << endmsg;
+  persObj->m_PDG_code = transObj->GetPDGCode();
+  persObj->m_status = transObj->status();
+  persObj->m_energy = (float) transObj->GetEnergy();
+  CLHEP::Hep3Vector mom = transObj->GetMomentum();
+  persObj->m_momentumX = (float) mom.x();
+  persObj->m_momentumY = (float) mom.y();
+  persObj->m_momentumZ = (float) mom.z();
+  CLHEP::Hep3Vector pos = transObj->GetPosition();
+  persObj->m_positionX = (float) pos.x();
+  persObj->m_positionY = (float) pos.y();
+  persObj->m_positionZ = (float) pos.z();
+  persObj->m_time = (float) transObj->GetTime();
+  persObj->m_uniqueID = transObj->id();
+  persObj->m_volName = transObj->GetVolName();
+}
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p1_test.cxx b/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p1_test.cxx
index efa8cb377b254f8aad6d4621e4d7f35883d9ae13..53266b8a2fa8d9982713c4702ad33f3ca076c4d1 100644
--- a/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p1_test.cxx
+++ b/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p1_test.cxx
@@ -33,9 +33,11 @@ void compare (const TrackRecord& p1,
               const TrackRecord& p2)
 {
   assert ( p1.GetPDGCode()  ==  p2.GetPDGCode() );
+  assert ( p1.status()  ==  p2.status() );
   assert ( p1.GetEnergy()   ==  p2.GetEnergy()  );
   assert ( p1.GetTime()     ==  p2.GetTime()  );
   assert ( p1.barcode()  ==  p2.barcode()  );
+  assert ( p1.id()  ==  p2.id()  );
   assert ( p1.GetVolName()  ==  p2.GetVolName()  );
   compare ( p1.GetPosition(), p2.GetPosition() );
   compare ( p1.GetMomentum(), p2.GetMomentum() );
@@ -60,12 +62,16 @@ void test1 ATLAS_NOT_THREAD_SAFE ()
   std::cout << "test1\n";
   Athena_test::Leakcheck check;
 
-  TrackRecord trans1 (123, 124.5,
-                      CLHEP::Hep3Vector (10.5, 11.5, 12.5),
-                      CLHEP::Hep3Vector (20.5, 21.5, 22.5),
-                      125.5,
-                      126,
-                      "vol");
+  TrackRecord trans1 (123, // pdg code
+                      1, // status - not persistified in TrackRecord_p1
+                      124.5, // energy
+                      CLHEP::Hep3Vector (10.5, 11.5, 12.5), // position
+                      CLHEP::Hep3Vector (20.5, 21.5, 22.5), // momentum
+                      125.5, // time
+                      126, // barcode
+                      0, // id - not persistified in TrackRecord_p1
+                      "vol" // volume name
+                      );
 
   testit (trans1);
 }
diff --git a/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p2_test.cxx b/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p2_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2084acacd20750d8573fe8d93df1d60cc4409884
--- /dev/null
+++ b/Simulation/G4SimCnv/G4SimTPCnv/test/TrackRecordCnv_p2_test.cxx
@@ -0,0 +1,86 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+/**
+ * @file G4SimTPCnv/test/TrackRecordCnv_p2_test.cxx
+ * @author John Chapman
+ * @date Aug, 2023
+ * @brief Tests for TrackRecordCnv_p2.
+ */
+
+
+#undef NDEBUG
+#include "G4SimTPCnv/TrackRecordCnv_p2.h"
+#include "G4SimTPCnv/TrackRecord_p2.h"
+#include "TrackRecord/TrackRecord.h"
+#include "TestTools/leakcheck.h"
+#include "CxxUtils/checker_macros.h"
+#include "GaudiKernel/MsgStream.h"
+#include <cassert>
+#include <iostream>
+
+
+void compare (const CLHEP::Hep3Vector& p1,
+              const CLHEP::Hep3Vector& p2)
+{
+  assert ( p1.x() == p2.x() );
+  assert ( p1.y() == p2.y() );
+  assert ( p1.z() == p2.z() );
+}
+
+
+void compare (const TrackRecord& p1,
+              const TrackRecord& p2)
+{
+  assert ( p1.GetPDGCode()  ==  p2.GetPDGCode() );
+  assert ( p1.status()  ==  p2.status() );
+  assert ( p1.GetEnergy()   ==  p2.GetEnergy()  );
+  assert ( p1.GetTime()     ==  p2.GetTime()  );
+  // Currently no way to get back the barcode value when using
+  // TrackRecord_p2 as the persistent version.
+  assert ( p1.id()  ==  p2.id()  );
+  assert ( p1.GetVolName()  ==  p2.GetVolName()  );
+  compare ( p1.GetPosition(), p2.GetPosition() );
+  compare ( p1.GetMomentum(), p2.GetMomentum() );
+}
+
+
+void testit (const TrackRecord& trans1)
+{
+  MsgStream log (0, "test");
+  TrackRecordCnv_p2 cnv;
+  TrackRecord_p2 pers;
+  cnv.transToPers (&trans1, &pers, log);
+  TrackRecord trans2;
+  cnv.persToTrans (&pers, &trans2, log);
+
+  compare (trans1, trans2);
+}
+
+
+void test1 ATLAS_NOT_THREAD_SAFE ()
+{
+  std::cout << "test1\n";
+  Athena_test::Leakcheck check;
+
+  TrackRecord trans1 (123, // pdg code
+                      1, // status
+                      124.5, // energy
+                      CLHEP::Hep3Vector (10.5, 11.5, 12.5), // position
+                      CLHEP::Hep3Vector (20.5, 21.5, 22.5), // momentum
+                      125.5, // time
+                      126, // barcode - not persistified in TrackRecord_p2
+                      127, // id
+                      "vol" // volume name
+                      );
+
+  testit (trans1);
+}
+
+
+int main ATLAS_NOT_THREAD_SAFE ()
+{
+  std::cout << "G4SimTPCnv/TrackRecordCnv_p2_test\n";
+  test1();
+  return 0;
+}
diff --git a/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeAction.cxx b/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeAction.cxx
index bb3b800808e747af4eeb91328e2725bed5467fcc..cc86469c38fef516aa7c996781a76977621d61d8 100644
--- a/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeAction.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeAction.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //class header
@@ -114,7 +114,9 @@ namespace G4UA
     // Create the TimedTrackRecord
     TrackHelper trHelp(aStep->GetTrack());
     int barcode = trHelp.GetBarcode();
-    m_trackRecordCollection->Emplace(pdgcode, ener, mom, pos, time, barcode,
+    int id = trHelp.GetUniqueID();
+    const int status = trHelp.GetStatus();
+    m_trackRecordCollection->Emplace(pdgcode, status, ener, mom, pos, time, barcode, id,
                                      preVol->GetName());
   }
 
diff --git a/Simulation/G4Utilities/TrackWriteFastSim/src/TrackFastSimSD.cxx b/Simulation/G4Utilities/TrackWriteFastSim/src/TrackFastSimSD.cxx
index 9cbddd001aa70439f9faf3e3997135b99c38e488..1d16550540f4734e076e514c30dd163bb61e1fbb 100644
--- a/Simulation/G4Utilities/TrackWriteFastSim/src/TrackFastSimSD.cxx
+++ b/Simulation/G4Utilities/TrackWriteFastSim/src/TrackFastSimSD.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // Class header
@@ -76,9 +76,11 @@ G4bool TrackFastSimSD::ProcessHits(G4Step* aStep,G4TouchableHistory* )
   // Barcode
   TrackHelper trHelp(track);
   const int barcode = trHelp.GetBarcode();
+  const int id = trHelp.GetUniqueID();
+  const int status = trHelp.GetStatus();
 
   //create the TimedTrackRecord
-  m_trackRecordCollection->Emplace(pdgcode,ener,mom,pos,time,barcode,preVol->GetName());
+  m_trackRecordCollection->Emplace(pdgcode,status,ener,mom,pos,time,barcode,id,preVol->GetName());
 
   return true;
 }
@@ -89,21 +91,23 @@ void TrackFastSimSD::WriteTrack(const G4Track* track, const bool originPos, cons
 
   G4VPhysicalVolume *preVol=track->GetVolume();
 
-  int pdgcode = (track->GetDefinition())?track->GetDefinition()->GetPDGEncoding():0;
+  const int pdgcode = (track->GetDefinition())?track->GetDefinition()->GetPDGEncoding():0;
 
-  G4ThreeVector pos = originPos?track->GetVertexPosition():track->GetPosition();
-  double ener=originMom?(track->GetVertexKineticEnergy()+track->GetDynamicParticle()->GetMass()):track->GetTotalEnergy();
+  const G4ThreeVector pos = originPos?track->GetVertexPosition():track->GetPosition();
+  const double ener=originMom?(track->GetVertexKineticEnergy()+track->GetDynamicParticle()->GetMass()):track->GetTotalEnergy();
   G4ThreeVector mom = track->GetMomentum();
   if (originMom){
     double mommag = std::sqrt(std::pow(ener,2)-std::pow(track->GetDynamicParticle()->GetMass(),2));
     mom = track->GetVertexMomentumDirection()*mommag;
   }
 
-  double time=track->GetGlobalTime();
+  const double time=track->GetGlobalTime();
   TrackHelper trHelp(track);
-  int barcode = trHelp.GetBarcode();
+  const int barcode = trHelp.GetBarcode();
+  const int id = trHelp.GetUniqueID();
+  const int status = trHelp.GetStatus();
 
   //create the TimedTrackRecord
-  m_trackRecordCollection->Emplace(pdgcode,ener,mom,pos,time,barcode,preVol?preVol->GetName():"Unknown");
+  m_trackRecordCollection->Emplace(pdgcode,status,ener,mom,pos,time,barcode,id,preVol?preVol->GetName():"Unknown");
 }
 
diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerTool.cxx b/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerTool.cxx
index da96e1d95a515d2e2e2e106b41845309642af3da..cf25e6c3439766aa333c1136b0938f12aec2e226 100644
--- a/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerTool.cxx
+++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerTool.cxx
@@ -1,10 +1,12 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // class header include
 #include "EntryLayerTool.h"
 
+#include "TruthUtils/MagicNumbers.h"
+
 // ISF includes
 #include "ISF_Event/ISFParticle.h"
 #include "ISF_Interfaces/IGeoIDSvc.h"
@@ -185,15 +187,18 @@ ISF::EntryLayer ISF::EntryLayerTool::registerParticle(const ISF::ISFParticle& pa
     // Use barcode assigend to ISFParticle only if no generation zero particle is present.
     auto                truthBinding = particle.getTruthBinding();
     auto generationZeroTruthParticle = truthBinding ? truthBinding->getGenerationZeroTruthParticle() : nullptr;
-    Barcode::ParticleBarcode barcode = generationZeroTruthParticle ? HepMC::barcode(generationZeroTruthParticle)
-                                                                   : particle.barcode();
+    const int barcode = generationZeroTruthParticle ? HepMC::barcode(generationZeroTruthParticle) : particle.barcode(); // FIXME barcode-based
+    const int id = generationZeroTruthParticle ? HepMC::uniqueID(generationZeroTruthParticle) : HepMC::UNDEFINED_ID; //particle.id(); // FIXME uncomment when ISFParticle has an id() method.
+    const int status = generationZeroTruthParticle ? generationZeroTruthParticle->status() : particle.status();
 
     m_collection[layerHit]->Emplace(particle.pdgCode(),
+                                    status,
                                     energy,
                                     hepMom,
                                     hepPos,
                                     particle.timeStamp(),
                                     barcode,
+                                    id,
                                     m_volumeName[layerHit] );
   }
 
diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerToolMT.cxx b/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerToolMT.cxx
index d2f656dc5998879896aaeadfce6decd78bbd1865..48be51f7603999d528711fff5abc0204d9f4d5ef 100644
--- a/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerToolMT.cxx
+++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4CommonTools/src/EntryLayerToolMT.cxx
@@ -1,10 +1,12 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // class header include
 #include "EntryLayerToolMT.h"
 
+#include "TruthUtils/MagicNumbers.h"
+
 // ISF includes
 #include "ISF_Event/ISFParticle.h"
 
@@ -133,16 +135,19 @@ ISF::EntryLayer ISF::EntryLayerToolMT::registerParticle(const ISF::ISFParticle&
     // Use barcode assigend to ISFParticle only if no generation zero particle is present.
     auto                truthBinding = particle.getTruthBinding();
     auto generationZeroTruthParticle = truthBinding ? truthBinding->getGenerationZeroTruthParticle() : nullptr;
-    Barcode::ParticleBarcode barcode = generationZeroTruthParticle ? HepMC::barcode(generationZeroTruthParticle)
-                                                                   : particle.barcode();
+    const int barcode = generationZeroTruthParticle ? HepMC::barcode(generationZeroTruthParticle) : particle.barcode(); // FIXME barcode-based
+    const int id = generationZeroTruthParticle ? HepMC::uniqueID(generationZeroTruthParticle) : HepMC::UNDEFINED_ID; //particle.id(); // FIXME uncomment when ISFParticle has an id() method.
+    const int status = generationZeroTruthParticle ? generationZeroTruthParticle->status() : particle.status();
 
     (*m_collectionHolder.get())[layerHit]->Emplace(particle.pdgCode(),
-                                                  energy,
-                                                  hepMom,
-                                                  hepPos,
-                                                  particle.timeStamp(),
-                                                  barcode,
-                                                  m_volumeName[layerHit] );
+                                                   status,
+                                                   energy,
+                                                   hepMom,
+                                                   hepPos,
+                                                   particle.timeStamp(),
+                                                   barcode,
+                                                   id,
+                                                   m_volumeName[layerHit] );
   }
 
   return layerHit;